diff --git a/.gn b/.gn
index 9d2eb7e..c977986 100644
--- a/.gn
+++ b/.gn
@@ -64,16 +64,13 @@
 # "gn check" or "gn gen --check".
 no_check_targets = [
   "//extensions/browser:*",  # 20 errors
-  "//extensions:*",  # 75 errors
+  "//extensions:*",  # 28 errors
   "//headless:*",  # 167 errors
-  "//ppapi/native_client/src/untrusted/pnacl_irt_shim:*",  # 197 errors
   "//ppapi/proxy:ipc_sources",  # 13 errors
   "//ppapi/proxy:proxy",  # 5 errors
   "//ppapi/thunk:*",  # 1071 errors
   "//remoting/host/security_key:*",  # 10 errors
   "//remoting/host/win:*",  # 43 errors
-  "//remoting/ios/app/settings:*",  # 6 errors
-  "//remoting/protocol:*",  # 3 errors
   "//sandbox/win:*",  # 7 errors
 
   "//third_party/icu/*",
diff --git a/BUILD.gn b/BUILD.gn
index 98bf349..86878c8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -168,6 +168,7 @@
       "//ppapi/examples/video_encode",
       "//third_party/vulkan-deps/spirv-tools/src:SPIRV-Tools",
       "//third_party/vulkan-deps/spirv-tools/src/test/fuzzers",
+      "//tools/aggregation_service:aggregation_service_tool",
       "//tools/perf/clear_system_cache",
       "//tools/polymer:polymer_tools_python_unittests",
       "//tools/privacy_budget:privacy_budget_tools",
@@ -1156,7 +1157,6 @@
       "//testing/xvfb.py",
       "//third_party/blink/tools/",
       "//third_party/blink/web_tests/VirtualTestSuites",
-      "//third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json",
       "//third_party/blink/web_tests/external/wpt/common/",
       "//third_party/blink/web_tests/external/wpt/resources/",
       "//third_party/blink/web_tests/resources/",
@@ -1211,6 +1211,7 @@
     "--seed",
     "4",
     "--debug-rwt-logging",
+    "--no-manifest-update",
     "--no-show-results",
     "--zero-tests-executed-ok",
     "--clobber-old-results",
@@ -1220,6 +1221,18 @@
     "100",
   ]
 
+  # generate manifest at build time
+  action("gen_manifest") {
+    script = "//third_party/blink/tools/gen_manifest.py"
+
+    args = ["--out", "$root_build_dir/gen/"]
+
+    outputs = [
+      "$root_build_dir/gen/external/wpt/MANIFEST.json",
+      "$root_build_dir/gen/wpt_internal/MANIFEST.json"
+    ]
+  }
+
   # https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_tests.md
   script_test("blink_web_tests") {
     run_under_python2 = true
@@ -1227,7 +1240,10 @@
 
     args = _common_web_test_args
 
-    data_deps = [ ":blink_web_tests_support_data" ]
+    data_deps = [ ":blink_web_tests_support_data",
+                  ":gen_manifest"
+                ]
+
     data = [
       "//third_party/blink/perf_tests/",
       "//third_party/blink/web_tests/",
diff --git a/DEPS b/DEPS
index ea47819..1932951 100644
--- a/DEPS
+++ b/DEPS
@@ -222,11 +222,11 @@
   # 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': '18a42b895440f71a475b368654f5070d48b0402d',
+  'skia_revision': 'd0329b91bc1042c7d0372b68198ac03998c4a363',
   # 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': '1faad41e9dcd644aa5be7a60ceb0616d339adb08',
+  'v8_revision': '21fd10e120f8b593560b9766654aecf58738042a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -234,15 +234,15 @@
   # 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': '51937ab386224053531b478e73ddf97a46d9fa8e',
+  'angle_revision': '396518e015f33d23a1b816fad01689434518508b',
   # 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': '3c89f07b349bf0d226d380c4b519b1a9d8f13759',
+  'swiftshader_revision': '43d3e0cc9c06c650a225f1a6730f5e453b46ac1b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '0e2676091765481fba37be157a563121f6b962b7',
+  'pdfium_revision': 'bd82b53735cdb83f6902494352847b9f13eac60e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -293,7 +293,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '096f6b42b59f63f75835570be67f312aa673c4b5',
+  'catapult_revision': '2fff900ff7a59f0b8ce073534353d88f2b646f62',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -301,7 +301,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': 'c811732a3f477fe32f4fcc6a53f69d06374bc871',
+  'devtools_frontend_revision': '07e1d04bf77968ab76727e525f132cf475160e5b',
   # 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.
@@ -341,11 +341,11 @@
   # 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': '4a811043ccd2b57b9bacd2cb79f30802c18f6301',
+  'dawn_revision': '2f51bfc74a0aa441f29e3112b19804126997957e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '00f114ef210bffae71307e73f33ff380b23208dc',
+  'quiche_revision': '3290ea5420a7a49a8a37e7ffb957fea7b81676cb',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -357,7 +357,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling wuffs
   # and whatever else without interference from each other.
-  'wuffs_revision': 'b2b8961126502d2ab00daa20d19a976964c012a3',
+  'wuffs_revision': 'd0451190ca0a4d0566d142261548cc264819f6c4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libgifcodec
   # and whatever else without interference from each other.
@@ -385,7 +385,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'libcxxabi_revision':    'd87a06daa9d92e525968b6a35099b01804e02152',
+  'libcxxabi_revision':    'cb34896ebd62f93f708ff9aad26159cf11dde6f4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -405,7 +405,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       '8fa87946779682841e21e2da977eccfb6cb3bded',
+  'libcxx_revision':       '79a2e924d96e2fc1e4b937c42efd08898fa472d7',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:31f2bba8aafa8015ca5761100a21f17c2d741062',
@@ -581,7 +581,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'be99633db632f35459756a4ee33356e1d18d7aed',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '07271357576a22fb9325300793c4fb5e26601c70',
       'condition': 'checkout_ios',
   },
 
@@ -651,7 +651,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': '5XazDouaPxiDX6cshJcjjvykw5Qf6eyy7WLnVrk7n4kC',
+          'version': 'Px9wnwF_5wm8GWzFTISnnUdIXX0ZuH1_mUtTcPSeTk8C',
         },
       ],
       'dep_type': 'cipd',
@@ -662,7 +662,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'nhcthApm2qPbCHsqEUx58PKHhH17qTL7bvbmZLiIoTQC',
+          'version': 'K1-2F6AIH6XC3p7sc0SeR8HizBweUyKcKaxmPXqdASgC',
         },
       ],
       'dep_type': 'cipd',
@@ -673,7 +673,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': 'AwcGhgyAARd41nmbm97AEdxCMcBfDMwahfVhsgjqzmEC',
+          'version': 'AEREMiplAGUDrQYWkb5GCwbOWnjB5bGyMc6Sx_vBsH0C',
         },
       ],
       'dep_type': 'cipd',
@@ -738,7 +738,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'PTOkBlPq_HcuCNU_wN2ZymkGWNszZRV4RCn5jnaVp7YC',
+          'version': '29574JKqBbhq5FiO3D4ydclUDICPzLTJGfyNc4k4ldYC',
       },
     ],
     'condition': 'checkout_android',
@@ -954,7 +954,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' + '@' + 'c826272602f92e36cd3e12dd4d9e63c1ceb6cb43',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0f1b3b9918b7f87c98a1919dcda569e2804a4884',
       'condition': 'checkout_chromeos',
   },
 
@@ -1241,7 +1241,7 @@
   },
 
   'src/third_party/libunwindstack': {
-      'url': Var('chromium_git') + '/chromium/src/third_party/libunwindstack.git' + '@' + '8c06e391ab8ee01828a55477f09e7cff26182174',
+      'url': Var('chromium_git') + '/chromium/src/third_party/libunwindstack.git' + '@' + 'b34a0059a648f179ef05da2c0927f564bdaea2b3',
       'condition': 'checkout_android',
   },
 
@@ -1343,7 +1343,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '9d6aade8df4477ef616f81b29cf91eb157c3686c',
+    Var('chromium_git') + '/openscreen' + '@' + '6c8b744d97aa6c8c7de0f9a3e3098d09e833c2e2',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1360,7 +1360,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e989e5e45ab55e146e4c55dd16092d0af5332313',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '566975367c6371c305734403c653ed81bbd53519',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1468,7 +1468,7 @@
   },
 
   'src/third_party/re2/src':
-    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'a5d27a7b2289c98849516aea50c807f3e3a5914b',
+    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '4606f89f43b2991908b904576bb1b936891115bc',
 
   'src/third_party/r8': {
       'packages': [
@@ -1553,7 +1553,7 @@
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '965b19a8636bbcd9617c1658cfe874a10cedb15d',
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@6dda7d6b86d6a43338b38fbf6b994b1010e011b1',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@cda66075b3f4a9480101fc8264e209e904c0efad',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'f67d7fa397e83060b76a1ec53579116a0bbdff7a',
@@ -1592,7 +1592,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '782277b9c5d41ecbdcba2941887cbcb9c365da10',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '00ca0044d4e06fa95706f6ec22c4fbeef9c679f9',
+    Var('webrtc_git') + '/src.git' + '@' + '5d70fe763d0882ae15c20ce2f01a5471dd55d3ec',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1653,7 +1653,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@428e128baad1160d2a83f282953a8b3a961a02ac',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@94dba81f61f82f97fac7704febdba96f2027eaac',
     'condition': 'checkout_src_internal',
   },
 
@@ -1661,7 +1661,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': 'WczWYMoyDSAzReq9CC4GfgzvTeGEVECrMyiwyKnyYWoC',
+        'version': 'jpm9CCFb7x6u-2IuadKlG4J0ssHT3j7ZvQK06uBTpf0C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1672,7 +1672,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': '9ocgJIVdoeA6pLWO6kTZTESIeYPRkEwNF5MosNwGx5YC',
+        'version': 'eCmMPkRdaeHi1w0Qy1-XqCmaLmNxlzo1L2xSrTt1To0C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1683,7 +1683,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'X7PZLg5jqz2jSiDx2RPl7e8sq36zOuArYmN6mKgK2BgC',
+        'version': '_TIm0eEyE6_6IK2yI5nM7vZbCJxOwa7yRXLnOTTcAnwC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/WATCHLISTS b/WATCHLISTS
index 4443199..5ca9249d 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1885,6 +1885,12 @@
                   'ios/chrome/browser/ui/translate|'\
                   'ios/web_view/internal/translate'
     },
+    'turtledove': {
+      'filepath': 'content/browser/interest_group/|'\
+                  'content/services/auction_worklet/|'\
+                  'third_party/blink/public/mojom/interest_group/|'\
+                  'third_party/blink/renderer/modules/ad_auction/'
+    },
     'ui_compositor': {
       'filepath': 'ui/compositor/layer\.|'\
                   'ui/compositor/layer_unittest|'\
@@ -2810,6 +2816,7 @@
                 'spang+watch@chromium.org'],
     'traffic_annotation': ['nicolaso+watch@chromium.org'],
     'translate': ['translate-reviews@chromium.org'],
+    'turtledove': ['taymon@google.com'],
     'ui_compositor': ['cc-bugs@chromium.org'],
     'ui_display_win': ['robliao+watch@chromium.org'],
     'ui_resources': ['oshima+watch@chromium.org'],
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc
index 9cc69cf..cb6c9a6 100644
--- a/android_webview/browser/aw_feature_list_creator.cc
+++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -89,6 +89,11 @@
     // determine if the seed is expired.
     variations::prefs::kVariationsLastFetchTime,
     variations::prefs::kVariationsSeedDate,
+
+    // Cache the expiry date of the list of apps whose package names are allowed
+    // to be recorded in UMA. This will have a valid value (not
+    // base::Time::Min()) only if the app is in the allowlist.
+    prefs::kMetricsShouldRecordAppPackageNameExpiryDate,
 };
 
 void HandleReadError(PersistentPrefStore::PrefReadError error) {}
@@ -120,7 +125,7 @@
 std::unique_ptr<PrefService> AwFeatureListCreator::CreatePrefService() {
   auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
 
-  AwMetricsServiceClient::RegisterPrefs(pref_registry.get());
+  AwMetricsServiceClient::RegisterMetricsPrefs(pref_registry.get());
   variations::VariationsService::RegisterPrefs(pref_registry.get());
 
   embedder_support::OriginTrialPrefs::RegisterPrefs(pref_registry.get());
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
index 13bee28..ca817b28 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 #include <stdio.h>
-#include <unistd.h>
 
 #include <cstring>
 #include <memory>
@@ -17,6 +16,7 @@
 #include "android_webview/browser/metrics/aw_metrics_service_client.h"
 #include "android_webview/common/aw_features.h"
 #include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h"
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/feature_list.h"
@@ -38,39 +38,45 @@
 
 constexpr int kBitsPerByte = 8;
 
-// Creates a bloomfilter after loading its data from file in `allowlist_fd`
-// and lookup the given `package_name` in it.
-bool IsLoggingPackageNameAllowed(int allowlist_fd,
-                                 int num_hash,
-                                 int num_bits,
-                                 const std::string& package_name) {
-  base::ScopedFILE file_stream(fdopen(allowlist_fd, "r"));
+// It returns an empty (null) absl::optional<base::Time> if loading of the
+// allowlist file fails. Otherwise it returns:
+// - `expiry_date` if the given `package_name` is in the allowlist.
+// - `base::Time::Min()` if the given `package_name` isn't in the allowlist.
+absl::optional<base::Time> GetExpiryTimeIfPackageNameLoggable(
+    base::ScopedFD allowlist_fd,
+    int num_hash,
+    int num_bits,
+    const std::string& package_name,
+    const base::Time& expiry_date) {
+  // Transfer the ownership of the file from `allowlist_fd` to `file_stream`.
+  base::ScopedFILE file_stream(fdopen(allowlist_fd.release(), "r"));
   if (!file_stream.get())
-    return false;
+    return absl::optional<base::Time>();
 
   // TODO(https://crbug.com/1219496): use mmap instead of reading the whole
   // file.
   std::string bloom_filter_data;
   if (!base::ReadStreamToString(file_stream.get(), &bloom_filter_data) ||
       bloom_filter_data.empty()) {
-    return false;
+    return absl::optional<base::Time>();
   }
 
   // Make sure the bloomfilter binary data is of the correct length.
   if (bloom_filter_data.size() !=
       size_t((num_bits + kBitsPerByte - 1) / kBitsPerByte)) {
-    return false;
+    return absl::optional<base::Time>();
   }
 
   return optimization_guide::BloomFilter(num_hash, num_bits, bloom_filter_data)
-      .Contains(package_name);
+                 .Contains(package_name)
+             ? expiry_date
+             : base::Time::Min();
 }
 
-void SetShouldRecordPackageName(bool package_present_in_allowlist) {
+void SetShouldRecordPackageName(absl::optional<base::Time> expiry_date) {
   auto* metrics_service_client = AwMetricsServiceClient::GetInstance();
   DCHECK(metrics_service_client);
-  metrics_service_client->SetShouldRecordPackageName(
-      package_present_in_allowlist);
+  metrics_service_client->SetShouldRecordPackageName(expiry_date);
 }
 
 }  // namespace
@@ -78,7 +84,7 @@
 AwAppsPackageNamesAllowlistComponentLoaderPolicy::
     AwAppsPackageNamesAllowlistComponentLoaderPolicy(
         std::string app_package_name,
-        base::OnceCallback<void(bool)> lookup_callback)
+        AllowListLookupCallback lookup_callback)
     : app_package_name_(std::move(app_package_name)),
       lookup_callback_(std::move(lookup_callback)) {
   DCHECK(!app_package_name_.empty());
@@ -108,46 +114,52 @@
 // }
 void AwAppsPackageNamesAllowlistComponentLoaderPolicy::ComponentLoaded(
     const base::Version& version,
-    const base::flat_map<std::string, int>& fd_map,
+    base::flat_map<std::string, base::ScopedFD>& fd_map,
     std::unique_ptr<base::DictionaryValue> manifest) {
+  // TODO(https://crbug.com/1216202): store the allowlist version in the local
+  // cache, don't lookup the allowlist if it's the same version.
+
   // Have to use double because base::DictionaryValue doesn't support int64
   // values.
   absl::optional<double> expiry_date_ms =
       manifest->FindDoublePath(kExpiryDateKey);
   absl::optional<int> num_hash = manifest->FindIntPath(kBloomFilterNumHashKey);
   absl::optional<int> num_bits = manifest->FindIntPath(kBloomFilterNumBitsKey);
-  auto allowlist_iterator = fd_map.end();
-
   // Being conservative and consider the allowlist expired when a valid expiry
   // date is absent.
-  if (num_hash.has_value() && num_bits.has_value() && num_hash.value() > 0 &&
-      num_bits.value() > 0 && expiry_date_ms.has_value() &&
-      base::Time::UnixEpoch() +
-              base::TimeDelta::FromMillisecondsD(expiry_date_ms.value()) >
-          base::Time::Now() &&
-      (allowlist_iterator = fd_map.find(kAllowlistBloomFilterFileName)) !=
-          fd_map.end()) {
-    base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-        base::BindOnce(&IsLoggingPackageNameAllowed, allowlist_iterator->second,
-                       num_hash.value(), num_bits.value(),
-                       std::move(app_package_name_)),
-        std::move(lookup_callback_));
-  } else {
+  if (!expiry_date_ms.has_value() || !num_hash.has_value() ||
+      !num_bits.has_value() || num_hash.value() <= 0 || num_bits.value() <= 0) {
     ComponentLoadFailed();
+    return;
   }
 
-  // Close unused files.
-  // TODO(https://crbug.com/1219672): use base::ScopedFD instead.
-  for (auto& iterator : fd_map) {
-    if (allowlist_iterator == fd_map.end() || iterator != *allowlist_iterator)
-      close(iterator.second);
+  base::Time expiry_date =
+      base::Time::UnixEpoch() +
+      base::TimeDelta::FromMillisecondsD(expiry_date_ms.value_or(0.0));
+  if (expiry_date <= base::Time::Now()) {
+    ComponentLoadFailed();
+    return;
   }
+
+  auto allowlist_iterator = fd_map.find(kAllowlistBloomFilterFileName);
+  if (allowlist_iterator == fd_map.end()) {
+    ComponentLoadFailed();
+    return;
+  }
+
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+      base::BindOnce(&GetExpiryTimeIfPackageNameLoggable,
+                     std::move(allowlist_iterator->second), num_hash.value(),
+                     num_bits.value(), std::move(app_package_name_),
+                     expiry_date),
+      std::move(lookup_callback_));
 }
 
 void AwAppsPackageNamesAllowlistComponentLoaderPolicy::ComponentLoadFailed() {
   DCHECK(lookup_callback_);
-  std::move(lookup_callback_).Run(/* lookup_result= */ false);
+  std::move(lookup_callback_)
+      .Run(/* expiry_date= */ absl::optional<base::Time>());
 }
 
 void AwAppsPackageNamesAllowlistComponentLoaderPolicy::GetHash(
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
index 6a42263..afc83a9 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
@@ -13,7 +13,9 @@
 
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "components/component_updater/android/component_loader_policy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class DictionaryValue;
@@ -29,6 +31,16 @@
 constexpr char kBloomFilterNumBitsKey[] = "bloomfilter_num_bits";
 constexpr char kExpiryDateKey[] = "expiry_date";
 
+// A callback that accepts an `absl::optional<base::Time>` expiry_date:
+// - If the allowlist loading fails, it will be called with a null value.
+// - If the package name isn't in the allowlist, it will be called with an
+//   always expired date `base::Time::Min()`.
+// - If the package name is in the allowlist, it will be called with the
+//   expiry_date after which the app package name shouldn't be recorded in UMA
+//   metrics.
+using AllowListLookupCallback =
+    base::OnceCallback<void(absl::optional<base::Time>)>;
+
 // Defines a loader responsible for receiving the allowlist for apps package
 // names that can be included in UMA records and lookup the embedding app's name
 // in that list.
@@ -40,7 +52,7 @@
   //                   `app_package_name` in the packages names allowlist.
   AwAppsPackageNamesAllowlistComponentLoaderPolicy(
       std::string app_package_name,
-      base::OnceCallback<void(bool)> lookup_callback);
+      AllowListLookupCallback lookup_callback);
   ~AwAppsPackageNamesAllowlistComponentLoaderPolicy() override;
 
   AwAppsPackageNamesAllowlistComponentLoaderPolicy(
@@ -51,14 +63,14 @@
   // The following methods override ComponentLoaderPolicy.
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override;
   void ComponentLoadFailed() override;
   void GetHash(std::vector<uint8_t>* hash) const override;
 
  private:
   std::string app_package_name_;
-  base::OnceCallback<void(bool)> lookup_callback_;
+  AllowListLookupCallback lookup_callback_;
 };
 
 void LoadPackageNamesAllowlistComponent(
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
index 7ed259a..7484287e 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
 #include "base/run_loop.h"
 #include "base/sequence_checker.h"
 #include "base/test/bind.h"
@@ -32,23 +33,17 @@
 constexpr int kNumBitsPerEntry = 16;
 const std::string kTestAllowlist[] = {"com.example.test", "my.fake.app",
                                       "yet.another.app"};
-double OneDayFromNowMs() {
-  return (base::Time::Now() + base::TimeDelta::FromDays(1) -
-          base::Time::UnixEpoch())
-      .InMillisecondsF();
-}
-
-double OneDayAgoMs() {
-  return (base::Time::Now() - base::TimeDelta::FromDays(1) -
-          base::Time::UnixEpoch())
-      .InMillisecondsF();
+double MillisFromUnixEpoch(const base::Time& time) {
+  return (time - base::Time::UnixEpoch()).InMillisecondsF();
 }
 
 std::unique_ptr<base::Value> BuildTestManifest() {
   auto manifest = std::make_unique<base::Value>(base::Value::Type::DICTIONARY);
   manifest->SetKey(kBloomFilterNumHashKey, base::Value(kNumHash));
   manifest->SetKey(kBloomFilterNumBitsKey, base::Value(3 * kNumBitsPerEntry));
-  manifest->SetKey(kExpiryDateKey, base::Value(OneDayFromNowMs()));
+  manifest->SetKey(kExpiryDateKey,
+                   base::Value(MillisFromUnixEpoch(
+                       base::Time::Now() + base::TimeDelta::FromDays(1))));
 
   return manifest;
 }
@@ -63,7 +58,6 @@
   }
 
   void TearDown() override {
-    close(allowlist_fd_);
     base::DeleteFile(allowlist_path_);
   }
 
@@ -80,17 +74,15 @@
     WriteAllowListToFile(filter->bytes());
   }
 
-  int OpenAndGetAllowlistFd() {
-    if (allowlist_fd_ == -1) {
-      allowlist_fd_ = open(allowlist_path_.value().c_str(), O_RDONLY);
-      CHECK(allowlist_fd_) << "Failed to open FD for " << allowlist_path_;
-    }
-    return allowlist_fd_;
+  base::ScopedFD OpenAndGetAllowlistFd() {
+    int allowlist_fd = open(allowlist_path_.value().c_str(), O_RDONLY);
+    CHECK(allowlist_fd) << "Failed to open FD for " << allowlist_path_;
+    return base::ScopedFD(allowlist_fd);
   }
 
-  void LookupConfirmationCallback(bool lookup_result) {
+  void LookupConfirmationCallback(absl::optional<base::Time> expiry_date) {
     EXPECT_TRUE(checker_.CalledOnValidSequence());
-    lookup_result_ = lookup_result;
+    allowlist_expiry_date_ = expiry_date;
     lookup_run_loop_.Quit();
   }
 
@@ -100,19 +92,21 @@
   base::SequenceCheckerImpl checker_;
   base::RunLoop lookup_run_loop_;
 
-  bool lookup_result_;
+  absl::optional<base::Time> allowlist_expiry_date_;
 
  private:
-  int allowlist_fd_ = -1;
   base::FilePath allowlist_path_;
 };
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestExistingPackageName) {
   WritePackageNamesAllowListToFile();
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
+  std::unique_ptr<base::Value> manifest = BuildTestManifest();
+  base::Time one_day_from_now =
+      base::Time::Now() + base::TimeDelta::FromDays(1);
+  manifest->SetDoubleKey(kExpiryDateKey, MillisFromUnixEpoch(one_day_from_now));
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -125,15 +119,15 @@
                           base::DictionaryValue::From(std::move(manifest)));
 
   lookup_run_loop_.Run();
-  EXPECT_TRUE(lookup_result_);
+  EXPECT_TRUE(allowlist_expiry_date_.has_value());
+  EXPECT_EQ(allowlist_expiry_date_.value(), one_day_from_now);
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestNonExistingPackageName) {
   WritePackageNamesAllowListToFile();
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -143,17 +137,17 @@
                          base::Unretained(this)));
 
   policy->ComponentLoaded(base::Version(), fd_map,
-                          base::DictionaryValue::From(std::move(manifest)));
+                          base::DictionaryValue::From(BuildTestManifest()));
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_TRUE(allowlist_expiry_date_.has_value());
+  EXPECT_TRUE(allowlist_expiry_date_.value().is_min());
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestAllowlistFileNotInMap) {
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map["another_file"] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -163,16 +157,16 @@
                          base::Unretained(this)));
 
   policy->ComponentLoaded(base::Version(), fd_map,
-                          base::DictionaryValue::From(std::move(manifest)));
+                          base::DictionaryValue::From(BuildTestManifest()));
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_FALSE(allowlist_expiry_date_.has_value());
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestMissingBloomFilterParams) {
   WritePackageNamesAllowListToFile();
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
 
   auto policy =
@@ -186,15 +180,14 @@
                           std::make_unique<base::DictionaryValue>());
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_FALSE(allowlist_expiry_date_.has_value());
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestTooShortBloomFilter) {
   WriteAllowListToFile(std::vector<uint8_t>(2, 0xff));
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -204,18 +197,17 @@
                          base::Unretained(this)));
 
   policy->ComponentLoaded(base::Version(), fd_map,
-                          base::DictionaryValue::From(std::move(manifest)));
+                          base::DictionaryValue::From(BuildTestManifest()));
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_FALSE(allowlist_expiry_date_.has_value());
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestTooLongBloomFilter) {
   WriteAllowListToFile(std::vector<uint8_t>(2000, 0xff));
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -225,19 +217,21 @@
                          base::Unretained(this)));
 
   policy->ComponentLoaded(base::Version(), fd_map,
-                          base::DictionaryValue::From(std::move(manifest)));
+                          base::DictionaryValue::From(BuildTestManifest()));
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_FALSE(allowlist_expiry_date_.has_value());
 }
 
 TEST_F(AwAppsPackageNamesAllowlistComponentLoaderPolicyTest,
        TestExpiredAllowlist) {
   WritePackageNamesAllowListToFile();
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   fd_map[kAllowlistBloomFilterFileName] = OpenAndGetAllowlistFd();
-  auto manifest = BuildTestManifest();
-  manifest->SetKey(kExpiryDateKey, base::Value(OneDayAgoMs()));
+  std::unique_ptr<base::Value> manifest = BuildTestManifest();
+  manifest->SetKey(kExpiryDateKey,
+                   base::Value(MillisFromUnixEpoch(
+                       base::Time::Now() - base::TimeDelta::FromDays(1))));
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
@@ -250,7 +244,7 @@
                           base::DictionaryValue::From(std::move(manifest)));
 
   lookup_run_loop_.Run();
-  EXPECT_FALSE(lookup_result_);
+  EXPECT_FALSE(allowlist_expiry_date_.has_value());
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.cc
index c103121..7a738e0 100644
--- a/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.cc
+++ b/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.cc
@@ -13,6 +13,7 @@
 
 #include "android_webview/browser/aw_browser_process.h"
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "base/values.h"
 #include "base/version.h"
 #include "components/component_updater/installer_policies/origin_trials_component_installer.h"
@@ -28,13 +29,8 @@
 
 void OriginTrialsComponentLoaderPolicy::ComponentLoaded(
     const base::Version& version,
-    const base::flat_map<std::string, int>& fd_map,
+    base::flat_map<std::string, base::ScopedFD>& fd_map,
     std::unique_ptr<base::DictionaryValue> manifest) {
-  // Close unused fds.
-  for (auto& key_value : fd_map) {
-    close(key_value.second);
-  }
-
   // Read the configuration from the manifest and set values in browser
   // local_state. These will be used on the next browser restart.
   // If an individual configuration value is missing, treat as a reset to the
diff --git a/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.h
index f17f313..e479051e 100644
--- a/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.h
+++ b/android_webview/browser/component_updater/loader_policies/origin_trials_component_loader_policy.h
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "components/component_updater/android/component_loader_policy.h"
 
 namespace base {
@@ -38,7 +39,7 @@
   // The following methods override ComponentLoaderPolicy.
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override;
   void ComponentLoadFailed() override;
   void GetHash(std::vector<uint8_t>* hash) const override;
diff --git a/android_webview/browser/gfx/aw_gl_functor.cc b/android_webview/browser/gfx/aw_gl_functor.cc
index 0a6d879..f2b8d302 100644
--- a/android_webview/browser/gfx/aw_gl_functor.cc
+++ b/android_webview/browser/gfx/aw_gl_functor.cc
@@ -6,7 +6,7 @@
 
 #include "android_webview/browser_jni_headers/AwGLFunctor_jni.h"
 #include "android_webview/public/browser/draw_gl.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 
diff --git a/android_webview/browser/gfx/browser_view_renderer_unittest.cc b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
index c3685bf..dc287f1c 100644
--- a/android_webview/browser/gfx/browser_view_renderer_unittest.cc
+++ b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
@@ -13,9 +13,9 @@
 #include "android_webview/browser/gfx/render_thread_manager.h"
 #include "android_webview/browser/gfx/test/rendering_test.h"
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
diff --git a/android_webview/browser/gfx/hardware_renderer_viz.cc b/android_webview/browser/gfx/hardware_renderer_viz.cc
index 1d3c4ad..dcbef57 100644
--- a/android_webview/browser/gfx/hardware_renderer_viz.cc
+++ b/android_webview/browser/gfx/hardware_renderer_viz.cc
@@ -451,7 +451,7 @@
     auto transaction = overlay_processor->TakeSurfaceTransactionOnRT();
     if (transaction) {
       DCHECK(merge_transaction);
-      merge_transaction(transaction->transaction());
+      merge_transaction(transaction->GetTransaction());
     }
   }
 }
diff --git a/android_webview/browser/gfx/overlay_processor_webview.cc b/android_webview/browser/gfx/overlay_processor_webview.cc
index cbe15de..cddcea0 100644
--- a/android_webview/browser/gfx/overlay_processor_webview.cc
+++ b/android_webview/browser/gfx/overlay_processor_webview.cc
@@ -32,6 +32,8 @@
 constexpr gpu::CommandBufferNamespace kOverlayProcessorNamespace =
     gpu::CommandBufferNamespace::IN_PROCESS;
 
+constexpr int kMaxBuffersInFlight = 3;
+
 scoped_refptr<gpu::SyncPointClientState> CreateSyncPointClientState(
     gpu::CommandBufferId command_buffer_id,
     gpu::SequenceId sequence_id) {
@@ -782,6 +784,8 @@
   LockResult result{};
   auto resource_id = overlay.resource_id;
 
+  resource_lock_count_[overlay.surface_id.frame_sink_id()]++;
+
   OverlayResourceLock lock = OverlayResourceLock(
       static_cast<viz::DisplayResourceProviderSkia*>(resource_provider_),
       resource_id);
@@ -791,7 +795,8 @@
   locked_resources_.insert(std::make_pair(resource_id, std::move(lock)));
 
   auto return_cb = base::BindOnce(&OverlayProcessorWebView::ReturnResource,
-                                  weak_ptr_factory_.GetWeakPtr(), resource_id);
+                                  weak_ptr_factory_.GetWeakPtr(), resource_id,
+                                  overlay.surface_id);
   auto return_cb_on_thread = base::BindPostTask(
       base::ThreadTaskRunnerHandle::Get(), std::move(return_cb));
 
@@ -821,7 +826,8 @@
   }
 }
 
-void OverlayProcessorWebView::ReturnResource(viz::ResourceId resource_id) {
+void OverlayProcessorWebView::ReturnResource(viz::ResourceId resource_id,
+                                             viz::SurfaceId surface_id) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   // |locked_resources_| is multimap and can contain multiple locks of the same
@@ -832,6 +838,27 @@
   auto it = locked_resources_.find(resource_id);
   DCHECK(it != locked_resources_.end());
   locked_resources_.erase(it);
+
+  DCHECK(resource_lock_count_.contains(surface_id.frame_sink_id()));
+  auto& count = resource_lock_count_[surface_id.frame_sink_id()];
+  DCHECK_GT(count, 0);
+
+  // When the lock count reaches kMaxBuffersInFlight, we don't send acks to the
+  // client in the ProcessForFrameSinkId. In this case we send ack here when the
+  // lock count drops below the threshold. Note, that because we still lock
+  // resource and schedule buffer update, the lock count can be larger than
+  // kMaxBuffersInFlight in certain cases, like quick overlay demotion and
+  // promotion again.
+  if (count == kMaxBuffersInFlight) {
+    auto* surface =
+        frame_sink_manager_->surface_manager()->GetSurfaceForId(surface_id);
+    if (surface) {
+      surface->SendAckToClient();
+    }
+  }
+
+  if (!--count)
+    resource_lock_count_.erase(surface_id.frame_sink_id());
 }
 
 void OverlayProcessorWebView::ProcessForFrameSinkId(
@@ -859,8 +886,13 @@
     UpdateOverlayResource(frame_sink_id,
                           pass.draw_quads.front().remapped_resources.ids[0],
                           uv_rect);
-    // TODO(vasilyt): Implement back pressure
-    surface->SendAckToClient();
+    // If resource lock count reached kMaxBuffersInFlight it means we can't
+    // schedule any more frames right away, in this case we delay sending ack to
+    // the client and will send it in ReturnResources after OverlayManager will
+    // process previous update.
+    if (resource_lock_count_[frame_sink_id] < kMaxBuffersInFlight) {
+      surface->SendAckToClient();
+    }
   }
 }
 
diff --git a/android_webview/browser/gfx/overlay_processor_webview.h b/android_webview/browser/gfx/overlay_processor_webview.h
index 809da17..e244fe96 100644
--- a/android_webview/browser/gfx/overlay_processor_webview.h
+++ b/android_webview/browser/gfx/overlay_processor_webview.h
@@ -92,7 +92,7 @@
   };
 
   LockResult LockResource(Overlay& overlay);
-  void ReturnResource(viz::ResourceId resource_id);
+  void ReturnResource(viz::ResourceId resource_id, viz::SurfaceId surface_id);
 
   void CreateManagerOnRT(
       gpu::DisplayCompositorMemoryAndTaskControllerOnGpu* controller_on_gpu,
@@ -111,6 +111,8 @@
   uint64_t next_overlay_id_ = 1;
   std::multimap<viz::ResourceId, OverlayResourceLock> locked_resources_;
 
+  base::flat_map<viz::FrameSinkId, int> resource_lock_count_;
+
   // Overlay candidates for the current frame.
   viz::OverlayCandidateList overlay_candidates_;
 
diff --git a/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc b/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
index 2cd4435..c9ce758 100644
--- a/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
+++ b/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
@@ -7,7 +7,7 @@
 #include <utility>
 
 #include "android_webview/browser_jni_headers/AwContentsLifecycleNotifier_jni.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "content/public/browser/browser_thread.h"
 
 using base::android::AttachCurrentThread;
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc
index 9c66b83..45b4e91 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.cc
+++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -16,6 +16,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/no_destructor.h"
+#include "base/time/time.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/prefs/pref_service.h"
@@ -23,6 +24,11 @@
 
 namespace android_webview {
 
+namespace prefs {
+const char kMetricsShouldRecordAppPackageNameExpiryDate[] =
+    "aw_metrics_app_package_name_allowlist.expiry_date";
+}  // namespace prefs
+
 namespace {
 
 // IMPORTANT: DO NOT CHANGE sample rates without first ensuring the Chrome
@@ -90,18 +96,29 @@
 }
 
 bool AwMetricsServiceClient::ShouldRecordPackageName() {
-  if (base::FeatureList::IsEnabled(
+  if (!base::FeatureList::IsEnabled(
           android_webview::features::kWebViewAppsPackageNamesAllowlist)) {
-    return should_record_package_name_;
+    // Revert to the default implementation of using a random sample to decide
+    // whether to record the app package name or not.
+    return ::metrics::AndroidMetricsServiceClient::ShouldRecordPackageName();
   }
-  // Revert to the default implementation of using a random sample to decide
-  // whether to record the app package name or not.
-  return ::metrics::AndroidMetricsServiceClient::ShouldRecordPackageName();
+
+  PrefService* local_state = pref_service();
+  DCHECK(local_state);
+  return local_state->GetTime(
+             prefs::kMetricsShouldRecordAppPackageNameExpiryDate) >=
+         base::Time::Now();
 }
 
 void AwMetricsServiceClient::SetShouldRecordPackageName(
-    bool should_record_package_name) {
-  should_record_package_name_ = should_record_package_name;
+    absl::optional<base::Time> expiry_date) {
+  if (!expiry_date.has_value())
+    return;
+
+  PrefService* local_state = pref_service();
+  DCHECK(local_state);
+  local_state->SetTime(prefs::kMetricsShouldRecordAppPackageNameExpiryDate,
+                       expiry_date.value());
 }
 
 void AwMetricsServiceClient::OnMetricsStart() {
@@ -152,6 +169,14 @@
 }
 
 // static
+void AwMetricsServiceClient::RegisterMetricsPrefs(
+    PrefRegistrySimple* registry) {
+  RegisterPrefs(registry);
+  registry->RegisterTimePref(
+      prefs::kMetricsShouldRecordAppPackageNameExpiryDate, base::Time::Min());
+}
+
+// static
 void JNI_AwMetricsServiceClient_SetHaveMetricsConsent(JNIEnv* env,
                                                       jboolean user_consent,
                                                       jboolean app_consent) {
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.h b/android_webview/browser/metrics/aw_metrics_service_client.h
index ef78df7..93d1acb 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.h
+++ b/android_webview/browser/metrics/aw_metrics_service_client.h
@@ -13,6 +13,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/no_destructor.h"
 #include "base/sequence_checker.h"
+#include "base/time/time.h"
 #include "components/embedder_support/android/metrics/android_metrics_service_client.h"
 #include "components/metrics/enabled_state_provider.h"
 #include "components/metrics/metrics_log_uploader.h"
@@ -22,6 +23,10 @@
 
 namespace android_webview {
 
+namespace prefs {
+extern const char kMetricsShouldRecordAppPackageNameExpiryDate[];
+}  // namespace prefs
+
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
 // TODO(https://crbug.com/1012025): remove this when the kInstallDate pref has
@@ -127,6 +132,8 @@
   static void SetInstance(
       std::unique_ptr<AwMetricsServiceClient> aw_metrics_service_client);
 
+  static void RegisterMetricsPrefs(PrefRegistrySimple* registry);
+
   AwMetricsServiceClient(std::unique_ptr<Delegate> delegate);
   ~AwMetricsServiceClient() override;
 
@@ -154,15 +161,24 @@
   // `::metrics::AndroidMetricsServiceClient::ShouldRecordPackageName` is used.
   bool ShouldRecordPackageName() override;
 
-  // Sets whether the embedding app's package name is allowed to be recorded in
-  // UMA logs or not. This is determened by looking up the app package name in a
+  // Sets that the embedding app's package name is allowed to be recorded in
+  // UMA logs. This is determened by looking up the app package name in a
   // dynamically downloaded allowlist of apps see
   // `AwAppsPackageNamesAllowlistComponentLoaderPolicy`.
-  void SetShouldRecordPackageName(bool should_record_package_name);
+  //
+  // `expiry_date` the date after which the app package name shouldn't be
+  //               recoreded in UMA because the allowlist that contained this
+  //               app has expired. If it has a null value, then it will be
+  //               ignored and the cached date will be used if any.
+  void SetShouldRecordPackageName(absl::optional<base::Time> expiry_date);
+
+ protected:
+  // Restrict usage of the inherited AndroidMetricsServiceClient::RegisterPrefs,
+  // RegisterMetricsPrefs should be used instead.
+  using AndroidMetricsServiceClient::RegisterPrefs;
 
  private:
   bool app_in_foreground_ = false;
-  bool should_record_package_name_ = false;
   std::unique_ptr<Delegate> delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(AwMetricsServiceClient);
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
new file mode 100644
index 0000000..677466fa
--- /dev/null
+++ b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/metrics/aw_metrics_service_client.h"
+
+#include <memory>
+
+#include "android_webview/common/aw_features.h"
+#include "base/metrics/user_metrics.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/time/time.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace android_webview {
+
+namespace {
+
+class AwMetricsServiceClientTestDelegate
+    : public AwMetricsServiceClient::Delegate {
+  void RegisterAdditionalMetricsProviders(
+      metrics::MetricsService* service) override {}
+  void AddWebViewAppStateObserver(WebViewAppStateObserver* observer) override {}
+  bool HasAwContentsEverCreated() const override { return false; }
+};
+
+class AwMetricsServiceClientTest : public testing::Test {
+  AwMetricsServiceClientTest& operator=(const AwMetricsServiceClientTest&) =
+      delete;
+  AwMetricsServiceClientTest(AwMetricsServiceClientTest&&) = delete;
+  AwMetricsServiceClientTest& operator=(AwMetricsServiceClientTest&&) = delete;
+
+ protected:
+  AwMetricsServiceClientTest()
+      : task_runner_(new base::TestSimpleTaskRunner),
+        prefs_(std::make_unique<TestingPrefServiceSimple>()),
+        client_(std::make_unique<AwMetricsServiceClient>(
+            std::make_unique<AwMetricsServiceClientTestDelegate>())) {
+    // Required by MetricsService.
+    base::SetRecordActionTaskRunner(task_runner_);
+    AwMetricsServiceClient::RegisterMetricsPrefs(prefs_->registry());
+    client_->Initialize(prefs_.get());
+  }
+
+  AwMetricsServiceClient* GetClient() { return client_.get(); }
+
+ private:
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  std::unique_ptr<TestingPrefServiceSimple> prefs_;
+  std::unique_ptr<AwMetricsServiceClient> client_;
+};
+
+}  // namespace
+
+TEST_F(AwMetricsServiceClientTest, TestShouldRecordPackageName_CacheNotSet) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(
+      android_webview::features::kWebViewAppsPackageNamesAllowlist);
+
+  EXPECT_FALSE(GetClient()->ShouldRecordPackageName());
+}
+
+TEST_F(AwMetricsServiceClientTest,
+       TestShouldRecordPackageName_TestExpiredResult) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(
+      android_webview::features::kWebViewAppsPackageNamesAllowlist);
+
+  auto* client = GetClient();
+  auto one_day_ago = base::Time::Now() - base::TimeDelta::FromDays(1);
+  client->SetShouldRecordPackageName(/* expiry_date= */ one_day_ago);
+  EXPECT_FALSE(client->ShouldRecordPackageName());
+}
+
+TEST_F(AwMetricsServiceClientTest,
+       TestShouldRecordPackageName_TestValidResult) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(
+      android_webview::features::kWebViewAppsPackageNamesAllowlist);
+
+  auto* client = GetClient();
+  auto one_day_from_now = base::Time::Now() + base::TimeDelta::FromDays(1);
+  client->SetShouldRecordPackageName(/* expiry_date= */ one_day_from_now);
+  EXPECT_TRUE(client->ShouldRecordPackageName());
+}
+
+TEST_F(AwMetricsServiceClientTest,
+       TestShouldRecordPackageName_TestInvalidResult) {
+  base::test::ScopedFeatureList scoped_list;
+  scoped_list.InitAndEnableFeature(
+      android_webview::features::kWebViewAppsPackageNamesAllowlist);
+
+  auto* client = GetClient();
+  auto one_day_from_now = base::Time::Now() + base::TimeDelta::FromDays(1);
+  client->SetShouldRecordPackageName(/* expiry_date= */ one_day_from_now);
+  client->SetShouldRecordPackageName(
+      /* expiry_date= */ absl::optional<base::Time>());
+  EXPECT_TRUE(client->ShouldRecordPackageName());
+}
+
+}  // namespace android_webview
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc
index c8a9dfa..f2cfffb 100644
--- a/android_webview/common/aw_switches.cc
+++ b/android_webview/common/aw_switches.cc
@@ -37,6 +37,13 @@
 const char kFinchSeedIgnorePendingDownload[] =
     "finch-seed-ignore-pending-download";
 
+// Forces WebView's service to always schedule a new variations seed download
+// job, even if the device is not charging. Note this switch may be necessary
+// for testing on Android emulators as these are not always considered to be
+// charging.
+const char kFinchSeedNoChargingRequirement[] =
+    "finch-seed-no-charging-requirement";
+
 // The minimum amount of time in seconds that WebView's service will wait
 // between two variations seed downloads from the variations server.
 const char kFinchSeedMinDownloadPeriod[] = "finch-seed-min-download-period";
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h
index 1c3fdf22..8bad5bd07 100644
--- a/android_webview/common/aw_switches.h
+++ b/android_webview/common/aw_switches.h
@@ -15,6 +15,7 @@
 extern const char kWebViewVerboseLogging[];
 extern const char kFinchSeedExpirationAge[];
 extern const char kFinchSeedIgnorePendingDownload[];
+extern const char kFinchSeedNoChargingRequirement[];
 extern const char kFinchSeedMinDownloadPeriod[];
 extern const char kFinchSeedMinUpdatePeriod[];
 extern const char kWebViewEnableModernCookieSameSite[];
diff --git a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc b/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc
index f6cbcda..7aeb5373 100644
--- a/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc
+++ b/android_webview/common/components/aw_apps_package_names_allowlist_component_utils.cc
@@ -4,7 +4,8 @@
 
 #include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h"
 
-#include "base/stl_util.h"
+#include "base/check.h"
+#include "base/cxx17_backports.h"
 
 namespace android_webview {
 
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 4d34f50f..f919ea097 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
@@ -51,6 +51,11 @@
             Flag.commandLine(AwSwitches.FINCH_SEED_IGNORE_PENDING_DOWNLOAD,
                     "Forces the WebView service to reschedule a variations seed download job even "
                             + "if one is already pending."),
+            Flag.commandLine(AwSwitches.FINCH_SEED_NO_CHARGING_REQUIREMENT,
+                    "Forces WebView's service to always schedule a new variations seed download "
+                            + "job, even if the device is not charging. Note this switch may be "
+                            + "necessary for testing on Android emulators as these are not always "
+                            + "considered to be charging."),
             Flag.commandLine(AwSwitches.FINCH_SEED_MIN_DOWNLOAD_PERIOD,
                     "Disables throttling of variations seed download jobs.", "0"),
             Flag.commandLine(AwSwitches.FINCH_SEED_MIN_UPDATE_PERIOD,
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 29339b8..0057533 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
@@ -107,8 +107,6 @@
             Assert.assertEquals("Job scheduled with wrong ID", JOB_ID, job.getId());
             Assert.assertEquals("Job scheduled with wrong network type",
                     JobInfo.NETWORK_TYPE_ANY, job.getNetworkType());
-            Assert.assertTrue("Job scheduled without charging requirement",
-                    job.isRequireCharging());
             mJob = job;
             return JobScheduler.RESULT_SUCCESS;
         }
@@ -314,6 +312,40 @@
         }
     }
 
+    // Tests the default behavior (without --finch-seed-no-charging-requirement flag) requires the
+    // device to be charging.
+    @Test
+    @SmallTest
+    public void testFinchSeedChargingRequiredByDefault() {
+        File stamp = VariationsUtils.getStampFile();
+        try {
+            AwVariationsSeedFetcher.scheduleIfNeeded();
+            JobInfo job = mScheduler.getPendingJob(JOB_ID);
+            Assert.assertNotNull("Job should have been scheduled", job);
+            Assert.assertTrue("Job should require charging but does not", job.isRequireCharging());
+        } finally {
+            mScheduler.clear();
+        }
+    }
+
+    // Tests that the --finch-seed-no-charging-requirement flag means the job does not require
+    // charging.
+    @Test
+    @SmallTest
+    @CommandLineFlags.Add(AwSwitches.FINCH_SEED_NO_CHARGING_REQUIREMENT)
+    public void testFinchSeedChargingNotRequiredWithSwitch() {
+        File stamp = VariationsUtils.getStampFile();
+        try {
+            AwVariationsSeedFetcher.scheduleIfNeeded();
+            JobInfo job = mScheduler.getPendingJob(JOB_ID);
+            Assert.assertNotNull("Job should have been scheduled", job);
+            Assert.assertFalse("Job should not require charging when flag is set but it does",
+                    job.isRequireCharging());
+        } finally {
+            mScheduler.clear();
+        }
+    }
+
     @Test
     @SmallTest
     public void testFetch() throws IOException, TimeoutException {
diff --git a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc b/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc
index cea1d0d..23ac395 100644
--- a/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc
+++ b/android_webview/nonembedded/component_updater/installer_policies/aw_package_names_allowlist_component_installer_policy_unittest.cc
@@ -7,9 +7,9 @@
 #include <vector>
 
 #include "android_webview/common/aw_switches.h"
+#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/stl_util.h"
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "base/version.h"
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
index a92b2df..201d127 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -131,10 +131,12 @@
         ComponentName thisComponent = new ComponentName(context, AwVariationsSeedFetcher.class);
         PersistableBundle extras = new PersistableBundle(/*capacity=*/1);
         extras.putInt(JOB_REQUEST_COUNT_KEY, 0);
+        boolean requiresCharging =
+                !CommandLine.getInstance().hasSwitch(AwSwitches.FINCH_SEED_NO_CHARGING_REQUIREMENT);
         JobInfo job =
                 new JobInfo.Builder(JOB_ID, thisComponent)
                         .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
-                        .setRequiresCharging(true)
+                        .setRequiresCharging(requiresCharging)
                         .setBackoffCriteria(JOB_INITIAL_BACKOFF_TIME_IN_MS, JOB_BACKOFF_POLICY)
                         .setExtras(extras)
                         .build();
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn
index e3f95de..161a9d3c 100644
--- a/android_webview/test/BUILD.gn
+++ b/android_webview/test/BUILD.gn
@@ -525,6 +525,7 @@
     "../browser/gfx/test/rendering_test.cc",
     "../browser/gfx/test/rendering_test.h",
     "../browser/lifecycle/aw_contents_lifecycle_notifier_unittest.cc",
+    "../browser/metrics/aw_metrics_service_client_unittest.cc",
     "../browser/metrics/aw_stability_metrics_provider_unittest.cc",
     "../browser/metrics/visibility_metrics_logger_unittest.cc",
     "../browser/permission/media_access_permission_request_unittest.cc",
diff --git a/android_webview/test/browser/embedded_component_loader_test_helper.cc b/android_webview/test/browser/embedded_component_loader_test_helper.cc
index 64503e6f..6058f104 100644
--- a/android_webview/test/browser/embedded_component_loader_test_helper.cc
+++ b/android_webview/test/browser/embedded_component_loader_test_helper.cc
@@ -15,6 +15,7 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "base/values.h"
 #include "base/version.h"
 #include "components/component_updater/android/component_loader_policy.h"
@@ -52,7 +53,7 @@
 
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override {
     // Make sure these values match the values in the
     // EmbeddedComponentLoaderTest.
@@ -83,7 +84,7 @@
 
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override {
     ExpectTrueToJava(
         false, "UnavailableComponentLoaderPolicy#ComponentLoaded is called");
diff --git a/android_webview/tools/system_webview_shell/BUILD.gn b/android_webview/tools/system_webview_shell/BUILD.gn
index eb02524..d938aed3 100644
--- a/android_webview/tools/system_webview_shell/BUILD.gn
+++ b/android_webview/tools/system_webview_shell/BUILD.gn
@@ -136,13 +136,13 @@
   ]
   data = [
     "test/data/",
-    "//third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/",
-    "//third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/",
-    "//third_party/blink/web_tests/platform/win/virtual/stable/webexposed/",
+    "//third_party/blink/web_tests/platform/linux/virtual/stable/http/tests/webexposed/",
+    "//third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/",
+    "//third_party/blink/web_tests/platform/win/virtual/stable/http/tests/webexposed/",
     "//third_party/blink/web_tests/resources/global-interface-listing.js",
-    "//third_party/blink/web_tests/virtual/stable/webexposed/",
-    "//third_party/blink/web_tests/webexposed/global-interface-listing.html",
-    "//third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt",
+    "//third_party/blink/web_tests/virtual/stable/http/tests/webexposed/",
+    "//third_party/blink/web_tests/http/tests/webexposed/global-interface-listing.php",
+    "//third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt",
   ]
   use_webview_provider = system_webview_apk_target
 }
diff --git a/apps/load_and_launch_browsertest.cc b/apps/load_and_launch_browsertest.cc
index 3b4fbd6..d2224b1 100644
--- a/apps/load_and_launch_browsertest.cc
+++ b/apps/load_and_launch_browsertest.cc
@@ -8,8 +8,8 @@
 
 #include "apps/switches.h"
 #include "base/base_switches.h"
+#include "base/cxx17_backports.h"
 #include "base/process/launch.h"
-#include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/test_switches.h"
 #include "base/test/test_timeouts.h"
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 31ebf59f..23bc775 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1829,7 +1829,6 @@
     "//ui/wm",
   ]
   deps = [
-    "//ash/ambient/proto",
     "//ash/app_list",
     "//ash/app_menu",
     "//ash/assistant/model",
@@ -1841,6 +1840,7 @@
     "//ash/constants",
     "//ash/keyboard/ui",
     "//ash/login/resources:resources_grit",
+    "//ash/public/cpp/ambient/proto",
     "//ash/quick_pair",
     "//ash/services/recording",
     "//ash/services/recording/public/mojom",
@@ -2466,7 +2466,6 @@
   deps = [
     ":ash",
     ":test_support",
-    "//ash/ambient/proto",
     "//ash/app_list",
     "//ash/app_list:test_support",
     "//ash/app_list:unit_tests",
@@ -2484,6 +2483,7 @@
     "//ash/public/cpp",
     "//ash/public/cpp:test_support",
     "//ash/public/cpp:unit_tests",
+    "//ash/public/cpp/ambient/proto",
     "//ash/public/cpp/external_arc:test_support",
     "//ash/public/cpp/external_arc:unit_tests",
     "//ash/public/cpp/holding_space:test_support",
@@ -2840,7 +2840,6 @@
   ]
   deps = [
     "//ash",
-    "//ash/ambient/proto",
     "//ash/app_list",
     "//ash/app_list:test_support",
     "//ash/app_menu",
@@ -2852,6 +2851,7 @@
     "//ash/keyboard/ui:test_support",
     "//ash/public/cpp",
     "//ash/public/cpp:test_support",
+    "//ash/public/cpp/ambient/proto",
     "//ash/services/recording:test_support",
     "//ash/services/recording/public/mojom",
     "//base",
diff --git a/ash/ambient/ambient_photo_cache.cc b/ash/ambient/ambient_photo_cache.cc
index 08b51052..508b6de 100644
--- a/ash/ambient/ambient_photo_cache.cc
+++ b/ash/ambient/ambient_photo_cache.cc
@@ -8,8 +8,8 @@
 #include <iostream>
 
 #include "ash/ambient/ambient_constants.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/ambient/ambient_client.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/memory/weak_ptr.h"
diff --git a/ash/ambient/ambient_photo_cache.h b/ash/ambient/ambient_photo_cache.h
index 47ceedf..45aead0 100644
--- a/ash/ambient/ambient_photo_cache.h
+++ b/ash/ambient/ambient_photo_cache.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include <string>
 
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/ash_export.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "base/callback_forward.h"
 #include "base/files/file_path.h"
 
diff --git a/ash/ambient/ambient_photo_cache_unittest.cc b/ash/ambient/ambient_photo_cache_unittest.cc
index fabd0b9..c063e0b 100644
--- a/ash/ambient/ambient_photo_cache_unittest.cc
+++ b/ash/ambient/ambient_photo_cache_unittest.cc
@@ -8,7 +8,7 @@
 #include <iostream>
 
 #include "ash/ambient/ambient_constants.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
diff --git a/ash/ambient/ambient_photo_controller.cc b/ash/ambient/ambient_photo_controller.cc
index 0981ee4..38d9b90d 100644
--- a/ash/ambient/ambient_photo_controller.cc
+++ b/ash/ambient/ambient_photo_controller.cc
@@ -13,9 +13,9 @@
 #include "ash/ambient/ambient_controller.h"
 #include "ash/ambient/ambient_photo_cache.h"
 #include "ash/ambient/model/ambient_backend_model.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
 #include "ash/public/cpp/ambient/ambient_client.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/image_downloader.h"
 #include "ash/shell.h"
 #include "base/barrier_closure.h"
@@ -284,6 +284,7 @@
     ambient::Photo* photo = cache_entry_.mutable_primary_photo();
     photo->set_details(topic->details);
     photo->set_is_portrait(topic->is_portrait);
+    photo->set_type(topic->topic_type);
 
     const int num_callbacks = (topic->related_image_url.empty()) ? 1 : 2;
     auto on_done = base::BarrierClosure(
@@ -301,6 +302,7 @@
       ambient::Photo* photo = cache_entry_.mutable_related_photo();
       photo->set_details(topic->related_details);
       photo->set_is_portrait(topic->is_portrait);
+      photo->set_type(topic->topic_type);
 
       photo_cache_->DownloadPhoto(
           topic->related_image_url,
@@ -491,6 +493,7 @@
   detailed_photo.details = cache_entry_.primary_photo().details();
   detailed_photo.related_details = cache_entry_.related_photo().details();
   detailed_photo.is_portrait = cache_entry_.primary_photo().is_portrait();
+  detailed_photo.topic_type = cache_entry_.primary_photo().type();
   detailed_photo.hash = hash;
 
   ResetImageData();
diff --git a/ash/ambient/ambient_photo_controller.h b/ash/ambient/ambient_photo_controller.h
index 6bdb84e..dd7e4a6 100644
--- a/ash/ambient/ambient_photo_controller.h
+++ b/ash/ambient/ambient_photo_controller.h
@@ -14,9 +14,9 @@
 #include "ash/ambient/ambient_photo_cache.h"
 #include "ash/ambient/model/ambient_backend_model.h"
 #include "ash/ambient/model/ambient_backend_model_observer.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/ash_export.h"
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
diff --git a/ash/ambient/ambient_photo_controller_unittest.cc b/ash/ambient/ambient_photo_controller_unittest.cc
index e14fa1f..29ff5970 100644
--- a/ash/ambient/ambient_photo_controller_unittest.cc
+++ b/ash/ambient/ambient_photo_controller_unittest.cc
@@ -11,10 +11,10 @@
 #include "ash/ambient/ambient_controller.h"
 #include "ash/ambient/model/ambient_backend_model.h"
 #include "ash/ambient/model/ambient_backend_model_observer.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/ambient/test/ambient_ash_test_base.h"
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
 #include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/shell.h"
 #include "base/barrier_closure.h"
 #include "base/base_paths.h"
diff --git a/ash/ambient/backdrop/ambient_backend_controller_impl.cc b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
index 5a2179b..d7d99285 100644
--- a/ash/ambient/backdrop/ambient_backend_controller_impl.cc
+++ b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
@@ -17,6 +17,7 @@
 #include "ash/public/cpp/ambient/ambient_metrics.h"
 #include "ash/public/cpp/ambient/ambient_prefs.h"
 #include "ash/public/cpp/ambient/common/ambient_settings.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
@@ -106,28 +107,28 @@
   return result;
 }
 
-AmbientModeTopicType ToAmbientModeTopicType(
+::ambient::TopicType ToAmbientModeTopicType(
     const backdrop::ScreenUpdate_Topic& topic) {
   if (!topic.has_topic_type())
-    return AmbientModeTopicType::kOther;
+    return ::ambient::TopicType::kOther;
 
   switch (topic.topic_type()) {
     case backdrop::CURATED:
-      return AmbientModeTopicType::kCurated;
+      return ::ambient::TopicType::kCurated;
     case backdrop::PERSONAL_PHOTO:
-      return AmbientModeTopicType::kPersonal;
+      return ::ambient::TopicType::kPersonal;
     case backdrop::FEATURED_PHOTO:
-      return AmbientModeTopicType::kFeatured;
+      return ::ambient::TopicType::kFeatured;
     case backdrop::GEO_PHOTO:
-      return AmbientModeTopicType::kGeo;
+      return ::ambient::TopicType::kGeo;
     case backdrop::CULTURAL_INSTITUTE:
-      return AmbientModeTopicType::kCulturalInstitute;
+      return ::ambient::TopicType::kCulturalInstitute;
     case backdrop::RSS_TOPIC:
-      return AmbientModeTopicType::kRss;
+      return ::ambient::TopicType::kRss;
     case backdrop::CAPTURED_ON_PIXEL:
-      return AmbientModeTopicType::kCapturedOnPixel;
+      return ::ambient::TopicType::kCapturedOnPixel;
     default:
-      return AmbientModeTopicType::kOther;
+      return ::ambient::TopicType::kOther;
   }
 }
 
diff --git a/ash/ambient/model/ambient_backend_model.cc b/ash/ambient/model/ambient_backend_model.cc
index 140e981..e0dde04 100644
--- a/ash/ambient/model/ambient_backend_model.cc
+++ b/ash/ambient/model/ambient_backend_model.cc
@@ -14,14 +14,14 @@
 namespace ash {
 
 namespace {
-int TypeToIndex(AmbientModeTopicType topic_type) {
+int TypeToIndex(::ambient::TopicType topic_type) {
   int index = static_cast<int>(topic_type);
   DCHECK_GE(index, 0);
   return index;
 }
 
-AmbientModeTopicType IndexToType(int index) {
-  AmbientModeTopicType topic_type = static_cast<AmbientModeTopicType>(index);
+::ambient::TopicType IndexToType(int index) {
+  ::ambient::TopicType topic_type = static_cast<::ambient::TopicType>(index);
   return topic_type;
 }
 
@@ -29,16 +29,18 @@
     const std::vector<AmbientModeTopic>& topics) {
   // We pair two topics if:
   // 1. They are in the landscape orientation.
-  // 2. They are in the same category;
+  // 2. They are in the same category.
+  // 3. They are not Geo photos.
   base::flat_map<int, std::vector<int>> topics_by_type;
   std::vector<AmbientModeTopic> paired_topics;
   int topic_idx = -1;
   for (const auto& topic : topics) {
     topic_idx++;
 
+    // Do not pair Geo photos, which will be rotate to fill the screen.
     // If a photo is portrait, it is from Google Photos and should have a paired
     // photo already.
-    if (topic.is_portrait) {
+    if (topic.topic_type == ::ambient::TopicType::kGeo || topic.is_portrait) {
       paired_topics.emplace_back(topic);
       continue;
     }
diff --git a/ash/ambient/model/ambient_backend_model.h b/ash/ambient/model/ambient_backend_model.h
index e2842759..9a75ba17 100644
--- a/ash/ambient/model/ambient_backend_model.h
+++ b/ash/ambient/model/ambient_backend_model.h
@@ -42,6 +42,7 @@
   std::string hash;
   // Whether the image is portrait or not.
   bool is_portrait = false;
+  ::ambient::TopicType topic_type = ::ambient::TopicType::kOther;
 };
 
 // Stores necessary information fetched from the backdrop server to render
diff --git a/ash/ambient/model/ambient_backend_model_unittest.cc b/ash/ambient/model/ambient_backend_model_unittest.cc
index 857c7ae..5322bb4a 100644
--- a/ash/ambient/model/ambient_backend_model_unittest.cc
+++ b/ash/ambient/model/ambient_backend_model_unittest.cc
@@ -10,6 +10,7 @@
 #include "ash/ambient/model/ambient_backend_model_observer.h"
 #include "ash/public/cpp/ambient/ambient_prefs.h"
 #include "ash/public/cpp/ambient/ambient_ui_model.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -39,7 +40,7 @@
                                   bool is_portrait,
                                   const std::string& related_url,
                                   const std::string& related_details,
-                                  AmbientModeTopicType topic_type) {
+                                  ::ambient::TopicType topic_type) {
   ash::AmbientModeTopic topic;
   topic.url = url;
   topic.details = details;
@@ -245,29 +246,29 @@
   topics.emplace_back(CreateTopic(
       /*url=*/"topic1_url", /*details=*/"topic1_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kPersonal));
+      /*related_details=*/"", ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic2_url", /*details=*/"topic2_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kPersonal));
+      /*related_details=*/"", ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic3_url", /*details=*/"topic3_details", /*is_portrait=*/false,
       /*related_url=*/"",
       /*related_details=*/"topic3_related_details",
-      AmbientModeTopicType::kPersonal));
+      ::ambient::TopicType::kPersonal));
 
   topics.emplace_back(CreateTopic(
       /*url=*/"topic4_url", /*details=*/"topic4_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic5_url", /*details=*/"topic5_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic6_url", /*details=*/"topic6_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
 
   AppendTopics(topics);
   EXPECT_EQ(fetched_topics().size(), 2u);
@@ -275,14 +276,14 @@
   EXPECT_EQ(fetched_topics()[0].url, "topic1_url");
   EXPECT_EQ(fetched_topics()[0].details, "topic1_details");
   EXPECT_FALSE(fetched_topics()[0].is_portrait);
-  EXPECT_EQ(fetched_topics()[0].topic_type, AmbientModeTopicType::kPersonal);
+  EXPECT_EQ(fetched_topics()[0].topic_type, ::ambient::TopicType::kPersonal);
   EXPECT_EQ(fetched_topics()[0].related_image_url, "topic2_url");
   EXPECT_EQ(fetched_topics()[0].related_details, "topic2_details");
 
   EXPECT_EQ(fetched_topics()[1].url, "topic4_url");
   EXPECT_EQ(fetched_topics()[1].details, "topic4_details");
   EXPECT_FALSE(fetched_topics()[1].is_portrait);
-  EXPECT_EQ(fetched_topics()[1].topic_type, AmbientModeTopicType::kFeatured);
+  EXPECT_EQ(fetched_topics()[1].topic_type, ::ambient::TopicType::kFeatured);
   EXPECT_EQ(fetched_topics()[1].related_image_url, "topic5_url");
   EXPECT_EQ(fetched_topics()[1].related_details, "topic5_details");
 }
@@ -295,30 +296,30 @@
       /*url=*/"topic1_url", /*details=*/"topic1_details", /*is_portrait=*/true,
       /*related_url=*/"topic1_related_url",
       /*related_details=*/"topic1_related_details",
-      AmbientModeTopicType::kPersonal));
+      ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic2_url", /*details=*/"topic2_details", /*is_portrait=*/true,
       /*related_url=*/"topic2_related_url",
       /*related_details=*/"topic2_related_details",
-      AmbientModeTopicType::kPersonal));
+      ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic3_url", /*details=*/"topic3_details", /*is_portrait=*/true,
       /*related_url=*/"topic3_related_url",
       /*related_details=*/"topic3_related_details",
-      AmbientModeTopicType::kPersonal));
+      ::ambient::TopicType::kPersonal));
 
   topics.emplace_back(CreateTopic(
       /*url=*/"topic4_url", /*details=*/"topic4_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic5_url", /*details=*/"topic5_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic6_url", /*details=*/"topic6_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
 
   AppendTopics(topics);
   EXPECT_EQ(fetched_topics().size(), 4u);
@@ -326,28 +327,28 @@
   EXPECT_EQ(fetched_topics()[0].url, "topic1_url");
   EXPECT_EQ(fetched_topics()[0].details, "topic1_details");
   EXPECT_TRUE(fetched_topics()[0].is_portrait);
-  EXPECT_EQ(fetched_topics()[0].topic_type, AmbientModeTopicType::kPersonal);
+  EXPECT_EQ(fetched_topics()[0].topic_type, ::ambient::TopicType::kPersonal);
   EXPECT_EQ(fetched_topics()[0].related_image_url, "topic1_related_url");
   EXPECT_EQ(fetched_topics()[0].related_details, "topic1_related_details");
 
   EXPECT_EQ(fetched_topics()[1].url, "topic2_url");
   EXPECT_EQ(fetched_topics()[1].details, "topic2_details");
   EXPECT_TRUE(fetched_topics()[1].is_portrait);
-  EXPECT_EQ(fetched_topics()[1].topic_type, AmbientModeTopicType::kPersonal);
+  EXPECT_EQ(fetched_topics()[1].topic_type, ::ambient::TopicType::kPersonal);
   EXPECT_EQ(fetched_topics()[1].related_image_url, "topic2_related_url");
   EXPECT_EQ(fetched_topics()[1].related_details, "topic2_related_details");
 
   EXPECT_EQ(fetched_topics()[2].url, "topic3_url");
   EXPECT_EQ(fetched_topics()[2].details, "topic3_details");
   EXPECT_TRUE(fetched_topics()[2].is_portrait);
-  EXPECT_EQ(fetched_topics()[2].topic_type, AmbientModeTopicType::kPersonal);
+  EXPECT_EQ(fetched_topics()[2].topic_type, ::ambient::TopicType::kPersonal);
   EXPECT_EQ(fetched_topics()[2].related_image_url, "topic3_related_url");
   EXPECT_EQ(fetched_topics()[2].related_details, "topic3_related_details");
 
   EXPECT_EQ(fetched_topics()[3].url, "topic4_url");
   EXPECT_EQ(fetched_topics()[3].details, "topic4_details");
   EXPECT_FALSE(fetched_topics()[3].is_portrait);
-  EXPECT_EQ(fetched_topics()[3].topic_type, AmbientModeTopicType::kFeatured);
+  EXPECT_EQ(fetched_topics()[3].topic_type, ::ambient::TopicType::kFeatured);
   EXPECT_EQ(fetched_topics()[3].related_image_url, "topic5_url");
   EXPECT_EQ(fetched_topics()[3].related_details, "topic5_details");
 }
@@ -361,25 +362,53 @@
   topics.emplace_back(CreateTopic(
       /*url=*/"topic1_url", /*details=*/"topic1_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kPersonal));
+      /*related_details=*/"", ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic2_url", /*details=*/"topic2_details", /*is_portrait=*/true,
       /*related_url=*/"topic2_related_url",
       /*related_details=*/"topic2_related_details",
-      AmbientModeTopicType::kPersonal));
+      ::ambient::TopicType::kPersonal));
   topics.emplace_back(CreateTopic(
       /*url=*/"topic3_url", /*details=*/"topic3_details", /*is_portrait=*/false,
       /*related_url=*/"",
-      /*related_details=*/"", AmbientModeTopicType::kFeatured));
+      /*related_details=*/"", ::ambient::TopicType::kFeatured));
 
   AppendTopics(topics);
   EXPECT_EQ(fetched_topics().size(), 1u);
   EXPECT_EQ(fetched_topics()[0].url, "topic2_url");
   EXPECT_EQ(fetched_topics()[0].details, "topic2_details");
   EXPECT_TRUE(fetched_topics()[0].is_portrait);
-  EXPECT_EQ(fetched_topics()[0].topic_type, AmbientModeTopicType::kPersonal);
+  EXPECT_EQ(fetched_topics()[0].topic_type, ::ambient::TopicType::kPersonal);
   EXPECT_EQ(fetched_topics()[0].related_image_url, "topic2_related_url");
   EXPECT_EQ(fetched_topics()[0].related_details, "topic2_related_details");
 }
 
+TEST_F(AmbientBackendModelTest, ShouldNotPairTwoLandscapeImagesInGeoCategory) {
+  // Set up 2 Geo landscape photos. Will output 2 topics of Geo photos.
+  std::vector<ash::AmbientModeTopic> topics;
+  topics.emplace_back(CreateTopic(
+      /*url=*/"topic1_url", /*details=*/"topic1_details", /*is_portrait=*/false,
+      /*related_url=*/"",
+      /*related_details=*/"", ::ambient::TopicType::kGeo));
+  topics.emplace_back(CreateTopic(
+      /*url=*/"topic2_url", /*details=*/"topic2_details", /*is_portrait=*/false,
+      /*related_url=*/"",
+      /*related_details=*/"", ::ambient::TopicType::kGeo));
+
+  AppendTopics(topics);
+  EXPECT_EQ(fetched_topics().size(), 2u);
+  EXPECT_EQ(fetched_topics()[0].url, "topic1_url");
+  EXPECT_EQ(fetched_topics()[0].details, "topic1_details");
+  EXPECT_FALSE(fetched_topics()[0].is_portrait);
+  EXPECT_EQ(fetched_topics()[0].topic_type, ::ambient::TopicType::kGeo);
+  EXPECT_EQ(fetched_topics()[0].related_image_url, "");
+  EXPECT_EQ(fetched_topics()[0].related_details, "");
+
+  EXPECT_EQ(fetched_topics()[1].url, "topic2_url");
+  EXPECT_EQ(fetched_topics()[1].details, "topic2_details");
+  EXPECT_FALSE(fetched_topics()[1].is_portrait);
+  EXPECT_EQ(fetched_topics()[1].topic_type, ::ambient::TopicType::kGeo);
+  EXPECT_EQ(fetched_topics()[1].related_image_url, "");
+  EXPECT_EQ(fetched_topics()[1].related_details, "");
+}
 }  // namespace ash
diff --git a/ash/ambient/test/ambient_ash_test_base.cc b/ash/ambient/test/ambient_ash_test_base.cc
index 8bc9a57..0288fb7 100644
--- a/ash/ambient/test/ambient_ash_test_base.cc
+++ b/ash/ambient/test/ambient_ash_test_base.cc
@@ -13,7 +13,6 @@
 #include "ash/ambient/ambient_constants.h"
 #include "ash/ambient/ambient_photo_cache.h"
 #include "ash/ambient/ambient_photo_controller.h"
-#include "ash/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/ambient/test/ambient_ash_test_helper.h"
 #include "ash/ambient/ui/ambient_background_image_view.h"
 #include "ash/ambient/ui/ambient_container_view.h"
@@ -23,6 +22,7 @@
 #include "ash/public/cpp/ambient/ambient_prefs.h"
 #include "ash/public/cpp/ambient/ambient_ui_model.h"
 #include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
@@ -300,6 +300,10 @@
   backend_controller()->SetPhotoOrientation(portrait);
 }
 
+void AmbientAshTestBase::SetPhotoTopicType(::ambient::TopicType topic_type) {
+  backend_controller()->SetPhotoTopicType(topic_type);
+}
+
 std::vector<AmbientBackgroundImageView*>
 AmbientAshTestBase::GetAmbientBackgroundImageViews() {
   std::vector<AmbientBackgroundImageView*> result;
diff --git a/ash/ambient/test/ambient_ash_test_base.h b/ash/ambient/test/ambient_ash_test_base.h
index 816756c5..cabbb350 100644
--- a/ash/ambient/test/ambient_ash_test_base.h
+++ b/ash/ambient/test/ambient_ash_test_base.h
@@ -13,6 +13,7 @@
 #include "ash/ambient/ambient_controller.h"
 #include "ash/ambient/test/test_ambient_client.h"
 #include "ash/ambient/ui/ambient_background_image_view.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/test/test_image_downloader.h"
 #include "ash/test/ash_test_base.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
@@ -97,6 +98,8 @@
 
   void SetPhotoOrientation(bool portrait);
 
+  void SetPhotoTopicType(::ambient::TopicType topic_type);
+
   // Advance the task environment timer to expire the lock screen inactivity
   // timer.
   void FastForwardToLockScreenTimeout();
diff --git a/ash/ambient/ui/ambient_background_image_view.cc b/ash/ambient/ui/ambient_background_image_view.cc
index 6b0e9ac..d7eb7e8 100644
--- a/ash/ambient/ui/ambient_background_image_view.cc
+++ b/ash/ambient/ui/ambient_background_image_view.cc
@@ -12,12 +12,18 @@
 #include "ash/ambient/ui/ambient_view_ids.h"
 #include "ash/ambient/ui/media_string_view.h"
 #include "ash/ambient/util/ambient_util.h"
+#include "ash/shell.h"
 #include "base/rand_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/layer.h"
+#include "ui/display/display.h"
+#include "ui/display/manager/display_manager.h"
+#include "ui/display/manager/managed_display_info.h"
+#include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/skbitmap_operations.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
@@ -67,6 +73,55 @@
       image, skia::ImageOperations::RESIZE_BEST, resized);
 }
 
+gfx::ImageSkia MaybeRotateImage(const gfx::ImageSkia& image,
+                                const gfx::Size& view_size,
+                                views::Widget* widget) {
+  if (image.isNull())
+    return image;
+
+  const double image_width = image.width();
+  const double image_height = image.height();
+  const double view_width = view_size.width();
+  const double view_height = view_size.height();
+  const double image_ratio = image_height / image_width;
+  const double view_ratio = view_height / view_width;
+
+  // Rotate the image to have the same orientation as the display.
+  // Keep the relative orientation between the image and the display in portrait
+  // mode.
+  if ((image_ratio - 1) * (view_ratio - 1) < 0) {
+    bool should_rotate = false;
+    SkBitmapOperations::RotationAmount rotation_amount;
+    const int64_t display_id =
+        display::Screen::GetScreen()
+            ->GetDisplayNearestWindow(widget->GetNativeWindow())
+            .id();
+    const auto active_rotation = Shell::Get()
+                                     ->display_manager()
+                                     ->GetDisplayInfo(display_id)
+                                     .GetActiveRotation();
+    switch (active_rotation) {
+      case display::Display::ROTATE_90:
+        should_rotate = true;
+        rotation_amount = SkBitmapOperations::RotationAmount::ROTATION_270_CW;
+        break;
+      case display::Display::ROTATE_270:
+        should_rotate = true;
+        rotation_amount = SkBitmapOperations::RotationAmount::ROTATION_90_CW;
+        break;
+      default:
+        NOTREACHED();
+        break;
+    }
+    if (should_rotate) {
+      return gfx::ImageSkiaOperations::CreateRotatedImage(image,
+                                                          rotation_amount);
+    }
+  }
+
+  return image;
+}
+
 }  // namespace
 
 AmbientBackgroundImageView::AmbientBackgroundImageView(
@@ -105,10 +160,12 @@
 void AmbientBackgroundImageView::UpdateImage(
     const gfx::ImageSkia& image,
     const gfx::ImageSkia& related_image,
-    bool is_portrait) {
+    bool is_portrait,
+    ::ambient::TopicType type) {
   image_unscaled_ = image;
   related_image_unscaled_ = related_image;
   is_portrait_ = is_portrait;
+  topic_type_ = type;
 
   UpdateGlanceableInfoPosition();
 
@@ -288,7 +345,11 @@
   if (image_unscaled.isNull())
     return;
 
-  image_view->SetImage(ResizeImage(image_unscaled, image_view->size()));
+  gfx::ImageSkia image_rotated =
+      topic_type_ == ::ambient::TopicType::kGeo
+          ? MaybeRotateImage(image_unscaled, image_view->size(), GetWidget())
+          : image_unscaled;
+  image_view->SetImage(ResizeImage(image_rotated, image_view->size()));
 
   // Intend to update the image origin in image view.
   // There is no bounds change or preferred size change when updating image from
diff --git a/ash/ambient/ui/ambient_background_image_view.h b/ash/ambient/ui/ambient_background_image_view.h
index 414ff59..fea80cb 100644
--- a/ash/ambient/ui/ambient_background_image_view.h
+++ b/ash/ambient/ui/ambient_background_image_view.h
@@ -9,6 +9,7 @@
 
 #include "ash/ambient/ui/ambient_view_delegate.h"
 #include "ash/ash_export.h"
+#include "ash/public/cpp/ambient/ambient_backend_controller.h"
 #include "base/scoped_multi_source_observation.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/image_view.h"
@@ -45,7 +46,8 @@
   // Updates the display images.
   void UpdateImage(const gfx::ImageSkia& image,
                    const gfx::ImageSkia& related_image,
-                   bool is_portrait);
+                   bool is_portrait,
+                   ::ambient::TopicType type);
 
   // Updates the details for the currently displayed image(s).
   void UpdateImageDetails(const std::u16string& details,
@@ -92,6 +94,8 @@
 
   bool is_portrait_ = false;
 
+  ::ambient::TopicType topic_type_ = ::ambient::TopicType::kOther;
+
   AmbientInfoView* ambient_info_view_ = nullptr;
 
   MediaStringView* media_string_view_ = nullptr;
diff --git a/ash/ambient/ui/photo_view.cc b/ash/ambient/ui/photo_view.cc
index 1dd85649..3afbed2 100644
--- a/ash/ambient/ui/photo_view.cc
+++ b/ash/ambient/ui/photo_view.cc
@@ -94,7 +94,7 @@
 
   image_views_.at(image_index_)
       ->UpdateImage(next_image.photo, next_image.related_photo,
-                    next_image.is_portrait);
+                    next_image.is_portrait, next_image.topic_type);
   image_views_.at(image_index_)
       ->UpdateImageDetails(base::UTF8ToUTF16(next_image.details),
                            base::UTF8ToUTF16(next_image.related_details));
diff --git a/ash/ambient/ui/photo_view_unittest.cc b/ash/ambient/ui/photo_view_unittest.cc
index d68b1d2..dbc1004d 100644
--- a/ash/ambient/ui/photo_view_unittest.cc
+++ b/ash/ambient/ui/photo_view_unittest.cc
@@ -9,6 +9,9 @@
 #include "ash/ambient/test/ambient_ash_test_base.h"
 #include "ash/ambient/ui/ambient_container_view.h"
 #include "ash/assistant/ui/assistant_view_ids.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
+#include "ui/display/manager/display_manager.h"
+#include "ui/display/test/display_manager_test_api.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/controls/image_view.h"
 
@@ -259,6 +262,42 @@
             gfx::Rect(/*x=*/-100, /*y=*/408, /*width=*/800, /*height=*/400));
 }
 
+// Test that when rotates to portrait screen, will rotate Geo landscape images.
+TEST_F(AmbientPhotoViewTest,
+       ShouldRotateGeoLandscapeImageWhenRotateToPortraitScreen) {
+  SetDecodedPhotoSize(/*width=*/20, /*height=*/10);
+  SetPhotoTopicType(::ambient::TopicType::kGeo);
+
+  UpdateDisplay("808x600");
+
+  ShowAmbientScreen();
+
+  FastForwardToNextImage();
+
+  auto* image_view = GetAmbientBackgroundImageView();
+
+  // Will show one landscape image.
+  // Image should be full height. Image height should extend left and right the
+  // visible part of the view.
+  ASSERT_EQ(image_view->GetImageBoundsInScreenForTesting(),
+            gfx::Rect(/*x=*/-196, /*y=*/0, /*width=*/1200, /*height=*/600));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsInScreenForTesting(), gfx::Rect());
+
+  // Rotate screen.
+  int64_t internal_display_id =
+      display::test::DisplayManagerTestApi(display_manager())
+          .SetFirstDisplayAsInternalDisplay();
+  display_manager()->SetDisplayRotation(internal_display_id,
+                                        display::Display::Rotation::ROTATE_90,
+                                        display::Display::RotationSource::USER);
+  // Will show one rotated image.
+  // Image should be full width. Image height should extend above and below the
+  // visible part of the screen.
+  ASSERT_EQ(image_view->GetImageBoundsInScreenForTesting(),
+            gfx::Rect(/*x=*/0, /*y=*/-196, /*width=*/600, /*height=*/1200));
+  ASSERT_EQ(image_view->GetRelatedImageBoundsInScreenForTesting(), gfx::Rect());
+}
+
 // Test that when rotates to landscape screen, will dynamically tile two
 // portrait images.
 TEST_F(AmbientPhotoViewTest, ShouldTileWhenRotateToLandscapeScreen) {
diff --git a/ash/ambient/util/ambient_util.cc b/ash/ambient/util/ambient_util.cc
index 034c15e21..6f2c926 100644
--- a/ash/ambient/util/ambient_util.cc
+++ b/ash/ambient/util/ambient_util.cc
@@ -7,6 +7,7 @@
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
 #include "ash/public/cpp/ambient/ambient_client.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/style/ash_color_provider.h"
 #include "base/no_destructor.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -65,24 +66,24 @@
       kTextShadowElevation, shadow_base_color, shadow_base_color);
 }
 
-bool IsAmbientModeTopicTypeAllowed(AmbientModeTopicType topic_type) {
+bool IsAmbientModeTopicTypeAllowed(::ambient::TopicType topic_type) {
   switch (topic_type) {
-    case ash::AmbientModeTopicType::kCurated:
+    case ::ambient::TopicType::kCurated:
       return chromeos::features::kAmbientModeDefaultFeedEnabled.Get();
-    case ash::AmbientModeTopicType::kCapturedOnPixel:
+    case ::ambient::TopicType::kCapturedOnPixel:
       return chromeos::features::kAmbientModeCapturedOnPixelPhotosEnabled.Get();
-    case ash::AmbientModeTopicType::kCulturalInstitute:
+    case ::ambient::TopicType::kCulturalInstitute:
       return chromeos::features::kAmbientModeCulturalInstitutePhotosEnabled
           .Get();
-    case ash::AmbientModeTopicType::kFeatured:
+    case ::ambient::TopicType::kFeatured:
       return chromeos::features::kAmbientModeFeaturedPhotosEnabled.Get();
-    case ash::AmbientModeTopicType::kGeo:
+    case ::ambient::TopicType::kGeo:
       return chromeos::features::kAmbientModeGeoPhotosEnabled.Get();
-    case ash::AmbientModeTopicType::kPersonal:
+    case ::ambient::TopicType::kPersonal:
       return chromeos::features::kAmbientModePersonalPhotosEnabled.Get();
-    case ash::AmbientModeTopicType::kRss:
+    case ::ambient::TopicType::kRss:
       return chromeos::features::kAmbientModeRssPhotosEnabled.Get();
-    case ash::AmbientModeTopicType::kOther:
+    case ::ambient::TopicType::kOther:
       return false;
   }
 }
diff --git a/ash/ambient/util/ambient_util.h b/ash/ambient/util/ambient_util.h
index 6cd2d0d..0640052 100644
--- a/ash/ambient/util/ambient_util.h
+++ b/ash/ambient/util/ambient_util.h
@@ -8,6 +8,7 @@
 #include "ash/ash_export.h"
 #include "ash/login/ui/lock_screen.h"
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/style/ash_color_provider.h"
 #include "ui/gfx/font_list.h"
 #include "ui/gfx/shadow_value.h"
@@ -38,7 +39,7 @@
 // which kPlaceholderColor will be used for the shadow color.
 ASH_EXPORT gfx::ShadowValues GetTextShadowValues(const ui::NativeTheme* theme);
 
-ASH_EXPORT bool IsAmbientModeTopicTypeAllowed(AmbientModeTopicType topic);
+ASH_EXPORT bool IsAmbientModeTopicTypeAllowed(::ambient::TopicType topic);
 
 }  // namespace util
 }  // namespace ambient
diff --git a/ash/app_list/app_list_bubble_presenter.cc b/ash/app_list/app_list_bubble_presenter.cc
index ab154d0..c58e1ea 100644
--- a/ash/app_list/app_list_bubble_presenter.cc
+++ b/ash/app_list/app_list_bubble_presenter.cc
@@ -17,6 +17,7 @@
 #include "base/bind.h"
 #include "base/check.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
@@ -39,6 +40,8 @@
   if (bubble_widget_)
     return;
 
+  base::Time time_shown = base::Time::Now();
+
   aura::Window* root_window = Shell::GetRootWindowForDisplayId(display_id);
   Shelf* shelf = Shelf::ForWindow(root_window);
   auto bubble_view = std::make_unique<AppListBubbleView>(
@@ -63,6 +66,9 @@
       bubble_widget_, home_button,
       base::BindRepeating(&AppListBubblePresenter::OnPressOutsideBubble,
                           base::Unretained(this)));
+
+  UmaHistogramTimes("Apps.AppListBubbleCreationTime",
+                    base::Time::Now() - time_shown);
 }
 
 ShelfAction AppListBubblePresenter::Toggle(int64_t display_id) {
diff --git a/ash/app_list/app_list_bubble_presenter_unittest.cc b/ash/app_list/app_list_bubble_presenter_unittest.cc
index 7693b011..fd3c3d9 100644
--- a/ash/app_list/app_list_bubble_presenter_unittest.cc
+++ b/ash/app_list/app_list_bubble_presenter_unittest.cc
@@ -15,6 +15,7 @@
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "base/run_loop.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/display/display.h"
@@ -68,6 +69,18 @@
   EXPECT_EQ(1u, NumberOfWidgetsInAppListContainer());
 }
 
+TEST_F(AppListBubblePresenterTest, ShowRecordsCreationTimeHistogram) {
+  base::HistogramTester histogram_tester;
+  AppListBubblePresenter* presenter = GetBubblePresenter();
+
+  presenter->Show(GetPrimaryDisplay().id());
+  histogram_tester.ExpectTotalCount("Apps.AppListBubbleCreationTime", 1);
+
+  presenter->Dismiss();
+  presenter->Show(GetPrimaryDisplay().id());
+  histogram_tester.ExpectTotalCount("Apps.AppListBubbleCreationTime", 2);
+}
+
 TEST_F(AppListBubblePresenterTest, DismissClosesWidget) {
   AppListBubblePresenter* presenter = GetBubblePresenter();
   presenter->Show(GetPrimaryDisplay().id());
diff --git a/ash/components/audio/audio_devices_pref_handler_impl.cc b/ash/components/audio/audio_devices_pref_handler_impl.cc
index 362e3cbe..f6c668b 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl.cc
+++ b/ash/components/audio/audio_devices_pref_handler_impl.cc
@@ -406,7 +406,7 @@
   registry->RegisterDictionaryPref(prefs::kAudioDevicesGainPercent);
   registry->RegisterDictionaryPref(prefs::kAudioDevicesMute);
   registry->RegisterDictionaryPref(prefs::kAudioDevicesState);
-  registry->RegisterBooleanPref(prefs::kInputNoiseCancellationEnabled, true);
+  registry->RegisterBooleanPref(prefs::kInputNoiseCancellationEnabled, false);
 
   // Register the prefs backing the audio muting policies.
   // Policy for audio input is handled by kAudioCaptureAllowed in the Chrome
diff --git a/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc b/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
index 31e87ee..d4954ab55 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
+++ b/ash/components/audio/audio_devices_pref_handler_impl_unittest.cc
@@ -453,9 +453,9 @@
 }
 
 TEST_P(AudioDevicesPrefHandlerTest, InputNoiseCancellationPrefRegistered) {
-  EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState());
-  audio_pref_handler_->SetNoiseCancellationState(false);
   EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState());
+  audio_pref_handler_->SetNoiseCancellationState(true);
+  EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState());
 }
 
 }  // namespace ash
diff --git a/ash/components/audio/audio_devices_pref_handler_stub.h b/ash/components/audio/audio_devices_pref_handler_stub.h
index 9b754c0d..880d2fc 100644
--- a/ash/components/audio/audio_devices_pref_handler_stub.h
+++ b/ash/components/audio/audio_devices_pref_handler_stub.h
@@ -57,7 +57,7 @@
   AudioDeviceVolumeGain audio_device_volume_gain_map_;
   AudioDeviceStateMap audio_device_state_map_;
 
-  bool noise_cancellation_state_ = true;
+  bool noise_cancellation_state_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(AudioDevicesPrefHandlerStub);
 };
diff --git a/ash/components/audio/cras_audio_handler.cc b/ash/components/audio/cras_audio_handler.cc
index 68fb78e..f481bb6 100644
--- a/ash/components/audio/cras_audio_handler.cc
+++ b/ash/components/audio/cras_audio_handler.cc
@@ -1960,6 +1960,7 @@
 }
 
 bool CrasAudioHandler::noise_cancellation_supported() const {
+  DCHECK(main_task_runner_->BelongsToCurrentThread());
   return noise_cancellation_supported_;
 }
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 24de2aa6..85efe291 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -104,10 +104,6 @@
 const base::Feature kArcManagedAdbSideloadingSupport{
     "ArcManagedAdbSideloadingSupport", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Controls whether to enable support for View.onKeyPreIme() of ARC apps.
-const base::Feature kArcPreImeKeyEventSupport{"ArcPreImeKeyEventSupport",
-                                              base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enables resize lock for ARC++ and puts restrictions on window resizing.
 // TODO(takise): Remove this after the feature is fully launched.
 const base::Feature kArcResizeLock{"ArcResizeLock",
@@ -200,8 +196,9 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enable TermsOfServiceURL policy for managed users.
+// https://crbug.com/1221342
 const base::Feature kManagedTermsOfService{"ManagedTermsOfService",
-                                           base::FEATURE_DISABLED_BY_DEFAULT};
+                                           base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enable display of button on Arc provisioning failure dialog for network
 // tests.
@@ -412,7 +409,7 @@
 
 // Enables or disables noise cancellation UI toggle.
 const base::Feature kEnableInputNoiseCancellationUi{
-    "EnableInputNoiseCancellationUi", base::FEATURE_ENABLED_BY_DEFAULT};
+    "EnableInputNoiseCancellationUi", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enables LocalSearchService to be initialized.
 const base::Feature kEnableLocalSearchService{"EnableLocalSearchService",
@@ -465,6 +462,9 @@
 const base::Feature kFamilyLinkOnSchoolDevice{"FamilyLinkOnSchoolDevice",
                                               base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Enables the Fast Pair feature.
+const base::Feature kFastPair{"FastPair", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enables the System Web App (SWA) version of file manager.
 const base::Feature kFilesSWA{"FilesSWA", base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -889,6 +889,14 @@
 const base::Feature kSessionManagerLongKillTimeout{
     "SessionManagerLongKillTimeout", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// If enabled, the session manager daemon will abort the browser if its
+// liveness checker detects a hang, i.e. the browser fails to acknowledge and
+// respond sufficiently to periodic pings.  IMPORTANT NOTE: the feature name
+// here must match exactly the name of the feature in the open-source ChromeOS
+// file session_manager_service.cc.
+const base::Feature kSessionManagerLivenessCheck{
+    "SessionManagerLivenessCheck", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Removes notifier settings from quick settings view.
 const base::Feature kSettingsAppNotificationSettings{
     "SettingsAppNotificationSettings", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -1208,6 +1216,10 @@
   return base::FeatureList::IsEnabled(kFamilyLinkOnSchoolDevice);
 }
 
+bool IsFastPairEnabled() {
+  return base::FeatureList::IsEnabled(kFastPair);
+}
+
 bool IsFileManagerSwaEnabled() {
   return base::FeatureList::IsEnabled(kFilesSWA);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 20236c2..c728e80 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -57,8 +57,6 @@
 extern const base::Feature kArcAdbSideloadingFeature;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kArcManagedAdbSideloadingSupport;
-COMPONENT_EXPORT(ASH_CONSTANTS)
-extern const base::Feature kArcPreImeKeyEventSupport;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kArcResizeLock;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistAutoCorrect;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kAssistEmojiEnhanced;
@@ -183,6 +181,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kExoPointerLock;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kFamilyLinkOnSchoolDevice;
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFastPair;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesSWA;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kFilesSinglePartitionFormat;
@@ -341,6 +340,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kSessionManagerLongKillTimeout;
 COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kSessionManagerLivenessCheck;
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kSettingsAppNotificationSettings;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kShimlessRMAFlow;
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -435,6 +436,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheSWAEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsEcheSWAResizingEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFamilyLinkOnSchoolDeviceEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFastPairEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFileManagerSwaEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFullscreenAlertBubbleEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGaiaCloseViewMessageEnabled();
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index aabc7ec..fd72a72 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -633,6 +633,13 @@
 // Specifies the user which is already logged in.
 const char kLoginUser[] = "login-user";
 
+// Specifies the user that the browser data migration should happen for.
+const char kBrowserDataMigrationForUser[] = "browser-data-migration-for-user";
+
+// Force skip or force migration. Should only be used for testing.
+const char kForceBrowserDataMigrationForTesting[] =
+    "force-browser-data-migration-for-testing";
+
 // Determines the URL to be used when calling the backend.
 const char kMarketingOptInUrl[] = "marketing-opt-in-url";
 
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h
index 979a6d2..9a86253 100644
--- a/ash/constants/ash_switches.h
+++ b/ash/constants/ash_switches.h
@@ -199,6 +199,10 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLoginManager[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLoginProfile[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLoginUser[];
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const char kBrowserDataMigrationForUser[];
+COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const char kForceBrowserDataMigrationForTesting[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kMarketingOptInUrl[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kNaturalScrollDefault[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kNoteTakingAppIds[];
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 7e2af7f..9aabdee 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -561,7 +561,7 @@
       // not know that a drop resulted in a tab being moved and will temporarily
       // visually return the tab to its original position. (crbug.com/1081905)
       operation_ = DragOperation::kMove;
-      StartCanceledAnimation(kCancelAnimationDuration);
+      drag_image_widget_.reset();
     } else if (operation_ == DragOperation::kNone) {
       StartCanceledAnimation(kCancelAnimationDuration);
     } else {
diff --git a/ash/drag_drop/tab_drag_drop_delegate.cc b/ash/drag_drop/tab_drag_drop_delegate.cc
index 47ca61e..4a34c400 100644
--- a/ash/drag_drop/tab_drag_drop_delegate.cc
+++ b/ash/drag_drop/tab_drag_drop_delegate.cc
@@ -124,7 +124,7 @@
           true, SplitViewDragIndicators::WindowDraggingState::kFromTop,
           snap_position));
 
-  UpdateSourceWindowBoundsIfNecessary(snap_position);
+  UpdateSourceWindowBoundsIfNecessary(snap_position, location_in_screen);
 
   tab_dragging_recorder_->RequestNext();
 }
@@ -159,14 +159,27 @@
   // otherwise the SetBounds() call may have no effect.
   source_window_->ClearProperty(kIsSourceWindowForDrag);
 
+  SplitViewController* const split_view_controller =
+      SplitViewController::Get(new_window);
+
+  // If it's already in split view mode, either snap the new window
+  // to the left or the right depending on the drop location.
+  const bool in_split_view_mode = split_view_controller->InSplitViewMode();
+  if (in_split_view_mode) {
+    snap_position =
+        split_view_controller->ComputeSnapPosition(location_in_screen);
+  }
+
   if (snap_position == SplitViewController::SnapPosition::NONE)
     return;
 
-  SplitViewController* const split_view_controller =
-      SplitViewController::Get(new_window);
   split_view_controller->SnapWindow(new_window, snap_position,
                                     /*activate_window=*/true);
 
+  // Do not snap the source window if already in split view mode.
+  if (in_split_view_mode)
+    return;
+
   // The tab drag source window is the last window the user was
   // interacting with. When dropping into split view, it makes the most
   // sense to snap this window to the opposite side. Do this.
@@ -182,7 +195,8 @@
 }
 
 void TabDragDropDelegate::UpdateSourceWindowBoundsIfNecessary(
-    SplitViewController::SnapPosition candidate_snap_position) {
+    SplitViewController::SnapPosition candidate_snap_position,
+    const gfx::Point& location_in_screen) {
   SplitViewController* const split_view_controller =
       SplitViewController::Get(source_window_);
 
@@ -201,8 +215,14 @@
         screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
             root_window_);
     new_source_window_bounds = area;
-    new_source_window_bounds.ClampToCenteredSize(gfx::Size(
-        area.width() * kSourceWindowScale, area.height() * kSourceWindowScale));
+
+    // Only shrink the window when the tab is dragged out of WebUI tab strip.
+    if (location_in_screen.y() >
+        Shell::Get()->shell_delegate()->GetBrowserWebUITabStripHeight()) {
+      new_source_window_bounds.ClampToCenteredSize(
+          gfx::Size(area.width() * kSourceWindowScale,
+                    area.height() * kSourceWindowScale));
+    }
   } else {
     const SplitViewController::SnapPosition opposite_position =
         (candidate_snap_position == SplitViewController::SnapPosition::LEFT)
diff --git a/ash/drag_drop/tab_drag_drop_delegate.h b/ash/drag_drop/tab_drag_drop_delegate.h
index 9ecea74..91631973 100644
--- a/ash/drag_drop/tab_drag_drop_delegate.h
+++ b/ash/drag_drop/tab_drag_drop_delegate.h
@@ -64,7 +64,8 @@
   // |candidate_snap_position| is where the dragged tab will be snapped
   // if dropped immediately.
   void UpdateSourceWindowBoundsIfNecessary(
-      SplitViewController::SnapPosition candidate_snap_position);
+      SplitViewController::SnapPosition candidate_snap_position,
+      const gfx::Point& location_in_screen);
 
   // Puts the source window back into its original position.
   void RestoreSourceWindowBounds();
diff --git a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
index 44199a1..d618c04 100644
--- a/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
+++ b/ash/drag_drop/tab_drag_drop_delegate_unittest.cc
@@ -190,6 +190,70 @@
                                      SplitViewController::SnapPosition::LEFT));
 }
 
+TEST_F(TabDragDropDelegateTest, DropTabInSplitViewMode) {
+  // Enter tablet split view mode by snap the source window to the left.
+  std::unique_ptr<aura::Window> source_window = CreateToplevelTestWindow();
+  SplitViewController* const split_view_controller =
+      SplitViewController::Get(source_window.get());
+  split_view_controller->SnapWindow(source_window.get(),
+                                    SplitViewController::SnapPosition::LEFT);
+  EXPECT_TRUE(split_view_controller->InTabletSplitViewMode());
+
+  const gfx::Point drag_start_location = source_window->bounds().CenterPoint();
+  auto area =
+      screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
+          source_window.get());
+
+  // Emulate a drag to the right side of the screen.
+  // |new_window1| should snap to the right split view.
+  gfx::Point drag_end_location_right(area.width() * 0.8, area.height() * 0.5);
+  TabDragDropDelegate delegate1(Shell::GetPrimaryRootWindow(),
+                                source_window.get(), drag_start_location);
+  delegate1.DragUpdate(drag_start_location);
+  delegate1.DragUpdate(drag_end_location_right);
+  std::unique_ptr<aura::Window> new_window1 = CreateToplevelTestWindow();
+  EXPECT_CALL(*mock_shell_delegate(),
+              CreateBrowserForTabDrop(source_window.get(), _))
+      .Times(1)
+      .WillOnce(Return(new_window1.get()));
+  delegate1.Drop(drag_end_location_right, ui::OSExchangeData());
+
+  EXPECT_TRUE(split_view_controller->InTabletSplitViewMode());
+  EXPECT_EQ(new_window1.get(), split_view_controller->GetSnappedWindow(
+                                   SplitViewController::SnapPosition::RIGHT));
+  EXPECT_EQ(source_window.get(), split_view_controller->GetSnappedWindow(
+                                     SplitViewController::SnapPosition::LEFT));
+  new_window1.reset();  // Close |new_window1|.
+
+  // Emulate a drag to the left side of the screen.
+  // |new_window2| should snap to the left split view.
+  // |source_window| should go into overview mode.
+  gfx::Point drag_end_location_left(area.width() * 0.2, area.height() * 0.5);
+  TabDragDropDelegate delegate2(Shell::GetPrimaryRootWindow(),
+                                source_window.get(), drag_start_location);
+  delegate2.DragUpdate(drag_start_location);
+  delegate2.DragUpdate(drag_end_location_left);
+  std::unique_ptr<aura::Window> new_window2 = CreateToplevelTestWindow();
+  EXPECT_CALL(*mock_shell_delegate(),
+              CreateBrowserForTabDrop(source_window.get(), _))
+      .Times(1)
+      .WillOnce(Return(new_window2.get()));
+  delegate2.Drop(drag_end_location_left, ui::OSExchangeData());
+
+  EXPECT_TRUE(split_view_controller->InTabletSplitViewMode());
+  EXPECT_EQ(nullptr, split_view_controller->GetSnappedWindow(
+                         SplitViewController::SnapPosition::RIGHT));
+  EXPECT_EQ(new_window2.get(), split_view_controller->GetSnappedWindow(
+                                   SplitViewController::SnapPosition::LEFT));
+  ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
+  auto windows_list = Shell::Get()
+                          ->overview_controller()
+                          ->GetWindowsListInOverviewGridsForTest();
+  EXPECT_NE(
+      std::end(windows_list),
+      std::find(windows_list.begin(), windows_list.end(), source_window.get()));
+}
+
 TEST_F(TabDragDropDelegateTest, SourceWindowBoundsUpdatedWhileDragging) {
   // Create the source window. This should automatically fill the work area
   // since we're in tablet mode.
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index 8fbaefa..9376c96 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -333,6 +333,7 @@
 
   deps = [
     "//ash/constants",
+    "//ash/public/cpp/ambient/proto",
     "//base/util/values:values_util",
     "//chromeos/components/quick_answers/public/cpp:prefs",
     "//chromeos/dbus/power:power_manager_proto",
diff --git a/ash/public/cpp/ambient/ambient_backend_controller.h b/ash/public/cpp/ambient/ambient_backend_controller.h
index 6d608f7..a5d15f5c 100644
--- a/ash/public/cpp/ambient/ambient_backend_controller.h
+++ b/ash/public/cpp/ambient/ambient_backend_controller.h
@@ -10,23 +10,13 @@
 #include <vector>
 
 #include "ash/public/cpp/ambient/common/ambient_settings.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/ash_public_export.h"
 #include "base/callback_forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
-enum class AmbientModeTopicType {
-  kCurated = 0,
-  kPersonal,
-  kFeatured,
-  kGeo,
-  kCulturalInstitute,
-  kRss,
-  kCapturedOnPixel,
-  kOther,
-};
-
 // AmbientModeTopic contains the information we need for rendering photo frame
 // for Ambient Mode. Corresponding to the |backdrop::ScreenUpdate::Topic| proto.
 struct ASH_PUBLIC_EXPORT AmbientModeTopic {
@@ -46,7 +36,7 @@
 
   std::string related_details;
 
-  AmbientModeTopicType topic_type = AmbientModeTopicType::kOther;
+  ::ambient::TopicType topic_type = ::ambient::TopicType::kOther;
 
   // Whether the original image is portrait or not. Cannot use aspect ratio of
   // the fetched image to determine it because the fetched image could be
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
index 7350efdc..5c84b4f 100644
--- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
+++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.cc
@@ -91,8 +91,9 @@
     topic.url = kFakeUrl;
     topic.details = kFakeDetails;
     topic.is_portrait = is_portrait_;
-    topic.related_image_url = kFakeUrl;
-    topic.topic_type = AmbientModeTopicType::kCulturalInstitute;
+    if (has_related_image_)
+      topic.related_image_url = kFakeUrl;
+    topic.topic_type = topic_type_;
 
     update.next_topics.emplace_back(topic);
   }
@@ -204,4 +205,10 @@
   is_portrait_ = portrait;
 }
 
+void FakeAmbientBackendControllerImpl::SetPhotoTopicType(
+    ::ambient::TopicType topic_type) {
+  has_related_image_ = false;
+  topic_type_ = topic_type;
+}
+
 }  // namespace ash
diff --git a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h
index 14ca7c6..4d4aa44 100644
--- a/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h
+++ b/ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h
@@ -8,6 +8,7 @@
 #include <array>
 
 #include "ash/public/cpp/ambient/ambient_backend_controller.h"
+#include "ash/public/cpp/ambient/proto/photo_cache_entry.pb.h"
 #include "ash/public/cpp/ash_public_export.h"
 #include "base/callback.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -68,6 +69,8 @@
 
   void SetPhotoOrientation(bool portrait);
 
+  void SetPhotoTopicType(::ambient::TopicType topic_type);
+
  private:
   OnSettingsAndAlbumsFetchedCallback pending_fetch_settings_albums_callback_;
 
@@ -76,6 +79,10 @@
   absl::optional<WeatherInfo> weather_info_;
 
   bool is_portrait_ = false;
+
+  bool has_related_image_ = true;
+
+  ::ambient::TopicType topic_type_ = ::ambient::TopicType::kCulturalInstitute;
 };
 
 }  // namespace ash
diff --git a/ash/ambient/proto/BUILD.gn b/ash/public/cpp/ambient/proto/BUILD.gn
similarity index 100%
rename from ash/ambient/proto/BUILD.gn
rename to ash/public/cpp/ambient/proto/BUILD.gn
diff --git a/ash/ambient/proto/photo_cache_entry.proto b/ash/public/cpp/ambient/proto/photo_cache_entry.proto
similarity index 71%
rename from ash/ambient/proto/photo_cache_entry.proto
rename to ash/public/cpp/ambient/proto/photo_cache_entry.proto
index b0e3d2a..578e748d 100644
--- a/ash/ambient/proto/photo_cache_entry.proto
+++ b/ash/public/cpp/ambient/proto/photo_cache_entry.proto
@@ -8,6 +8,18 @@
 
 package ambient;
 
+// Types of photos, indicating which topic category it comes from.
+enum TopicType {
+  kCurated = 0;
+  kPersonal = 1;
+  kFeatured = 2;
+  kGeo = 3;
+  kCulturalInstitute = 4;
+  kRss = 5;
+  kCapturedOnPixel = 6;
+  kOther = 7;
+}
+
 // Contains image and attributes.
 message Photo {
   // Content of the photo.
@@ -18,6 +30,8 @@
 
   // Whether the uncropped photo is portrait.
   optional bool is_portrait = 3 [default = false];
+
+  optional TopicType type = 4;
 }
 
 // Contains two of ambient photos.
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_manager.cc b/ash/public/cpp/external_arc/message_center/arc_notification_manager.cc
index 017d518..44909e54a 100644
--- a/ash/public/cpp/external_arc/message_center/arc_notification_manager.cc
+++ b/ash/public/cpp/external_arc/message_center/arc_notification_manager.cc
@@ -42,7 +42,8 @@
 namespace {
 
 constexpr char kPlayStorePackageName[] = "com.android.vending";
-constexpr char kArcGmsPackageName[] = "com.chromium.arc.gms";
+constexpr char kArcGmsPackageName[] = "org.chromium.arc.gms";
+
 constexpr char kManagedProvisioningPackageName[] =
     "com.android.managedprovisioning";
 
@@ -533,7 +534,7 @@
     return true;
 
   // Notifications from Play Store are ignored in Public Session and Kiosk mode.
-  // TODO: Use centralized const for Play Store package.
+  // TODO (sarakato): Use centralized const for Play Store package.
   if (data->package_name.has_value() &&
       *data->package_name == kPlayStorePackageName &&
       delegate_->IsPublicSessionOrKiosk()) {
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_surface_impl.cc b/ash/public/cpp/external_arc/message_center/arc_notification_surface_impl.cc
index 2d2df65..d4f1043a6 100644
--- a/ash/public/cpp/external_arc/message_center/arc_notification_surface_impl.cc
+++ b/ash/public/cpp/external_arc/message_center/arc_notification_surface_impl.cc
@@ -4,9 +4,7 @@
 
 #include "ash/public/cpp/external_arc/message_center/arc_notification_surface_impl.h"
 
-#include "ash/constants/ash_features.h"
 #include "base/check_op.h"
-#include "base/feature_list.h"
 #include "components/exo/notification_surface.h"
 #include "components/exo/surface.h"
 #include "ui/aura/client/aura_constants.h"
@@ -92,11 +90,7 @@
   native_view_->SetName("ArcNotificationSurface");
   native_view_->AddChild(surface_->host_window());
 
-  if (base::FeatureList::IsEnabled(
-          chromeos::features::kArcPreImeKeyEventSupport)) {
-    surface_->host_window()->SetProperty(aura::client::kSkipImeProcessing,
-                                         true);
-  }
+  surface_->host_window()->SetProperty(aura::client::kSkipImeProcessing, true);
 
   native_view_->Show();
 }
diff --git a/ash/quick_pair/common/BUILD.gn b/ash/quick_pair/common/BUILD.gn
index fc82dea..6a267eb 100644
--- a/ash/quick_pair/common/BUILD.gn
+++ b/ash/quick_pair/common/BUILD.gn
@@ -21,8 +21,6 @@
     "logging.h",
     "protocol.cc",
     "protocol.h",
-    "quick_pair_features.cc",
-    "quick_pair_features.h",
   ]
 
   deps = [ "//base" ]
diff --git a/ash/quick_pair/common/device.h b/ash/quick_pair/common/device.h
index fe04619..1174054 100644
--- a/ash/quick_pair/common/device.h
+++ b/ash/quick_pair/common/device.h
@@ -18,7 +18,7 @@
 // can use |metadata_id| to query the Service to receive a full metadata object.
 struct Device {
   Device(std::string metadata_id, std::string address, Protocol protocol);
-  Device(const Device&) = default;
+  Device(const Device&) = delete;
   Device(Device&&) = default;
   Device& operator=(const Device&) = delete;
   Device& operator=(Device&&) = delete;
diff --git a/ash/quick_pair/common/quick_pair_features.cc b/ash/quick_pair/common/quick_pair_features.cc
deleted file mode 100644
index a1a1a97..0000000
--- a/ash/quick_pair/common/quick_pair_features.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/quick_pair/common/quick_pair_features.h"
-
-namespace ash {
-namespace features {
-
-// Enables Fast Pair functionality.
-const base::Feature kFastPair{"FastPair", base::FEATURE_DISABLED_BY_DEFAULT};
-
-}  // namespace features
-}  // namespace ash
diff --git a/ash/quick_pair/common/quick_pair_features.h b/ash/quick_pair/common/quick_pair_features.h
deleted file mode 100644
index 0427f76a..0000000
--- a/ash/quick_pair/common/quick_pair_features.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_QUICK_PAIR_COMMON_QUICK_PAIR_FEATURES_H_
-#define ASH_QUICK_PAIR_COMMON_QUICK_PAIR_FEATURES_H_
-
-#include "base/component_export.h"
-#include "base/feature_list.h"
-
-namespace ash {
-namespace features {
-
-COMPONENT_EXPORT(QUICK_PAIR_COMMON) extern const base::Feature kFastPair;
-
-}  // namespace features
-}  // namespace ash
-
-#endif  // ASH_QUICK_PAIR_COMMON_QUICK_PAIR_FEATURES_H_
diff --git a/ash/quick_pair/feature_status_tracker/BUILD.gn b/ash/quick_pair/feature_status_tracker/BUILD.gn
index 0cb38256..458f703 100644
--- a/ash/quick_pair/feature_status_tracker/BUILD.gn
+++ b/ash/quick_pair/feature_status_tracker/BUILD.gn
@@ -23,6 +23,7 @@
   ]
 
   deps = [
+    "//ash/constants",
     "//ash/quick_pair/common",
     "//base",
     "//device/bluetooth",
@@ -66,6 +67,7 @@
   deps = [
     ":feature_status_tracker",
     ":test_support",
+    "//ash/constants",
     "//ash/quick_pair/common",
     "//base/test:test_support",
     "//device/bluetooth",
diff --git a/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.cc b/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.cc
index 5e3baa82..3b4b2160 100644
--- a/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.cc
+++ b/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.cc
@@ -4,7 +4,7 @@
 
 #include "ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.h"
 
-#include "ash/quick_pair/common/quick_pair_features.h"
+#include "ash/constants/ash_features.h"
 #include "ash/quick_pair/feature_status_tracker/base_enabled_provider.h"
 #include "ash/quick_pair/feature_status_tracker/bluetooth_enabled_provider.h"
 #include "base/bind.h"
@@ -22,7 +22,7 @@
           std::move(google_api_key_availability_provider)) {
   // If the flag isn't enabled or if the API keys aren't available,
   // Fast Pair will never be enabled so don't hook up any callbacks.
-  if (base::FeatureList::IsEnabled(features::kFastPair) &&
+  if (features::IsFastPairEnabled() &&
       google_api_key_availability_provider_->is_enabled()) {
     bluetooth_enabled_provider_->SetCallback(base::BindRepeating(
         &FastPairEnabledProvider::OnSubProviderEnabledChanged,
diff --git a/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider_unittest.cc b/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider_unittest.cc
index c39344f..2202fd0 100644
--- a/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider_unittest.cc
+++ b/ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "ash/quick_pair/common/quick_pair_features.h"
+#include "ash/constants/ash_features.h"
 #include "ash/quick_pair/feature_status_tracker/bluetooth_enabled_provider.h"
 #include "ash/quick_pair/feature_status_tracker/fake_bluetooth_adapter.h"
 #include "ash/quick_pair/feature_status_tracker/mock_bluetooth_enabled_provider.h"
diff --git a/ash/quick_pair/scanning/scanner_broker.h b/ash/quick_pair/scanning/scanner_broker.h
index 063f817..58cc30c 100644
--- a/ash/quick_pair/scanning/scanner_broker.h
+++ b/ash/quick_pair/scanning/scanner_broker.h
@@ -21,8 +21,8 @@
  public:
   class Observer : public base::CheckedObserver {
    public:
-    virtual void OnDeviceFound(Device device);
-    virtual void OnDeviceLost(Device device);
+    virtual void OnDeviceFound(const Device& device);
+    virtual void OnDeviceLost(const Device& device);
   };
 
   virtual void AddObserver(Observer* observer) = 0;
diff --git a/ash/quick_pair/scanning/scanner_broker_impl.cc b/ash/quick_pair/scanning/scanner_broker_impl.cc
index 833feec..f34f08f88 100644
--- a/ash/quick_pair/scanning/scanner_broker_impl.cc
+++ b/ash/quick_pair/scanning/scanner_broker_impl.cc
@@ -47,13 +47,13 @@
   QP_LOG(INFO) << "Stoping Fast Pair Scanning.";
 }
 
-void ScannerBrokerImpl::NotifyDeviceFound(Device device) {
+void ScannerBrokerImpl::NotifyDeviceFound(const Device& device) {
   for (auto& observer : observers_) {
     observer.OnDeviceFound(device);
   }
 }
 
-void ScannerBrokerImpl::NotifyDeviceLost(Device device) {
+void ScannerBrokerImpl::NotifyDeviceLost(const Device& device) {
   for (auto& observer : observers_) {
     observer.OnDeviceLost(device);
   }
diff --git a/ash/quick_pair/scanning/scanner_broker_impl.h b/ash/quick_pair/scanning/scanner_broker_impl.h
index b6670b4..72426b5 100644
--- a/ash/quick_pair/scanning/scanner_broker_impl.h
+++ b/ash/quick_pair/scanning/scanner_broker_impl.h
@@ -29,8 +29,8 @@
   void StartFastPairScanning();
   void StopFastPairScanning();
 
-  void NotifyDeviceFound(Device device);
-  void NotifyDeviceLost(Device device);
+  void NotifyDeviceFound(const Device& device);
+  void NotifyDeviceLost(const Device& device);
 
   base::ObserverList<Observer> observers_;
 };
diff --git a/ash/quick_pair/ui/BUILD.gn b/ash/quick_pair/ui/BUILD.gn
index c1bfd0c..d9b5b0f 100644
--- a/ash/quick_pair/ui/BUILD.gn
+++ b/ash/quick_pair/ui/BUILD.gn
@@ -13,17 +13,23 @@
   defines = [ "IS_QUICK_PAIR_UI_IMPL" ]
 
   sources = [
+    "fast_pair/fast_pair_image_decoder.cc",
+    "fast_pair/fast_pair_image_decoder.h",
     "fast_pair/fast_pair_notification_controller.cc",
     "fast_pair/fast_pair_notification_controller.h",
   ]
 
   deps = [
     "//ash/public/cpp:cpp",
+    "//ash/quick_pair/common",
     "//ash/resources/vector_icons",
     "//ash/strings",
     "//base",
+    "//components/image_fetcher/core",
+    "//services/data_decoder/public/cpp",
     "//ui/base",
     "//ui/gfx",
     "//ui/message_center",
+    "//url",
   ]
 }
diff --git a/ash/quick_pair/ui/DEPS b/ash/quick_pair/ui/DEPS
new file mode 100644
index 0000000..a3763bfa
--- /dev/null
+++ b/ash/quick_pair/ui/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+components/image_fetcher",
+]
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.cc b/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.cc
new file mode 100644
index 0000000..93baf07
--- /dev/null
+++ b/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.cc
@@ -0,0 +1,100 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.h"
+
+#include "ash/quick_pair/common/logging.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "components/image_fetcher/core/image_fetcher.h"
+#include "components/image_fetcher/core/request_metadata.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/data_decoder/public/cpp/decode_image.h"
+
+namespace {
+
+constexpr char kImageFetcherUmaClientName[] = "FastPair";
+
+// TODO(crbug.com/1226117) Update policy from Nearby to Fast Pair.
+constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("fast_pair", R"(
+        semantics {
+          sender: "Get Fast Pair Device Image Data from Google"
+          description:
+            "Fast Pair can provide device images to be used in notifications "
+            "for corresponding Fast Pair devices. For a given image url, "
+            "Google's servers will return the image data in bytes to be "
+            "futher decoded here."
+          trigger: "A notification is being triggered for a Fast Pair device."
+          data: "Image pixels and URLs. No user identifier is sent along with "
+                "the data."
+          destination: GOOGLE_OWNED_SERVICE
+        }
+        policy {
+          cookies_allowed: NO
+          setting:
+            "This feature is only enabled for signed-in users who enable "
+            "Nearby Share"
+          chrome_policy {
+            BrowserSignin {
+              policy_options {mode: MANDATORY}
+              BrowserSignin: 0
+            }
+          }
+        })");
+
+void ToImage(DecodeImageCallback on_image_decoded_callback,
+             const SkBitmap& bitmap) {
+  if (bitmap.empty()) {
+    QP_LOG(WARNING) << "Failed to decode image";
+    std::move(on_image_decoded_callback).Run(gfx::Image());
+    return;
+  }
+  gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
+  std::move(on_image_decoded_callback).Run(image);
+}
+
+}  // namespace
+
+namespace ash {
+namespace quick_pair {
+
+FastPairImageDecoder::FastPairImageDecoder(
+    std::unique_ptr<image_fetcher::ImageFetcher> fetcher)
+    : fetcher_(std::move(fetcher)) {}
+
+FastPairImageDecoder::~FastPairImageDecoder() = default;
+
+void FastPairImageDecoder::DecodeImage(
+    const GURL& image_url,
+    DecodeImageCallback on_image_decoded_callback) {
+  fetcher_->FetchImageData(
+      image_url,
+      base::BindOnce(&FastPairImageDecoder::OnImageDataFetched,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     std::move(on_image_decoded_callback)),
+      image_fetcher::ImageFetcherParams(kTrafficAnnotation,
+                                        kImageFetcherUmaClientName));
+}
+
+void FastPairImageDecoder::DecodeImage(
+    const std::vector<uint8_t>& encoded_image_bytes,
+    DecodeImageCallback on_image_decoded_callback) {
+  data_decoder::DecodeImageIsolated(
+      encoded_image_bytes, data_decoder::mojom::ImageCodec::kDefault,
+      /*shrink_to_fit=*/false, data_decoder::kDefaultMaxSizeInBytes,
+      /*desired_image_frame_size=*/gfx::Size(),
+      base::BindOnce(&ToImage, std::move(on_image_decoded_callback)));
+}
+
+void FastPairImageDecoder::OnImageDataFetched(
+    DecodeImageCallback on_image_decoded_callback,
+    const std::string& image_data,
+    const image_fetcher::RequestMetadata& request_metadata) {
+  DecodeImage(std::vector<uint8_t>(image_data.begin(), image_data.end()),
+              std::move(on_image_decoded_callback));
+}
+
+}  // namespace quick_pair
+}  // namespace ash
diff --git a/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.h b/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.h
new file mode 100644
index 0000000..d1f8bf5a
--- /dev/null
+++ b/ash/quick_pair/ui/fast_pair/fast_pair_image_decoder.h
@@ -0,0 +1,56 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_H_
+#define ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
+
+using DecodeImageCallback = base::OnceCallback<void(const gfx::Image&)>;
+
+namespace image_fetcher {
+class ImageFetcher;
+struct RequestMetadata;
+}  // namespace image_fetcher
+
+namespace ash {
+namespace quick_pair {
+
+// The FastPairImageDecoder decodes and returns images for the device used in
+// the notifications. FastPairImageDecoder can decode images from either a
+// given url or from given bytes of image data.
+class FastPairImageDecoder {
+ public:
+  explicit FastPairImageDecoder(
+      std::unique_ptr<image_fetcher::ImageFetcher> fetcher);
+  FastPairImageDecoder(const FastPairImageDecoder&) = delete;
+  FastPairImageDecoder& operator=(const FastPairImageDecoder&) = delete;
+  ~FastPairImageDecoder();
+
+  void DecodeImage(const GURL& image_url,
+                   DecodeImageCallback on_image_decoded_callback);
+
+  void DecodeImage(const std::vector<uint8_t>& encoded_image_bytes,
+                   DecodeImageCallback on_image_decoded_callback);
+
+ private:
+  // ImageDataFetcher callback
+  void OnImageDataFetched(
+      DecodeImageCallback on_image_decoded_callback,
+      const std::string& image_data,
+      const image_fetcher::RequestMetadata& request_metadata);
+
+  std::unique_ptr<image_fetcher::ImageFetcher> fetcher_;
+  base::WeakPtrFactory<FastPairImageDecoder> weak_ptr_factory_{this};
+};
+
+}  // namespace quick_pair
+}  // namespace ash
+
+#endif  // ASH_QUICK_PAIR_UI_FAST_PAIR_FAST_PAIR_IMAGE_DECODER_H_
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index f1e55f6..4fc320ad 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -88,6 +88,10 @@
   // Checks whether a drag-drop operation is a tab drag.
   virtual bool IsTabDrag(const ui::OSExchangeData& drop_data);
 
+  // Return the height of WebUI tab strip used to determine if a tab has
+  // dragged out of it.
+  virtual int GetBrowserWebUITabStripHeight() = 0;
+
   // Drops tab in a new browser window. |drop_data| must be from a tab
   // drag as determined by IsTabDrag() above.
   virtual aura::Window* CreateBrowserForTabDrop(
diff --git a/ash/strings/ash_strings_af.xtb b/ash/strings/ash_strings_af.xtb
index 4af13978..02ff964 100644
--- a/ash/strings/ash_strings_af.xtb
+++ b/ash/strings/ash_strings_af.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Herbegin om op te dateer</translation>
 <translation id="2595239820337756193">5K in myl</translation>
 <translation id="2596078834055697711">Neem vensterskermkiekie</translation>
+<translation id="2607678425161541573">Aanlyn aanmelding word vereis</translation>
 <translation id="2617342710774726426">SIM-kaart is gesluit</translation>
 <translation id="2621713457727696555">Beveilig</translation>
 <translation id="2653019840645008922">Vensterskoot</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index fe1de12b..4b77ebb 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">جارٍ التحميل...</translation>
 <translation id="3712407551474845318">التقاط منطقة</translation>
 <translation id="371370241367527062">الميكروفون الأمامي</translation>
+<translation id="3713734891607377840">فتح الملف بعد اكتمال تنزيله</translation>
 <translation id="3742055079367172538">تم التقاط لقطة الشاشة</translation>
 <translation id="3771549900096082774">وضع التباين العالي</translation>
 <translation id="3773700760453577392">منع أحد المشرفين الدخول المتعدد لـ <ph name="USER_EMAIL" />. لذا على جميع المستخدمين تسجيل الخروج للمتابعة.</translation>
diff --git a/ash/strings/ash_strings_as.xtb b/ash/strings/ash_strings_as.xtb
index 435e25b4a..e51abc2 100644
--- a/ash/strings/ash_strings_as.xtb
+++ b/ash/strings/ash_strings_as.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">ল'ড হৈ আছে...</translation>
 <translation id="3712407551474845318">স্ক্ৰীণৰ আংশিক স্ক্রীণশ্বট লওক</translation>
 <translation id="371370241367527062">সন্মুখৰ মাইক্ৰ’ফ’ন</translation>
+<translation id="3713734891607377840">সম্পূৰ্ণ হোৱাৰ পাছত খোলক</translation>
 <translation id="3742055079367172538">স্ক্ৰীণশ্বট লোৱা হ’ল</translation>
 <translation id="3771549900096082774">হাই কনট্ৰাষ্ট ম’ড</translation>
 <translation id="3773700760453577392">কোনো প্ৰশাসকে <ph name="USER_EMAIL" />ৰ বাবে একাধিক ছাইন ইনৰ সুবিধাটোৰ অনুমতি বাতিল কৰিছে। অব্যাহত ৰাখিবলৈ সকলো ব্যৱহাৰকাৰীয়ে ছাইন আউট কৰিবই লাগিব।</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb
index 324a80a..995e769 100644
--- a/ash/strings/ash_strings_bn.xtb
+++ b/ash/strings/ash_strings_bn.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">লোড হচ্ছে...</translation>
 <translation id="3712407551474845318">অঞ্চল ক্যাপচার করুন</translation>
 <translation id="371370241367527062">সামনের মাইক্রোফোন</translation>
+<translation id="3713734891607377840">সম্পূর্ণ হলে খুলুন</translation>
 <translation id="3742055079367172538">স্ক্রিনশট নেওয়া হয়েছে</translation>
 <translation id="3771549900096082774">উচ্চ কনট্রাস্ট মোড</translation>
 <translation id="3773700760453577392">একজন অ্যাডমিনিস্ট্রেটর <ph name="USER_EMAIL" />-র জন্য একাধিক সাইন-ইন বাতিল করেছেন। চালিয়ে যাওয়ার জন্য, সব ব্যবহারকারীকে অবশ্যই সাইন-আউট করতে হবে।</translation>
diff --git a/ash/strings/ash_strings_bs.xtb b/ash/strings/ash_strings_bs.xtb
index c6c66fa..8f39546 100644
--- a/ash/strings/ash_strings_bs.xtb
+++ b/ash/strings/ash_strings_bs.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Ponovo pokrenite da biste ažurirali</translation>
 <translation id="2595239820337756193">5 km u miljama</translation>
 <translation id="2596078834055697711">Napravite snimak ekrana prozora</translation>
+<translation id="2607678425161541573">Potrebna je online prijava</translation>
 <translation id="2617342710774726426">SIM kartica je zaključana</translation>
 <translation id="2621713457727696555">Osigurano</translation>
 <translation id="2653019840645008922">Snimanje prozora</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb
index 183780d..e918bf0 100644
--- a/ash/strings/ash_strings_de.xtb
+++ b/ash/strings/ash_strings_de.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Wird geladen...</translation>
 <translation id="3712407551474845318">Bereich erfassen</translation>
 <translation id="371370241367527062">Mikrofon auf der Vorderseite</translation>
+<translation id="3713734891607377840">Nach dem Herunterladen öffnen</translation>
 <translation id="3742055079367172538">Screenshot erstellt</translation>
 <translation id="3771549900096082774">Modus mit hohem Kontrast</translation>
 <translation id="3773700760453577392">Ein Administrator hat die Mehrfachanmeldung für <ph name="USER_EMAIL" /> deaktiviert. Alle Nutzer müssen sich abmelden, um fortfahren zu können.</translation>
diff --git a/ash/strings/ash_strings_es-419.xtb b/ash/strings/ash_strings_es-419.xtb
index c8afe61..ca812e23 100644
--- a/ash/strings/ash_strings_es-419.xtb
+++ b/ash/strings/ash_strings_es-419.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Cargando...</translation>
 <translation id="3712407551474845318">Captura parcial de pantalla</translation>
 <translation id="371370241367527062">Micrófono delantero</translation>
+<translation id="3713734891607377840">Abrir cuando se complete la descarga</translation>
 <translation id="3742055079367172538">Captura de pantalla tomada</translation>
 <translation id="3771549900096082774">Modo de contraste alto</translation>
 <translation id="3773700760453577392">Un administrador inhabilitó el acceso múltiple para <ph name="USER_EMAIL" />.
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb
index cae03f7..79f8df8 100644
--- a/ash/strings/ash_strings_et.xtb
+++ b/ash/strings/ash_strings_et.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Taaskäivitage värskendamiseks</translation>
 <translation id="2595239820337756193">5 km miilides</translation>
 <translation id="2596078834055697711">Jäädvustab aknast kuvatõmmise</translation>
+<translation id="2607678425161541573">Veebis sisselogimine on nõutav</translation>
 <translation id="2617342710774726426">SIM-kaart on lukustatud</translation>
 <translation id="2621713457727696555">Kaitstud</translation>
 <translation id="2653019840645008922">Akna jäädvustamine</translation>
diff --git a/ash/strings/ash_strings_eu.xtb b/ash/strings/ash_strings_eu.xtb
index 2016102..fc2d9ecb 100644
--- a/ash/strings/ash_strings_eu.xtb
+++ b/ash/strings/ash_strings_eu.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Kargatzen…</translation>
 <translation id="3712407551474845318">Egin eremuaren argazkia</translation>
 <translation id="371370241367527062">Aurreko mikrofonoa</translation>
+<translation id="3713734891607377840">Deskarga amaitzen denean irekiko da</translation>
 <translation id="3742055079367172538">Pantaila-argazkia hartu da</translation>
 <translation id="3771549900096082774">Kontraste handiko modua</translation>
 <translation id="3773700760453577392">Administratzaile batek <ph name="USER_EMAIL" /> erabiltzaileari saio-hasiera anitza desgaitu dio.
diff --git a/ash/strings/ash_strings_fr.xtb b/ash/strings/ash_strings_fr.xtb
index 9cf8f95..c6114d54 100644
--- a/ash/strings/ash_strings_fr.xtb
+++ b/ash/strings/ash_strings_fr.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Chargement en cours...</translation>
 <translation id="3712407551474845318">Capturer la zone</translation>
 <translation id="371370241367527062">Micro avant</translation>
+<translation id="3713734891607377840">Ouvrir une fois terminé</translation>
 <translation id="3742055079367172538">Capture d'écran réalisée</translation>
 <translation id="3771549900096082774">Mode Contraste élevé</translation>
 <translation id="3773700760453577392">Un administrateur a désactivé la connexion multicompte pour <ph name="USER_EMAIL" />. Tous les utilisateurs doivent se déconnecter pour continuer.</translation>
diff --git a/ash/strings/ash_strings_gl.xtb b/ash/strings/ash_strings_gl.xtb
index f3fedcf..d89272a 100644
--- a/ash/strings/ash_strings_gl.xtb
+++ b/ash/strings/ash_strings_gl.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Cargando...</translation>
 <translation id="3712407551474845318">Capturar área</translation>
 <translation id="371370241367527062">Micrófono frontal</translation>
+<translation id="3713734891607377840">Abrir ao finalizar</translation>
 <translation id="3742055079367172538">Captura de pantalla feita</translation>
 <translation id="3771549900096082774">Modo de alto contraste</translation>
 <translation id="3773700760453577392">Un administrador non permitiu o inicio de sesión múltiple de <ph name="USER_EMAIL" />.
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb
index 071ab6b..8b2322e 100644
--- a/ash/strings/ash_strings_gu.xtb
+++ b/ash/strings/ash_strings_gu.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">લોડ કરી રહ્યું છે...</translation>
 <translation id="3712407551474845318">પ્રદેશને કૅપ્ચર કરો</translation>
 <translation id="371370241367527062">આગળનો માઇક્રોફોન</translation>
+<translation id="3713734891607377840">પૂર્ણ થાય ત્યારે ખોલો</translation>
 <translation id="3742055079367172538">સ્ક્રીનશૉટ લેવાયો</translation>
 <translation id="3771549900096082774">ઉચ્ચ કોન્ટ્રાસ્ટ મોડ</translation>
 <translation id="3773700760453577392">એડમિને <ph name="USER_EMAIL" /> માટે એકથી વધુ સાઇન ઇનને નામંજૂર કર્યું છે. ચાલુ રાખવા માટે બધા વપરાશકર્તાઓએ સાઇન આઉટ કરવું જરૂરી છે.</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb
index c1c6d28..31e9582 100644
--- a/ash/strings/ash_strings_hr.xtb
+++ b/ash/strings/ash_strings_hr.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Ponovo pokrenite da biste ažurirali</translation>
 <translation id="2595239820337756193">5 km u miljama</translation>
 <translation id="2596078834055697711">Snimanje snimke zaslona prozora</translation>
+<translation id="2607678425161541573">Potrebna je online prijava</translation>
 <translation id="2617342710774726426">SIM kartica je zaključana</translation>
 <translation id="2621713457727696555">Zaštićeno</translation>
 <translation id="2653019840645008922">Snimanje prozora</translation>
diff --git a/ash/strings/ash_strings_ml.xtb b/ash/strings/ash_strings_ml.xtb
index 09d04c5..e6c89bd6 100644
--- a/ash/strings/ash_strings_ml.xtb
+++ b/ash/strings/ash_strings_ml.xtb
@@ -346,6 +346,7 @@
 <translation id="370665806235115550">ലോഡ്ചെയ്യുന്നു...</translation>
 <translation id="3712407551474845318">ആവശ്യമുള്ള ഏരിയ ക്യാപ്‌ചർ ചെയ്യുക</translation>
 <translation id="371370241367527062">മുൻവശത്തുള്ള മൈക്രോഫോൺ</translation>
+<translation id="3713734891607377840">പൂർത്തിയാകുമ്പോൾ തുറക്കുക</translation>
 <translation id="3742055079367172538">സ്‌ക്രീൻഷോട്ട് എടുത്തു</translation>
 <translation id="3771549900096082774">ഉയർന്ന ദൃശ്യതീവ്രതാ മോഡ്</translation>
 <translation id="3773700760453577392"><ph name="USER_EMAIL" /> എന്ന ഇമെയിലിലേക്ക് ഒന്നിലധികം പേർ സൈൻ ഇൻ ചെയ്യുന്നത് ഒരു അഡ്‌മിനിസ്‌ട്രേറ്റർ വിലക്കിയിരിക്കുന്നു. തുടരാൻ, എല്ലാ ഉപയോക്താക്കളും സൈൻ ഔട്ട് ചെയ്യണം.</translation>
diff --git a/ash/strings/ash_strings_mn.xtb b/ash/strings/ash_strings_mn.xtb
index cca2bbd1..1fb468e6 100644
--- a/ash/strings/ash_strings_mn.xtb
+++ b/ash/strings/ash_strings_mn.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Шинэчлэхийн тулд дахин эхлүүлэх</translation>
 <translation id="2595239820337756193">5 км милиэр</translation>
 <translation id="2596078834055697711">Цонхны дэлгэцийн зургийг дарах</translation>
+<translation id="2607678425161541573">Онлайнаар нэвтрэх шаардлагатай</translation>
 <translation id="2617342710774726426">SIM карт түгжигдсэн</translation>
 <translation id="2621713457727696555">Хамгаалалттай</translation>
 <translation id="2653019840645008922">Цонхны зураг авах</translation>
diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb
index 07b18546..38f73842 100644
--- a/ash/strings/ash_strings_ne.xtb
+++ b/ash/strings/ash_strings_ne.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">लोड गर्दै...</translation>
 <translation id="3712407551474845318">क्षेत्र कैद गर्नुहोस्</translation>
 <translation id="371370241367527062">अगाडिको माइक्रोफोन</translation>
+<translation id="3713734891607377840">डाउनलोड भएपछि खुल्ने छ</translation>
 <translation id="3742055079367172538">स्क्रिनसट लिइयो</translation>
 <translation id="3771549900096082774">उच्च कन्ट्रास्ट मोड</translation>
 <translation id="3773700760453577392">कुनै प्रशासकले <ph name="USER_EMAIL" /> बाट एकभन्दा बढी साइन इन गर्ने अनुमति दिनुभएको छैन। जारी राख्न सबै प्रयोगकर्ताहरूले अनिवार्य रूपमा साइन आउट गर्नु पर्छ।</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index 6236699..1148f16 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Opnieuw starten om updates uit te voeren</translation>
 <translation id="2595239820337756193">5 km in mijl</translation>
 <translation id="2596078834055697711">Een screenshot van het venster maken</translation>
+<translation id="2607678425161541573">Online inloggen vereist</translation>
 <translation id="2617342710774726426">Simkaart is vergrendeld</translation>
 <translation id="2621713457727696555">Beveiligd</translation>
 <translation id="2653019840645008922">Vensteropname</translation>
diff --git a/ash/strings/ash_strings_or.xtb b/ash/strings/ash_strings_or.xtb
index ee3b8670..a073dfd 100644
--- a/ash/strings/ash_strings_or.xtb
+++ b/ash/strings/ash_strings_or.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">ଲୋଡ୍ କରୁଛି...</translation>
 <translation id="3712407551474845318">ଅଞ୍ଚଳ କ୍ୟାପ୍‍ଚର୍‌ କରନ୍ତୁ</translation>
 <translation id="371370241367527062">ସାମ୍‌ନାପଟର ମାଇକ୍ରୋଫୋନ୍</translation>
+<translation id="3713734891607377840">ସମ୍ପୂର୍ଣ୍ଣ ହେବା ପରେ ଖୋଲନ୍ତୁ</translation>
 <translation id="3742055079367172538">ସ୍କ୍ରି‍ନ୍‍ସଟ୍ ନିଆଯାଇଛି</translation>
 <translation id="3771549900096082774">ଉଚ୍ଚ କଣ୍ଟ୍ରାଷ୍ଟ୍ ମୋଡ୍</translation>
 <translation id="3773700760453577392">ଜଣେ ବ୍ୟବସ୍ଥାପକ <ph name="USER_EMAIL" /> ପାଇଁ ଏକାଧିକ ସାଇନ୍-ଇନ୍‌କୁ ଅନୁମୋଦିତ କରିନାହାନ୍ତି। ଜାରି ରଖିବା ନିମନ୍ତେ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ସାଇନ୍ ଆଉଟ୍ କରିବାକୁ ହେବ।</translation>
diff --git a/ash/strings/ash_strings_pa.xtb b/ash/strings/ash_strings_pa.xtb
index 8f00f88..3caef6c2 100644
--- a/ash/strings/ash_strings_pa.xtb
+++ b/ash/strings/ash_strings_pa.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...</translation>
 <translation id="3712407551474845318">ਖੇਤਰ ਕੈਪਚਰ ਕਰੋ</translation>
 <translation id="371370241367527062">ਮੂਹਰਲਾ ਮਾਈਕ੍ਰੋਫ਼ੋਨ</translation>
+<translation id="3713734891607377840">ਪੂਰਾ ਹੋਣ 'ਤੇ ਖੁੱਲ੍ਹੇ</translation>
 <translation id="3742055079367172538">ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਿਆ ਗਿਆ</translation>
 <translation id="3771549900096082774">ਉੱਚ ਵਖਰੇਵਾਂ ਮੋਡ</translation>
 <translation id="3773700760453577392">ਕਿਸੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ <ph name="USER_EMAIL" /> ਲਈ ਬਹੁ-ਗਿਣਤੀ ਸਾਈਨ-ਇਨ ਨੂੰ ਅਸਵੀਕਾਰ ਕੀਤਾ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਸਾਈਨ-ਆਊਟ ਹੋਣਾ ਲਾਜ਼ਮੀ ਹੈ।</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb
index e5890f2..30ba293 100644
--- a/ash/strings/ash_strings_pt-BR.xtb
+++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -119,7 +119,7 @@
 <translation id="1864454756846565995">Dispositivo USB-C (porta traseira)</translation>
 <translation id="1882814835921407042">Rede móvel indisponível</translation>
 <translation id="1882897271359938046">Espelhamento de <ph name="DISPLAY_NAME" /></translation>
-<translation id="1885785240814121742">Desbloqueio com impressão digital</translation>
+<translation id="1885785240814121742">Desbloqueio por impressão digital</translation>
 <translation id="1888656773939766144"><ph name="DISPLAY_NAME" /> não é compatível com <ph name="SPECIFIED_RESOLUTION" /> (<ph name="SPECIFIED_REFRESH_RATE" /> Hz). A resolução foi modificada para <ph name="FALLBACK_RESOLUTION" /> (<ph name="FALLBACK_REFRESH_RATE" />). Clique em "Confirmar" para manter as mudanças. As configurações anteriores serão restauradas em <ph name="TIMEOUT_SECONDS" />.</translation>
 <translation id="1919743966458266018">O atalho para abrir o gerenciador de tarefas foi alterado. Use <ph name="NEW_SHORTCUT" /> em vez de <ph name="OLD_SHORTCUT" />.</translation>
 <translation id="1923539912171292317">Cliques automáticos</translation>
@@ -866,7 +866,7 @@
 <translation id="7846634333498149051">Teclado</translation>
 <translation id="7860671499921112077">Deslize com três dedos para cima para abrir a Visão geral</translation>
 <translation id="7866482334467279021">ativada</translation>
-<translation id="7868900307798234037">Desbloqueio com impressão digital</translation>
+<translation id="7868900307798234037">Desbloqueio por impressão digital</translation>
 <translation id="7872786842639831132">Desativado</translation>
 <translation id="7875575368831396199">Parece que o Bluetooth está desativado no seu <ph name="DEVICE_TYPE" />. Ative-o para usar o recurso Seu smartphone.</translation>
 <translation id="7886169021410746335">ajustar configurações de privacidade.</translation>
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb
index febbd5f..df2df55b 100644
--- a/ash/strings/ash_strings_si.xtb
+++ b/ash/strings/ash_strings_si.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">යාවත්කාලීන කිරීමට නැවත පණගන්වන්න</translation>
 <translation id="2595239820337756193">සැතපුම්වලින් 5K</translation>
 <translation id="2596078834055697711">කවුළුවේ තිර රුවක් ලබා ගන්න</translation>
+<translation id="2607678425161541573">සබැඳි පිරීම අවශ්‍යයි</translation>
 <translation id="2617342710774726426">SIM පත අගුළු වැටී ඇත</translation>
 <translation id="2621713457727696555">ආරක්ෂිතයි</translation>
 <translation id="2653019840645008922">කවුළු ග්‍රහණය</translation>
diff --git a/ash/strings/ash_strings_sq.xtb b/ash/strings/ash_strings_sq.xtb
index f1cbeda41..5d00eff5 100644
--- a/ash/strings/ash_strings_sq.xtb
+++ b/ash/strings/ash_strings_sq.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">Po ngarkon...</translation>
 <translation id="3712407551474845318">Regjistro sektorin</translation>
 <translation id="371370241367527062">Mikrofoni i përparmë</translation>
+<translation id="3713734891607377840">Hape kur të përfundojë</translation>
 <translation id="3742055079367172538">Pamja e ekranit u mor</translation>
 <translation id="3771549900096082774">Modaliteti i kontrastit të lartë</translation>
 <translation id="3773700760453577392">Një administrator ka ndaluar identifikimin e shumëfishtë për <ph name="USER_EMAIL" />. Të gjithë përdoruesit duhet të dalin për të vazhduar.</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb
index ca51a4d1..541e06d6 100644
--- a/ash/strings/ash_strings_ta.xtb
+++ b/ash/strings/ash_strings_ta.xtb
@@ -63,11 +63,11 @@
 <translation id="1341651618736211726">கூடுதல் விருப்பங்கள்</translation>
 <translation id="1346748346194534595">வலது</translation>
 <translation id="1351937230027495976">மெனுவைச் சுருக்கு</translation>
-<translation id="1383597849754832576">உடனடி வசனத்தின் கோப்புகளைப் பதிவிறக்க முடியவில்லை. பிறகு முயலவும்.</translation>
+<translation id="1383597849754832576">உடனடி வசனத்தின் ஃபைல்களைப் பதிவிறக்க முடியவில்லை. பிறகு முயலவும்.</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1391102559483454063">இயக்கப்பட்டுள்ளது</translation>
 <translation id="1407069428457324124">டார்க் தீம்</translation>
-<translation id="1419738280318246476">அறிவிப்பில் வந்த செயலைச் செய்வதற்கு, சாதனத்தைத் திறங்கள்</translation>
+<translation id="1419738280318246476">அறிவிப்பில் வந்த செயலைச் செய்வதற்கு, சாதனத்தை அன்லாக் செய்யுங்கள்</translation>
 <translation id="1420408895951708260">நைட் லைட்டை ஆன்/ஆஃப் செய்யும். <ph name="STATE_TEXT" /></translation>
 <translation id="1426410128494586442">ஆம்</translation>
 <translation id="144853431011121127">உங்கள் மொபைலுக்கு வரும் அறிவிப்புகளை <ph name="DEVICE_TYPE" /> இல் பெறலாம்</translation>
@@ -119,7 +119,7 @@
 <translation id="1864454756846565995">USB-C சாதனம் (பின்பக்கப் போர்ட்)</translation>
 <translation id="1882814835921407042">மொபைலில் நெட்வொர்க் இல்லை</translation>
 <translation id="1882897271359938046"><ph name="DISPLAY_NAME" /> ஐப் பிரதிபலிக்கிறது</translation>
-<translation id="1885785240814121742">கைரேகை மூலம் திறக்கலாம்</translation>
+<translation id="1885785240814121742">கைரேகை மூலம் அன்லாக் செய்யலாம்</translation>
 <translation id="1888656773939766144"><ph name="SPECIFIED_RESOLUTION" /> தெளிவுத்திறனை (<ph name="SPECIFIED_REFRESH_RATE" /> Hz) <ph name="DISPLAY_NAME" /> ஆதரிக்கவில்லை. தெளிவுத்திறன் <ph name="FALLBACK_RESOLUTION" /> (<ph name="FALLBACK_REFRESH_RATE" />) என்பதற்கு மாற்றப்பட்டது. மாற்றங்களை வைத்திருக்க ‘உறுதிசெய்’ என்பதைக் கிளிக் செய்யவும். இன்னும் <ph name="TIMEOUT_SECONDS" /> இல் முந்தைய அமைப்புகள் மீட்டெடுக்கப்படும்.</translation>
 <translation id="1919743966458266018">செயல் நிர்வாகியைத் திறப்பதற்கான ஷார்ட்கட் மாற்றப்பட்டது. <ph name="OLD_SHORTCUT" /> க்குப் பதிலாக <ph name="NEW_SHORTCUT" /> ஐப் பயன்படுத்தவும்.</translation>
 <translation id="1923539912171292317">தன்னியக்க கிளிக்குகள்</translation>
@@ -346,6 +346,7 @@
 <translation id="370665806235115550">ஏற்றுகிறது…</translation>
 <translation id="3712407551474845318">பகுதியைப் படமெடு</translation>
 <translation id="371370241367527062">முன்பக்க மைக்ரோஃபோன்</translation>
+<translation id="3713734891607377840">பதிவிறக்கியதும் திற</translation>
 <translation id="3742055079367172538">ஸ்கிரீன்ஷாட் எடுக்கப்பட்டது</translation>
 <translation id="3771549900096082774">அதிக ஒளி மாறுபாட்டுப் பயன்முறை</translation>
 <translation id="3773700760453577392"><ph name="USER_EMAIL" />க்கு, பல உள்நுழைவை நிர்வாகி அனுமதிக்கவில்லை. தொடர, எல்லாப் பயனர்களும் வெளியேற வேண்டும்.</translation>
@@ -444,7 +445,7 @@
 <translation id="4451374464530248585">இந்தக் கீபோர்டு ஷார்ட்கட் மாற்றப்பட்டுள்ளது: Alt + கீழ்நோக்கிய அம்புக்குறி. Page Down பட்டனைப் பயன்படுத்த, <ph name="LAUNCHER_KEY_NAME" /> பட்டன் + கீழ்நோக்கிய அம்புக்குறி பட்டனை அழுத்தவும்.</translation>
 <translation id="445864333228800152">மாலை வணக்கம்,</translation>
 <translation id="4458688154122353284">ஸ்கிரீனை ரெக்கார்டு செய்வதை நிறுத்து</translation>
-<translation id="4471354919263203780">பேச்சு அறிதலுக்கான கோப்புகளைப் பதிவிறக்குகிறது... <ph name="PERCENT" />%</translation>
+<translation id="4471354919263203780">பேச்சு அறிதலுக்கான ஃபைல்களைப் பதிவிறக்குகிறது... <ph name="PERCENT" />%</translation>
 <translation id="4472575034687746823">தொடங்குக</translation>
 <translation id="4477350412780666475">அடுத்த டிராக்</translation>
 <translation id="4477892968187500306">Googleளால் சரிபார்க்கப்படாத ஆப்ஸ் இந்தச் சாதனத்தில் இருக்கக்கூடும்.</translation>
@@ -477,7 +478,7 @@
 <translation id="4642092649622328492">பகுதியளவு ஸ்கிரீன்ஷாட்டை எடுக்கும்</translation>
 <translation id="4659419629803378708">ChromeVox இயக்கப்பட்டது</translation>
 <translation id="4665114317261903604">'தொந்தரவு செய்ய வேண்டாம்' அம்சத்தை ஆன்/ஆஃப் செய்யும். <ph name="STATE_TEXT" /></translation>
-<translation id="4696813013609194136">பெற்றோர் குறியீட்டின் மூலம் சாதனத்தை திறத்தல்</translation>
+<translation id="4696813013609194136">பெற்றோர் குறியீட்டின் மூலம் சாதனத்தை அன்லாக் செய்தல்</translation>
 <translation id="4702647871202761252">தனிப்பட்ட திரை முடக்கப்பட்டுள்ளது</translation>
 <translation id="4705716602320768426">கருத்தைப் பதிவுசெய்க</translation>
 <translation id="4731797938093519117">பெற்றோர் அணுகல்</translation>
@@ -1013,7 +1014,7 @@
 <translation id="8982906748181120328">‘அருகில் பகிர்தல்’ தெரிவுநிலை</translation>
 <translation id="8983038754672563810">HSPA</translation>
 <translation id="8990809378771970590"><ph name="IME_NAME" /> பயன்படுத்தப்படுகிறது</translation>
-<translation id="899350903320462459">அறிவிப்பில் வந்த செயலைச் செய்வதற்கு, சாதனத்தை <ph name="LOGIN_ID" /> ஆகத் திறக்கவும்</translation>
+<translation id="899350903320462459">அறிவிப்பில் வந்த செயலைச் செய்வதற்கு, சாதனத்தை <ph name="LOGIN_ID" /> ஆக அன்லாக் செய்யவும்</translation>
 <translation id="9017320285115481645">Family Link பெற்றோர் அணுகல் குறியீட்டை உள்ளிடவும்.</translation>
 <translation id="9024331582947483881">முழுத்திரை</translation>
 <translation id="9047624247355796468"><ph name="NETWORK_NAME" />க்கான அமைப்புகளைத் திறக்கும்</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb
index 28db316..71d7eb1 100644
--- a/ash/strings/ash_strings_te.xtb
+++ b/ash/strings/ash_strings_te.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">లోడ్ అవుతోంది...</translation>
 <translation id="3712407551474845318">ప్రాంతాన్ని సంగ్రహించు</translation>
 <translation id="371370241367527062">ముందువైపు మైక్రోఫోన్</translation>
+<translation id="3713734891607377840">పూర్తయినప్పుడు తెరవండి</translation>
 <translation id="3742055079367172538">స్క్రీన్‌షాట్ తీసినప్పుడు</translation>
 <translation id="3771549900096082774">అధిక కాంట్రాస్ట్ మోడ్</translation>
 <translation id="3773700760453577392"><ph name="USER_EMAIL" /> కోసం బహుళ సైన్-ఇన్ అనుమతిని నిర్వాహకుడు తిరస్కరించారు.
diff --git a/ash/strings/ash_strings_ur.xtb b/ash/strings/ash_strings_ur.xtb
index 023979c..1873a6e 100644
--- a/ash/strings/ash_strings_ur.xtb
+++ b/ash/strings/ash_strings_ur.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">لوڈ ہو رہے ہیں…</translation>
 <translation id="3712407551474845318">علاقہ کیپچر کریں</translation>
 <translation id="371370241367527062">سامنے کا مائیکروفون</translation>
+<translation id="3713734891607377840">مکمل ہونے پر کھولیں</translation>
 <translation id="3742055079367172538">اسکرین شاٹ لی گئی</translation>
 <translation id="3771549900096082774">اعلی تناسب امتزاج وضع</translation>
 <translation id="3773700760453577392">منتظم نے <ph name="USER_EMAIL" /> کیلئے متعدد سائن ان کی اجازت نہیں دی ہے۔ جاری رکھنے کیلئے تمام صارفین کا سائن آؤٹ کرنا لازمی ہے۔</translation>
diff --git a/ash/strings/ash_strings_uz.xtb b/ash/strings/ash_strings_uz.xtb
index 06ce0737..0509e5b 100644
--- a/ash/strings/ash_strings_uz.xtb
+++ b/ash/strings/ash_strings_uz.xtb
@@ -208,6 +208,7 @@
 <translation id="2582112259361606227">Yangilash uchun qayta ishga tushiring</translation>
 <translation id="2595239820337756193">5 mil kilometrda</translation>
 <translation id="2596078834055697711">Oynadan skrinshot olish</translation>
+<translation id="2607678425161541573">Onlayn kirish zarur</translation>
 <translation id="2617342710774726426">SIM karta qulflangan</translation>
 <translation id="2621713457727696555">Himoyalangan</translation>
 <translation id="2653019840645008922">Oynani tasvirga olish</translation>
diff --git a/ash/strings/ash_strings_zh-CN.xtb b/ash/strings/ash_strings_zh-CN.xtb
index 8adecf7..3ca7370 100644
--- a/ash/strings/ash_strings_zh-CN.xtb
+++ b/ash/strings/ash_strings_zh-CN.xtb
@@ -347,6 +347,7 @@
 <translation id="370665806235115550">正在加载...</translation>
 <translation id="3712407551474845318">获取区域截图</translation>
 <translation id="371370241367527062">前置麦克风</translation>
+<translation id="3713734891607377840">下载完成后打开</translation>
 <translation id="3742055079367172538">已完成屏幕截图</translation>
 <translation id="3771549900096082774">高反差模式</translation>
 <translation id="3773700760453577392">管理员已禁止 <ph name="USER_EMAIL" /> 使用多帐号登录功能。所有用户都必须先退出帐号才能继续。</translation>
diff --git a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc
index b454674..064accb2 100644
--- a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc
+++ b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc
@@ -231,7 +231,7 @@
 
   views::ToggleButton* toggle =
       (views::ToggleButton*)toggles_map_[internal_mic.id]->children()[1];
-  EXPECT_TRUE(toggle->GetIsOn());
+  EXPECT_FALSE(toggle->GetIsOn());
 }
 
 TEST_F(UnifiedAudioDetailedViewControllerTest,
@@ -239,7 +239,7 @@
   scoped_feature_list_.InitAndEnableFeature(
       features::kEnableInputNoiseCancellationUi);
 
-  audio_pref_handler_->SetNoiseCancellationState(false);
+  audio_pref_handler_->SetNoiseCancellationState(true);
 
   fake_cras_audio_client()->SetAudioNodesAndNotifyObserversForTesting(
       GenerateAudioNodeList({kInternalMic, kMicJack, kFrontMic, kRearMic}));
@@ -258,8 +258,8 @@
   widget->SetContentsView(toggle);
 
   // The toggle loaded the pref correctly.
-  EXPECT_FALSE(toggle->GetIsOn());
-  EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState());
+  EXPECT_TRUE(toggle->GetIsOn());
+  EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState());
 
   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(),
                        ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
@@ -268,11 +268,11 @@
   // Flipping the toggle.
   views::test::ButtonTestApi(toggle).NotifyClick(press);
   // The new state of the toggle must be saved to the prefs.
-  EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState());
+  EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState());
 
   // Flipping back and checking the prefs again.
   views::test::ButtonTestApi(toggle).NotifyClick(press);
-  EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState());
+  EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState());
 }
 
 // TODO(1205197): Remove this test once the flag is removed.
diff --git a/ash/system/dark_mode/OWNERS b/ash/system/dark_mode/OWNERS
index d34399a..847ebd39 100644
--- a/ash/system/dark_mode/OWNERS
+++ b/ash/system/dark_mode/OWNERS
@@ -1,3 +1,2 @@
 amehfooz@chromium.org
-minch@chromium.org
-tengs@chromium.org
+minch@chromium.org
\ No newline at end of file
diff --git a/ash/system/network/network_state_list_detailed_view.cc b/ash/system/network/network_state_list_detailed_view.cc
index 91c6ebf..6349cb8 100644
--- a/ash/system/network/network_state_list_detailed_view.cc
+++ b/ash/system/network/network_state_list_detailed_view.cc
@@ -296,32 +296,34 @@
 
 void NetworkStateListDetailedView::HandleViewClickedImpl(
     NetworkStatePropertiesPtr network) {
-  // If the network is locked and is cellular show SIM unlock dialog in OS
-  // Settings.
-  if (network->type == NetworkType::kCellular &&
-      base::FeatureList::IsEnabled(
-          chromeos::features::kUpdatedCellularActivationUi) &&
-      network->type_state->get_cellular()->sim_locked) {
-    if (!Shell::Get()->session_controller()->ShouldEnableSettings()) {
+  if (network) {
+    // If the network is locked and is cellular show SIM unlock dialog in OS
+    // Settings.
+    if (network->type == NetworkType::kCellular &&
+        base::FeatureList::IsEnabled(
+            chromeos::features::kUpdatedCellularActivationUi) &&
+        network->type_state->get_cellular()->sim_locked) {
+      if (!Shell::Get()->session_controller()->ShouldEnableSettings()) {
+        return;
+      }
+      Shell::Get()->system_tray_model()->client()->ShowSettingsSimUnlock();
       return;
     }
-    Shell::Get()->system_tray_model()->client()->ShowSettingsSimUnlock();
-    return;
-  }
 
-  if (network && CanNetworkConnect(
-                     network->connection_state, network->type,
-                     network->type == NetworkType::kCellular
-                         ? network->type_state->get_cellular()->activation_state
-                         : ActivationStateType::kUnknown,
-                     network->connectable)) {
-    Shell::Get()->metrics()->RecordUserMetricsAction(
-        list_type_ == LIST_TYPE_VPN
-            ? UMA_STATUS_AREA_CONNECT_TO_VPN
-            : UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK);
-    LogUserNetworkEvent(*network.get());
-    chromeos::NetworkConnect::Get()->ConnectToNetworkId(network->guid);
-    return;
+    if (CanNetworkConnect(
+            network->connection_state, network->type,
+            network->type == NetworkType::kCellular
+                ? network->type_state->get_cellular()->activation_state
+                : ActivationStateType::kUnknown,
+            network->connectable)) {
+      Shell::Get()->metrics()->RecordUserMetricsAction(
+          list_type_ == LIST_TYPE_VPN
+              ? UMA_STATUS_AREA_CONNECT_TO_VPN
+              : UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK);
+      LogUserNetworkEvent(*network.get());
+      chromeos::NetworkConnect::Get()->ConnectToNetworkId(network->guid);
+      return;
+    }
   }
   // If the network is no longer available or not connectable or configurable,
   // show the Settings UI.
diff --git a/ash/system/phonehub/OWNERS b/ash/system/phonehub/OWNERS
index cda073f..4a30830 100644
--- a/ash/system/phonehub/OWNERS
+++ b/ash/system/phonehub/OWNERS
@@ -1,2 +1 @@
-tengs@chromium.org
-file://chromeos/components/phonehub/OWNERS
+file://chromeos/components/phonehub/OWNERS
\ No newline at end of file
diff --git a/ash/system/privacy_screen/OWNERS b/ash/system/privacy_screen/OWNERS
deleted file mode 100644
index d12cc955..0000000
--- a/ash/system/privacy_screen/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tengs@chromium.org
diff --git a/ash/system/tray/OWNERS b/ash/system/tray/OWNERS
index 430ce8a..1ed3536 100644
--- a/ash/system/tray/OWNERS
+++ b/ash/system/tray/OWNERS
@@ -1,2 +1 @@
-tetsui@chromium.org
-tengs@chromium.org
+tetsui@chromium.org
\ No newline at end of file
diff --git a/ash/system/unified/OWNERS b/ash/system/unified/OWNERS
index d59b406..847cbcc0 100644
--- a/ash/system/unified/OWNERS
+++ b/ash/system/unified/OWNERS
@@ -1,3 +1,2 @@
 amehfooz@chromium.org
-tetsui@chromium.org
-tengs@chromium.org
+tetsui@chromium.org
\ No newline at end of file
diff --git a/ash/test_shell_delegate.cc b/ash/test_shell_delegate.cc
index a82c5982..1e1da30 100644
--- a/ash/test_shell_delegate.cc
+++ b/ash/test_shell_delegate.cc
@@ -57,6 +57,10 @@
   return should_wait_for_touch_ack_;
 }
 
+int TestShellDelegate::GetBrowserWebUITabStripHeight() {
+  return 0;
+}
+
 void TestShellDelegate::BindMultiDeviceSetup(
     mojo::PendingReceiver<chromeos::multidevice_setup::mojom::MultiDeviceSetup>
         receiver) {
diff --git a/ash/test_shell_delegate.h b/ash/test_shell_delegate.h
index 1c480f4..8fef474 100644
--- a/ash/test_shell_delegate.h
+++ b/ash/test_shell_delegate.h
@@ -41,6 +41,7 @@
   bool CanGoBack(gfx::NativeWindow window) const override;
   void SetTabScrubberEnabled(bool enabled) override;
   bool ShouldWaitForTouchPressAck(gfx::NativeWindow window) override;
+  int GetBrowserWebUITabStripHeight() override;
   void BindMultiDeviceSetup(
       mojo::PendingReceiver<
           chromeos::multidevice_setup::mojom::MultiDeviceSetup> receiver)
diff --git a/ash/webui/diagnostics_ui/backend/cpu_usage_data.cc b/ash/webui/diagnostics_ui/backend/cpu_usage_data.cc
index 6e882ac4..22adaca 100644
--- a/ash/webui/diagnostics_ui/backend/cpu_usage_data.cc
+++ b/ash/webui/diagnostics_ui/backend/cpu_usage_data.cc
@@ -4,7 +4,7 @@
 
 #include "ash/webui/diagnostics_ui/backend/cpu_usage_data.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 CpuUsageData::CpuUsageData(uint64_t user_time,
@@ -49,4 +49,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/cpu_usage_data.h b/ash/webui/diagnostics_ui/backend/cpu_usage_data.h
index 264b347..1641d4e 100644
--- a/ash/webui/diagnostics_ui/backend/cpu_usage_data.h
+++ b/ash/webui/diagnostics_ui/backend/cpu_usage_data.h
@@ -8,7 +8,7 @@
 #include <cstdint>
 #include <limits>
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class CpuUsageData {
@@ -43,6 +43,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_CPU_USAGE_DATA_H_
diff --git a/ash/webui/diagnostics_ui/backend/cpu_usage_data_unittest.cc b/ash/webui/diagnostics_ui/backend/cpu_usage_data_unittest.cc
index bbb497f..76e291cd5 100644
--- a/ash/webui/diagnostics_ui/backend/cpu_usage_data_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/cpu_usage_data_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class CpuUsageDataTest : public testing::Test {
@@ -76,4 +76,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.cc b/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.cc
index 853fc92c..cebc38f 100644
--- a/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.cc
+++ b/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.cc
@@ -9,28 +9,28 @@
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.h"
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-using cros_healthd::mojom::BatteryInfo;
-using cros_healthd::mojom::BatteryResult;
-using cros_healthd::mojom::BatteryResultPtr;
-using cros_healthd::mojom::CpuInfo;
-using cros_healthd::mojom::CpuResult;
-using cros_healthd::mojom::CpuResultPtr;
-using cros_healthd::mojom::MemoryInfo;
-using cros_healthd::mojom::MemoryResult;
-using cros_healthd::mojom::MemoryResultPtr;
-using cros_healthd::mojom::NonInteractiveRoutineUpdate;
-using cros_healthd::mojom::NonInteractiveRoutineUpdatePtr;
-using cros_healthd::mojom::RoutineUpdate;
-using cros_healthd::mojom::RoutineUpdateUnion;
-using cros_healthd::mojom::RoutineUpdateUnionPtr;
-using cros_healthd::mojom::SystemInfo;
-using cros_healthd::mojom::SystemResult;
-using cros_healthd::mojom::SystemResultPtr;
-using cros_healthd::mojom::TelemetryInfo;
+using ::chromeos::cros_healthd::mojom::BatteryInfo;
+using ::chromeos::cros_healthd::mojom::BatteryResult;
+using ::chromeos::cros_healthd::mojom::BatteryResultPtr;
+using ::chromeos::cros_healthd::mojom::CpuInfo;
+using ::chromeos::cros_healthd::mojom::CpuResult;
+using ::chromeos::cros_healthd::mojom::CpuResultPtr;
+using ::chromeos::cros_healthd::mojom::MemoryInfo;
+using ::chromeos::cros_healthd::mojom::MemoryResult;
+using ::chromeos::cros_healthd::mojom::MemoryResultPtr;
+using ::chromeos::cros_healthd::mojom::NonInteractiveRoutineUpdate;
+using ::chromeos::cros_healthd::mojom::NonInteractiveRoutineUpdatePtr;
+using ::chromeos::cros_healthd::mojom::RoutineUpdate;
+using ::chromeos::cros_healthd::mojom::RoutineUpdateUnion;
+using ::chromeos::cros_healthd::mojom::RoutineUpdateUnionPtr;
+using ::chromeos::cros_healthd::mojom::SystemInfo;
+using ::chromeos::cros_healthd::mojom::SystemResult;
+using ::chromeos::cros_healthd::mojom::SystemResultPtr;
+using ::chromeos::cros_healthd::mojom::TelemetryInfo;
 
 template <typename TResult, typename TTag>
 bool CheckResponse(const TResult& result,
@@ -107,4 +107,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.h b/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.h
index ac03b0f3..01f75c8 100644
--- a/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.h
+++ b/ash/webui/diagnostics_ui/backend/cros_healthd_helpers.h
@@ -5,46 +5,37 @@
 #ifndef ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
 #define ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
 
-namespace cros_healthd {
-namespace mojom {
-class BatteryInfo;
-class CpuInfo;
-class MemoryInfo;
-class NonInteractiveRoutineUpdate;
-class RoutineUpdate;
-class SystemInfo;
-class TelemetryInfo;
-}  // namespace mojom
-}  // namespace cros_healthd
+#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom-forward.h"
+#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom-forward.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 // Extracts BatteryInfo from |info|. Logs and returns a nullptr if
 // BatteryInfo in not present.
-const cros_healthd::mojom::BatteryInfo* GetBatteryInfo(
-    const cros_healthd::mojom::TelemetryInfo& info);
+const chromeos::cros_healthd::mojom::BatteryInfo* GetBatteryInfo(
+    const chromeos::cros_healthd::mojom::TelemetryInfo& info);
 
 // Extracts CpuInfo from |info|. Logs and returns a nullptr if CpuInfo
 // in not present.
-const cros_healthd::mojom::CpuInfo* GetCpuInfo(
-    const cros_healthd::mojom::TelemetryInfo& info);
+const chromeos::cros_healthd::mojom::CpuInfo* GetCpuInfo(
+    const chromeos::cros_healthd::mojom::TelemetryInfo& info);
 
 // Extracts MemoryInfo from |info|. Logs and returns a nullptr if MemoryInfo
 // in not present.
-const cros_healthd::mojom::MemoryInfo* GetMemoryInfo(
-    const cros_healthd::mojom::TelemetryInfo& info);
+const chromeos::cros_healthd::mojom::MemoryInfo* GetMemoryInfo(
+    const chromeos::cros_healthd::mojom::TelemetryInfo& info);
 
 // Extracts SystemInfo from |info|. Logs and returns a nullptr if SystemInfo
 // in not present.
-const cros_healthd::mojom::SystemInfo* GetSystemInfo(
-    const cros_healthd::mojom::TelemetryInfo& info);
+const chromeos::cros_healthd::mojom::SystemInfo* GetSystemInfo(
+    const chromeos::cros_healthd::mojom::TelemetryInfo& info);
 
-const cros_healthd::mojom::NonInteractiveRoutineUpdate*
+const chromeos::cros_healthd::mojom::NonInteractiveRoutineUpdate*
 GetNonInteractiveRoutineUpdate(
-    const cros_healthd::mojom::RoutineUpdate& update);
+    const chromeos::cros_healthd::mojom::RoutineUpdate& update);
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
diff --git a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
index 54045ab6..59551b16 100644
--- a/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
+++ b/ash/webui/diagnostics_ui/backend/diagnostics_manager.cc
@@ -11,7 +11,7 @@
 #include "ash/webui/diagnostics_ui/backend/system_data_provider.h"
 #include "ash/webui/diagnostics_ui/backend/system_routine_controller.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 DiagnosticsManager::DiagnosticsManager(SessionLogHandler* session_log_handler)
@@ -49,4 +49,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/diagnostics_manager.h b/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
index 9f00ea2d..ca7805e 100644
--- a/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
+++ b/ash/webui/diagnostics_ui/backend/diagnostics_manager.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class NetworkHealthProvider;
@@ -39,6 +39,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_DIAGNOSTICS_MANAGER_H_
diff --git a/ash/webui/diagnostics_ui/backend/histogram_util.cc b/ash/webui/diagnostics_ui/backend/histogram_util.cc
index d7683ee1..157e526 100644
--- a/ash/webui/diagnostics_ui/backend/histogram_util.cc
+++ b/ash/webui/diagnostics_ui/backend/histogram_util.cc
@@ -8,7 +8,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/time/time.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace metrics {
 
@@ -37,4 +37,4 @@
 
 }  // namespace metrics
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/histogram_util.h b/ash/webui/diagnostics_ui/backend/histogram_util.h
index 2c6fdc7..30780616 100644
--- a/ash/webui/diagnostics_ui/backend/histogram_util.h
+++ b/ash/webui/diagnostics_ui/backend/histogram_util.h
@@ -14,7 +14,7 @@
 class TimeDelta;
 }  // namespace base
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace metrics {
 
@@ -29,6 +29,6 @@
 
 }  // namespace metrics
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_HISTOGRAM_UTIL_H_
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider.cc b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
index e298242..a23667d4 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider.cc
@@ -16,7 +16,7 @@
 #include "base/strings/string_util.h"
 #include "chromeos/system/statistics_provider.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 namespace {
@@ -225,4 +225,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider.h b/ash/webui/diagnostics_ui/backend/input_data_provider.h
index d59122c..27f5a68d 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider.h
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider.h
@@ -17,7 +17,7 @@
 #include "ui/events/ozone/device/device_manager.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class InputDataProvider : public mojom::InputDataProvider,
@@ -62,6 +62,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_INPUT_DATA_PROVIDER_H_
diff --git a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
index cf14c3a..8e54910f 100644
--- a/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/input_data_provider_unittest.cc
@@ -16,7 +16,7 @@
 #include "ui/events/ozone/device/device_manager.h"
 #include "ui/events/ozone/evdev/event_device_test_util.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class FakeDeviceManager : public ui::DeviceManager {
@@ -357,4 +357,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/log_test_helpers.cc b/ash/webui/diagnostics_ui/backend/log_test_helpers.cc
index 0a0d340..1d7fdf4 100644
--- a/ash/webui/diagnostics_ui/backend/log_test_helpers.cc
+++ b/ash/webui/diagnostics_ui/backend/log_test_helpers.cc
@@ -9,7 +9,7 @@
 
 #include "base/strings/string_split.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 const char kSeparator[] = "-";
@@ -29,4 +29,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/log_test_helpers.h b/ash/webui/diagnostics_ui/backend/log_test_helpers.h
index 867324b..73cbb73 100644
--- a/ash/webui/diagnostics_ui/backend/log_test_helpers.h
+++ b/ash/webui/diagnostics_ui/backend/log_test_helpers.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 extern const char kSeparator[];
@@ -21,6 +21,6 @@
 std::vector<std::string> GetLogLineContents(const std::string& log_line);
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_LOG_TEST_HELPERS_H_
diff --git a/ash/webui/diagnostics_ui/backend/log_test_helpers_unittest.cc b/ash/webui/diagnostics_ui/backend/log_test_helpers_unittest.cc
index 9ea6afaf..dbb3e5f4 100644
--- a/ash/webui/diagnostics_ui/backend/log_test_helpers_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/log_test_helpers_unittest.cc
@@ -9,7 +9,7 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class LogHelpersTest : public testing::Test {
@@ -61,4 +61,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider.cc b/ash/webui/diagnostics_ui/backend/network_health_provider.cc
index d627d00..0fdb1de4 100644
--- a/ash/webui/diagnostics_ui/backend/network_health_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/network_health_provider.cc
@@ -13,11 +13,11 @@
 #include "chromeos/services/network_config/in_process_instance.h"
 #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-namespace network_mojom = chromeos::network_config::mojom;
+namespace network_mojom = ::chromeos::network_config::mojom;
 using network_mojom::ConnectionStateType;
 using network_mojom::NetworkType;
 
@@ -344,4 +344,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider.h b/ash/webui/diagnostics_ui/backend/network_health_provider.h
index ac0da77..d21e5c7 100644
--- a/ash/webui/diagnostics_ui/backend/network_health_provider.h
+++ b/ash/webui/diagnostics_ui/backend/network_health_provider.h
@@ -16,7 +16,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 // Stores network state, managed properties, and an observer for a network.
 struct NetworkProperties {
@@ -30,11 +30,12 @@
 
 using NetworkPropertiesMap = std::map<std::string, NetworkProperties>;
 
-using DeviceMap = std::map<network_config::mojom::NetworkType,
-                           network_config::mojom::DeviceStatePropertiesPtr>;
+using DeviceMap =
+    std::map<chromeos::network_config::mojom::NetworkType,
+             chromeos::network_config::mojom::DeviceStatePropertiesPtr>;
 
 class NetworkHealthProvider
-    : public network_config::mojom::CrosNetworkConfigObserver,
+    : public chromeos::network_config::mojom::CrosNetworkConfigObserver,
       public mojom::NetworkHealthProvider {
  public:
   NetworkHealthProvider();
@@ -58,10 +59,11 @@
   void OnNetworkStateListChanged() override;
   void OnDeviceStateListChanged() override;
   void OnActiveNetworksChanged(
-      std::vector<network_config::mojom::NetworkStatePropertiesPtr>
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
           active_networks) override;
   void OnNetworkStateChanged(
-      network_config::mojom::NetworkStatePropertiesPtr network_state) override;
+      chromeos::network_config::mojom::NetworkStatePropertiesPtr network_state)
+      override;
   void OnVpnProvidersChanged() override;
   void OnNetworkCertificatesChanged() override;
 
@@ -74,16 +76,18 @@
  private:
   // Handler for receiving a list of active networks.
   void OnActiveNetworkStateListReceived(
-      std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks);
+      std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
+          networks);
 
   // Handler for receiving a list of devices.
   void OnDeviceStateListReceived(
-      std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices);
+      std::vector<chromeos::network_config::mojom::DeviceStatePropertiesPtr>
+          devices);
 
   // Handler for receiving managed properties for a network.
   void OnManagedPropertiesReceived(
       const std::string& guid,
-      network_config::mojom::ManagedPropertiesPtr managed_properties);
+      chromeos::network_config::mojom::ManagedPropertiesPtr managed_properties);
 
   // Gets ManagedProperties for a network |guid| from CrosNetworkConfig.
   void GetManagedPropertiesForNetwork(const std::string& guid);
@@ -106,8 +110,8 @@
   NetworkProperties& GetNetworkProperties(const std::string& guid);
 
   // Finds a matching device for a given network type.
-  network_config::mojom::DeviceStateProperties* GetMatchingDevice(
-      network_config::mojom::NetworkType type);
+  chromeos::network_config::mojom::DeviceStateProperties* GetMatchingDevice(
+      chromeos::network_config::mojom::NetworkType type);
 
   // Map of networks that are active and of a supported
   // type (Ethernet, WiFi, Cellular).
@@ -121,11 +125,11 @@
   std::string active_guid_;
 
   // Remote for sending requests to the CrosNetworkConfig service.
-  mojo::Remote<network_config::mojom::CrosNetworkConfig>
+  mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
       remote_cros_network_config_;
 
   // Receiver for the CrosNetworkConfigObserver events.
-  mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver>
+  mojo::Receiver<chromeos::network_config::mojom::CrosNetworkConfigObserver>
       cros_network_config_observer_receiver_{this};
 
   // Remotes for tracking observers that will be notified of changes to the
@@ -136,6 +140,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_NETWORK_HEALTH_PROVIDER_H_
diff --git a/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc
index c787145..7af54d96 100644
--- a/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/network_health_provider_unittest.cc
@@ -31,10 +31,13 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
+// TODO(https://crbug.com/1164001): remove when network_config is moved to ash.
+namespace network_config = ::chromeos::network_config;
+
 void ValidateManagedPropertiesSet(
     const NetworkPropertiesMap& network_properties_map,
     const std::string& guid) {
@@ -405,4 +408,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.cc b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.cc
index 16d3b0f..1c72ea5 100644
--- a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.cc
+++ b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.cc
@@ -8,7 +8,7 @@
 #include "base/time/time.h"
 #include "ui/base/l10n/time_format.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 mojom::BatteryState ConvertBatteryStateFromProto(
@@ -91,4 +91,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.h b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.h
index 563b94f..3b0d61f 100644
--- a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.h
+++ b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions.h
@@ -10,7 +10,7 @@
 #include "ash/webui/diagnostics_ui/mojom/system_data_provider.mojom.h"
 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 mojom::BatteryState ConvertBatteryStateFromProto(
@@ -29,6 +29,6 @@
     const power_manager::PowerSupplyProperties& power_supply_props);
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_POWER_MANAGER_CLIENT_CONVERSIONS_H_
diff --git a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions_unittest.cc b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions_unittest.cc
index 253bb7c..2e7e0c5 100644
--- a/ash/webui/diagnostics_ui/backend/power_manager_client_conversions_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/power_manager_client_conversions_unittest.cc
@@ -9,7 +9,7 @@
 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -101,4 +101,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/routine_log.cc b/ash/webui/diagnostics_ui/backend/routine_log.cc
index 76f1cf2..f2c83f6 100644
--- a/ash/webui/diagnostics_ui/backend/routine_log.cc
+++ b/ash/webui/diagnostics_ui/backend/routine_log.cc
@@ -12,7 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -122,4 +122,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/routine_log.h b/ash/webui/diagnostics_ui/backend/routine_log.h
index 06d3df85..1669219c 100644
--- a/ash/webui/diagnostics_ui/backend/routine_log.h
+++ b/ash/webui/diagnostics_ui/backend/routine_log.h
@@ -10,7 +10,7 @@
 #include "ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom.h"
 #include "base/files/file_path.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 // RoutineLog is used to record the status and outcome of Diagnostics Routines.
@@ -43,6 +43,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_ROUTINE_LOG_H_
diff --git a/ash/webui/diagnostics_ui/backend/routine_log_unittest.cc b/ash/webui/diagnostics_ui/backend/routine_log_unittest.cc
index 7b40191..fd6f1d3c 100644
--- a/ash/webui/diagnostics_ui/backend/routine_log_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/routine_log_unittest.cc
@@ -16,7 +16,7 @@
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -113,4 +113,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/routine_properties.cc b/ash/webui/diagnostics_ui/backend/routine_properties.cc
index 54eb6e4b..052f852 100644
--- a/ash/webui/diagnostics_ui/backend/routine_properties.cc
+++ b/ash/webui/diagnostics_ui/backend/routine_properties.cc
@@ -4,9 +4,9 @@
 
 #include "ash/webui/diagnostics_ui/backend/routine_properties.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
-namespace healthd = cros_healthd::mojom;
+namespace healthd = ::chromeos::cros_healthd::mojom;
 
 const RoutineProperties kRoutineProperties[] = {
     {mojom::RoutineType::kBatteryCharge, "BatteryChargeResult",
@@ -72,4 +72,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
\ No newline at end of file
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/routine_properties.h b/ash/webui/diagnostics_ui/backend/routine_properties.h
index 3c1b6eaf..7097a6a 100644
--- a/ash/webui/diagnostics_ui/backend/routine_properties.h
+++ b/ash/webui/diagnostics_ui/backend/routine_properties.h
@@ -12,7 +12,7 @@
 #include "ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom.h"
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 // Contains information related to a mojom::RoutineType, used in conjunction
@@ -22,7 +22,7 @@
   mojom::RoutineType type;
   const char* metric_name;
   uint32_t duration_seconds;
-  cros_healthd::mojom::DiagnosticRoutineEnum healthd_type;
+  chromeos::cros_healthd::mojom::DiagnosticRoutineEnum healthd_type;
 };
 
 extern const RoutineProperties kRoutineProperties[];
@@ -39,6 +39,6 @@
 const RoutineProperties& GetRoutineProperties(mojom::RoutineType routine_type);
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
-#endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_ROUTINE_PROPERTIES_H_
\ No newline at end of file
+#endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_ROUTINE_PROPERTIES_H_
diff --git a/ash/webui/diagnostics_ui/backend/routine_properties_unittest.cc b/ash/webui/diagnostics_ui/backend/routine_properties_unittest.cc
index bbb220b3..940c5b2 100644
--- a/ash/webui/diagnostics_ui/backend/routine_properties_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/routine_properties_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 TEST(RoutineTypeUtilTtest, RoutinePropertiesListUpToDate) {
@@ -18,4 +18,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.cc b/ash/webui/diagnostics_ui/backend/session_log_handler.cc
index 1e29d34..c03f83ef 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler.cc
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler.cc
@@ -19,7 +19,7 @@
 #include "ui/gfx/native_widget_types.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -147,9 +147,9 @@
 }
 
 void SessionLogHandler::HandleInitialize(const base::ListValue* args) {
-  DCHECK(args && args->empty());
+  DCHECK(args && args->GetList().empty());
   AllowJavascript();
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.h b/ash/webui/diagnostics_ui/backend/session_log_handler.h
index f18f4bd..94e78d2 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler.h
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler.h
@@ -27,7 +27,7 @@
 class HoldingSpaceClient;
 }  // namespace ash
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class TelemetryLog;
@@ -95,6 +95,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_SESSION_LOG_HANDLER_H_
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
index d37b024..f2b058f 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
@@ -31,7 +31,7 @@
 #include "ui/shell_dialogs/select_file_dialog_factory.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -313,4 +313,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/system_data_provider.cc b/ash/webui/diagnostics_ui/backend/system_data_provider.cc
index 94de187..47cb766 100644
--- a/ash/webui/diagnostics_ui/backend/system_data_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/system_data_provider.cc
@@ -21,11 +21,11 @@
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-namespace healthd = cros_healthd::mojom;
+namespace healthd = ::chromeos::cros_healthd::mojom;
 using PhysicalCpuInfos = std::vector<healthd::PhysicalCpuInfoPtr>;
 using PowerSupplyProperties = power_manager::PowerSupplyProperties;
 using ProbeCategories = healthd::ProbeCategoryEnum;
@@ -644,4 +644,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/system_data_provider.h b/ash/webui/diagnostics_ui/backend/system_data_provider.h
index 5d8e52f..a6038a7 100644
--- a/ash/webui/diagnostics_ui/backend/system_data_provider.h
+++ b/ash/webui/diagnostics_ui/backend/system_data_provider.h
@@ -22,7 +22,7 @@
 class RepeatingTimer;
 }  // namespace base
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class TelemetryLog;
@@ -75,11 +75,11 @@
 
   void OnSystemInfoProbeResponse(
       GetSystemInfoCallback callback,
-      cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
   void OnBatteryInfoProbeResponse(
       GetBatteryInfoCallback callback,
-      cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
   void UpdateBatteryChargeStatus();
 
@@ -102,16 +102,20 @@
   void OnBatteryChargeStatusUpdated(
       const absl::optional<power_manager::PowerSupplyProperties>&
           power_supply_properties,
-      cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
-  void OnBatteryHealthUpdated(cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+  void OnBatteryHealthUpdated(
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
-  void OnMemoryUsageUpdated(cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+  void OnMemoryUsageUpdated(
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
-  void OnCpuUsageUpdated(cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+  void OnCpuUsageUpdated(
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
 
-  void ComputeAndPopulateCpuUsage(const cros_healthd::mojom::CpuInfo& cpu_info,
-                                  mojom::CpuUsage& out_cpu_usage);
+  void ComputeAndPopulateCpuUsage(
+      const chromeos::cros_healthd::mojom::CpuInfo& cpu_info,
+      mojom::CpuUsage& out_cpu_usage);
 
   bool IsLoggingEnabled() const;
 
@@ -119,7 +123,8 @@
 
   CpuUsageData previous_cpu_usage_data_;
 
-  mojo::Remote<cros_healthd::mojom::CrosHealthdProbeService> probe_service_;
+  mojo::Remote<chromeos::cros_healthd::mojom::CrosHealthdProbeService>
+      probe_service_;
   mojo::RemoteSet<mojom::BatteryChargeStatusObserver>
       battery_charge_status_observers_;
   mojo::RemoteSet<mojom::BatteryHealthObserver> battery_health_observers_;
@@ -137,6 +142,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_
diff --git a/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
index c19283b..2cb8d102 100644
--- a/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
@@ -29,31 +29,32 @@
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-void SetProbeTelemetryInfoResponse(
-    cros_healthd::mojom::BatteryInfoPtr battery_info,
-    cros_healthd::mojom::CpuInfoPtr cpu_info,
-    cros_healthd::mojom::MemoryInfoPtr memory_info,
-    cros_healthd::mojom::SystemInfoPtr system_info) {
-  auto info = cros_healthd::mojom::TelemetryInfo::New();
+namespace healthd_mojom = ::chromeos::cros_healthd::mojom;
+
+void SetProbeTelemetryInfoResponse(healthd_mojom::BatteryInfoPtr battery_info,
+                                   healthd_mojom::CpuInfoPtr cpu_info,
+                                   healthd_mojom::MemoryInfoPtr memory_info,
+                                   healthd_mojom::SystemInfoPtr system_info) {
+  auto info = healthd_mojom::TelemetryInfo::New();
   if (system_info) {
-    info->system_result = cros_healthd::mojom::SystemResult::NewSystemInfo(
-        std::move(system_info));
+    info->system_result =
+        healthd_mojom::SystemResult::NewSystemInfo(std::move(system_info));
   }
   if (battery_info) {
-    info->battery_result = cros_healthd::mojom::BatteryResult::NewBatteryInfo(
-        std::move(battery_info));
+    info->battery_result =
+        healthd_mojom::BatteryResult::NewBatteryInfo(std::move(battery_info));
   }
   if (memory_info) {
-    info->memory_result = cros_healthd::mojom::MemoryResult::NewMemoryInfo(
-        std::move(memory_info));
+    info->memory_result =
+        healthd_mojom::MemoryResult::NewMemoryInfo(std::move(memory_info));
   }
   if (cpu_info) {
     info->cpu_result =
-        cros_healthd::mojom::CpuResult::NewCpuInfo(std::move(cpu_info));
+        healthd_mojom::CpuResult::NewCpuInfo(std::move(cpu_info));
   }
 
   cros_healthd::FakeCrosHealthdClient::Get()
@@ -71,25 +72,24 @@
                                       const std::string& build_number,
                                       const std::string& patch_number) {
   // System info
-  auto system_info = cros_healthd::mojom::SystemInfo::New();
+  auto system_info = healthd_mojom::SystemInfo::New();
   system_info->product_name = absl::optional<std::string>(board_name);
-  auto os_version_info = cros_healthd::mojom::OsVersion::New(
+  auto os_version_info = healthd_mojom::OsVersion::New(
       milestone_version, build_number, patch_number, "unittest-channel");
   system_info->os_version = std::move(os_version_info);
   system_info->marketing_name = marketing_name;
 
   // Battery info
-  auto battery_info =
-      has_battery ? cros_healthd::mojom::BatteryInfo::New() : nullptr;
+  auto battery_info = has_battery ? healthd_mojom::BatteryInfo::New() : nullptr;
 
   // Memory info
-  auto memory_info = cros_healthd::mojom::MemoryInfo::New();
+  auto memory_info = healthd_mojom::MemoryInfo::New();
   memory_info->total_memory_kib = total_memory_kib;
 
   // CPU info
-  auto cpu_info = cros_healthd::mojom::CpuInfo::New();
-  auto physical_cpu_info = cros_healthd::mojom::PhysicalCpuInfo::New();
-  auto logical_cpu_info = cros_healthd::mojom::LogicalCpuInfo::New();
+  auto cpu_info = healthd_mojom::CpuInfo::New();
+  auto physical_cpu_info = healthd_mojom::PhysicalCpuInfo::New();
+  auto logical_cpu_info = healthd_mojom::LogicalCpuInfo::New();
   logical_cpu_info->max_clock_speed_khz = cpu_max_clock_speed_khz;
   physical_cpu_info->logical_cpus.push_back(std::move(logical_cpu_info));
   physical_cpu_info->model_name = cpu_model;
@@ -102,7 +102,7 @@
 
 // Constructs a BatteryInfoPtr. If |temperature| = 0, it will be omitted from
 // the response to simulate an empty temperature field.
-cros_healthd::mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
+healthd_mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
     int64_t cycle_count,
     double voltage_now,
     const std::string& vendor,
@@ -117,19 +117,19 @@
     const std::string& status,
     const absl::optional<std::string>& manufacture_date,
     uint64_t temperature) {
-  cros_healthd::mojom::NullableUint64Ptr temp_value_ptr(
-      cros_healthd::mojom::NullableUint64::New());
+  healthd_mojom::NullableUint64Ptr temp_value_ptr(
+      healthd_mojom::NullableUint64::New());
   if (temperature != 0) {
     temp_value_ptr->value = temperature;
   }
-  auto battery_info = cros_healthd::mojom::BatteryInfo::New(
+  auto battery_info = healthd_mojom::BatteryInfo::New(
       cycle_count, voltage_now, vendor, serial_number, charge_full_design,
       charge_full, voltage_min_design, model_name, charge_now, current_now,
       technology, status, manufacture_date, std::move(temp_value_ptr));
   return battery_info;
 }
 
-cros_healthd::mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
+healthd_mojom::BatteryInfoPtr CreateCrosHealthdBatteryInfoResponse(
     const std::string& vendor,
     double charge_full_design) {
   return CreateCrosHealthdBatteryInfoResponse(
@@ -149,9 +149,9 @@
       /*temperature=*/0);
 }
 
-cros_healthd::mojom::BatteryInfoPtr
-CreateCrosHealthdBatteryChargeStatusResponse(double charge_now,
-                                             double current_now) {
+healthd_mojom::BatteryInfoPtr CreateCrosHealthdBatteryChargeStatusResponse(
+    double charge_now,
+    double current_now) {
   return CreateCrosHealthdBatteryInfoResponse(
       /*cycle_count=*/0,
       /*voltage_now=*/0,
@@ -169,7 +169,7 @@
       /*temperature=*/0);
 }
 
-cros_healthd::mojom::BatteryInfoPtr CreateCrosHealthdBatteryHealthResponse(
+healthd_mojom::BatteryInfoPtr CreateCrosHealthdBatteryHealthResponse(
     double charge_full_now,
     double charge_full_design,
     int32_t cycle_count) {
@@ -192,7 +192,7 @@
 
 void SetCrosHealthdBatteryInfoResponse(const std::string& vendor,
                                        double charge_full_design) {
-  cros_healthd::mojom::BatteryInfoPtr battery_info =
+  healthd_mojom::BatteryInfoPtr battery_info =
       CreateCrosHealthdBatteryInfoResponse(vendor, charge_full_design);
   SetProbeTelemetryInfoResponse(std::move(battery_info), /*cpu_info=*/nullptr,
                                 /*memory_info=*/nullptr,
@@ -201,7 +201,7 @@
 
 void SetCrosHealthdBatteryChargeStatusResponse(double charge_now,
                                                double current_now) {
-  cros_healthd::mojom::BatteryInfoPtr battery_info =
+  healthd_mojom::BatteryInfoPtr battery_info =
       CreateCrosHealthdBatteryChargeStatusResponse(charge_now, current_now);
   SetProbeTelemetryInfoResponse(std::move(battery_info), /*cpu_info=*/nullptr,
                                 /*memory_info=*/nullptr,
@@ -211,7 +211,7 @@
 void SetCrosHealthdBatteryHealthResponse(double charge_full_now,
                                          double charge_full_design,
                                          int32_t cycle_count) {
-  cros_healthd::mojom::BatteryInfoPtr battery_info =
+  healthd_mojom::BatteryInfoPtr battery_info =
       CreateCrosHealthdBatteryHealthResponse(charge_full_now,
                                              charge_full_design, cycle_count);
   SetProbeTelemetryInfoResponse(std::move(battery_info), /*cpu_info=*/nullptr,
@@ -222,10 +222,9 @@
 void SetCrosHealthdMemoryUsageResponse(uint32_t total_memory_kib,
                                        uint32_t free_memory_kib,
                                        uint32_t available_memory_kib) {
-  cros_healthd::mojom::MemoryInfoPtr memory_info =
-      cros_healthd::mojom::MemoryInfo::New(total_memory_kib, free_memory_kib,
-                                           available_memory_kib,
-                                           /*page_faults_since_last_boot=*/0);
+  healthd_mojom::MemoryInfoPtr memory_info = healthd_mojom::MemoryInfo::New(
+      total_memory_kib, free_memory_kib, available_memory_kib,
+      /*page_faults_since_last_boot=*/0);
   SetProbeTelemetryInfoResponse(/*battery_info=*/nullptr, /*cpu_info=*/nullptr,
                                 /*memory_info=*/std::move(memory_info),
                                 /*system_info=*/nullptr);
@@ -235,13 +234,13 @@
     const std::vector<CpuUsageData>& usage_data,
     const std::vector<int32_t>& cpu_temps,
     const std::vector<uint32_t>& scaled_cpu_clock_speed) {
-  auto cpu_info_ptr = cros_healthd::mojom::CpuInfo::New();
-  auto physical_cpu_info_ptr = cros_healthd::mojom::PhysicalCpuInfo::New();
+  auto cpu_info_ptr = healthd_mojom::CpuInfo::New();
+  auto physical_cpu_info_ptr = healthd_mojom::PhysicalCpuInfo::New();
 
   DCHECK_EQ(usage_data.size(), scaled_cpu_clock_speed.size());
   for (size_t i = 0; i < usage_data.size(); ++i) {
     const auto& data = usage_data[i];
-    auto logical_cpu_info_ptr = cros_healthd::mojom::LogicalCpuInfo::New();
+    auto logical_cpu_info_ptr = healthd_mojom::LogicalCpuInfo::New();
 
     logical_cpu_info_ptr->user_time_user_hz = data.GetUserTime();
     logical_cpu_info_ptr->system_time_user_hz = data.GetSystemTime();
@@ -256,8 +255,7 @@
 
   cpu_info_ptr->physical_cpus.push_back(std::move(physical_cpu_info_ptr));
   for (const auto& cpu_temp : cpu_temps) {
-    auto cpu_temp_channel_ptr =
-        cros_healthd::mojom::CpuTemperatureChannel::New();
+    auto cpu_temp_channel_ptr = healthd_mojom::CpuTemperatureChannel::New();
     cpu_temp_channel_ptr->temperature_celsius = cpu_temp;
     cpu_info_ptr->temperature_channels.emplace_back(
         std::move(cpu_temp_channel_ptr));
@@ -1018,4 +1016,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller.cc b/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
index e07970a75..a5921fd 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller.cc
@@ -26,11 +26,11 @@
 #include "services/device/public/mojom/wake_lock_provider.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-namespace healthd = cros_healthd::mojom;
+namespace healthd = ::chromeos::cros_healthd::mojom;
 
 constexpr uint32_t kBatteryDurationInSeconds = 30;
 constexpr uint32_t kBatteryChargeMinimumPercent = 0;
@@ -440,7 +440,7 @@
 
 void SystemRoutineController::HandlePowerRoutineStatusUpdate(
     mojom ::RoutineType routine_type,
-    cros_healthd::mojom::RoutineUpdatePtr update_ptr) {
+    healthd::RoutineUpdatePtr update_ptr) {
   DCHECK(IsPowerRoutine(routine_type));
 
   const healthd::NonInteractiveRoutineUpdate* update =
@@ -714,4 +714,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller.h b/ash/webui/diagnostics_ui/backend/system_routine_controller.h
index 08c69cad..2ec7874a 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller.h
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller.h
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
+#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom-forward.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -22,22 +23,15 @@
 class OneShotTimer;
 }  // namespace base
 
-namespace cros_healthd {
-namespace mojom {
-class RunRoutineResponsePtr;
-class RoutineUpdatePtr;
-}  // namespace mojom
-}  // namespace cros_healthd
-
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class RoutineLog;
 
 constexpr int32_t kInvalidRoutineId = 0;
 
-using RunRoutineCallback =
-    base::OnceCallback<void(cros_healthd::mojom::RunRoutineResponsePtr)>;
+using RunRoutineCallback = base::OnceCallback<void(
+    chromeos::cros_healthd::mojom::RunRoutineResponsePtr)>;
 
 class SystemRoutineController : public mojom::SystemRoutineController {
  public:
@@ -64,33 +58,34 @@
  private:
   void OnAvailableRoutinesFetched(
       GetSupportedRoutinesCallback callback,
-      const std::vector<cros_healthd::mojom::DiagnosticRoutineEnum>&
+      const std::vector<chromeos::cros_healthd::mojom::DiagnosticRoutineEnum>&
           supported_routines);
 
   void ExecuteRoutine(mojom::RoutineType routine_type);
 
   void OnRoutineStarted(
       mojom::RoutineType routine_type,
-      cros_healthd::mojom::RunRoutineResponsePtr response_ptr);
+      chromeos::cros_healthd::mojom::RunRoutineResponsePtr response_ptr);
 
   void OnPowerRoutineStarted(
       mojom::RoutineType routine_type,
-      cros_healthd::mojom::RunRoutineResponsePtr response_ptr);
+      chromeos::cros_healthd::mojom::RunRoutineResponsePtr response_ptr);
 
   void ContinuePowerRoutine(mojom::RoutineType routine_type);
 
   void OnPowerRoutineContinued(
       mojom::RoutineType routine_type,
-      cros_healthd::mojom::RoutineUpdatePtr update_ptr);
+      chromeos::cros_healthd::mojom::RoutineUpdatePtr update_ptr);
 
   void CheckRoutineStatus(mojom::RoutineType routine_type);
 
-  void OnRoutineStatusUpdated(mojom::RoutineType routine_type,
-                              cros_healthd::mojom::RoutineUpdatePtr update_ptr);
+  void OnRoutineStatusUpdated(
+      mojom::RoutineType routine_type,
+      chromeos::cros_healthd::mojom::RoutineUpdatePtr update_ptr);
 
   void HandlePowerRoutineStatusUpdate(
       mojom ::RoutineType routine_type,
-      cros_healthd::mojom::RoutineUpdatePtr update_ptr);
+      chromeos::cros_healthd::mojom::RoutineUpdatePtr update_ptr);
 
   bool IsRoutineRunning() const;
 
@@ -124,7 +119,7 @@
   void OnInflightRoutineRunnerDisconnected();
 
   void OnRoutineCancelAttempted(
-      cros_healthd::mojom::RoutineUpdatePtr update_ptr);
+      chromeos::cros_healthd::mojom::RoutineUpdatePtr update_ptr);
 
   bool IsLoggingEnabled() const;
 
@@ -149,7 +144,7 @@
   mojo::Remote<mojom::RoutineRunner> inflight_routine_runner_;
   std::unique_ptr<base::OneShotTimer> inflight_routine_timer_;
 
-  mojo::Remote<cros_healthd::mojom::CrosHealthdDiagnosticsService>
+  mojo::Remote<chromeos::cros_healthd::mojom::CrosHealthdDiagnosticsService>
       diagnostics_service_;
 
   mojo::Receiver<mojom::SystemRoutineController> receiver_{this};
@@ -168,6 +163,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_SYSTEM_ROUTINE_CONTROLLER_H_
diff --git a/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc b/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
index 3f5f62d..d89ac85 100644
--- a/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/system_routine_controller_unittest.cc
@@ -25,11 +25,11 @@
 #include "services/device/public/cpp/test/test_wake_lock_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
-namespace healthd = cros_healthd::mojom;
+namespace healthd = ::chromeos::cros_healthd::mojom;
 
 constexpr char kChargePercentKey[] = "chargePercent";
 constexpr char kDischargePercentKey[] = "dischargePercent";
@@ -950,4 +950,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/telemetry_log.cc b/ash/webui/diagnostics_ui/backend/telemetry_log.cc
index 92e6e7e8..701da1ea 100644
--- a/ash/webui/diagnostics_ui/backend/telemetry_log.cc
+++ b/ash/webui/diagnostics_ui/backend/telemetry_log.cc
@@ -12,7 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -171,4 +171,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/telemetry_log.h b/ash/webui/diagnostics_ui/backend/telemetry_log.h
index 2fb029f..2f50c50 100644
--- a/ash/webui/diagnostics_ui/backend/telemetry_log.h
+++ b/ash/webui/diagnostics_ui/backend/telemetry_log.h
@@ -9,7 +9,7 @@
 
 #include "ash/webui/diagnostics_ui/mojom/system_data_provider.mojom.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 
 class TelemetryLog {
@@ -39,6 +39,6 @@
 };
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_BACKEND_TELEMETRY_LOG_H_
diff --git a/ash/webui/diagnostics_ui/backend/telemetry_log_unittest.cc b/ash/webui/diagnostics_ui/backend/telemetry_log_unittest.cc
index 61e88e7..03271714 100644
--- a/ash/webui/diagnostics_ui/backend/telemetry_log_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/telemetry_log_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/strings/string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace diagnostics {
 namespace {
 
@@ -159,4 +159,4 @@
 }
 
 }  // namespace diagnostics
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc
index dca0aa16..295d06231 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -22,20 +22,38 @@
 #include "ash/webui/diagnostics_ui/url_constants.h"
 #include "base/containers/span.h"
 #include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
 #include "chromeos/login/login_state/login_state.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "services/network/public/mojom/content_security_policy.mojom.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/resources/grit/webui_generated_resources.h"
 #include "ui/resources/grit/webui_resources.h"
 
-namespace chromeos {
+namespace ash {
 
 namespace {
 
+std::u16string GetSettingsLinkLabel() {
+  int string_id = IDS_DIAGNOSTICS_SETTINGS_LINK_TEXT;
+  std::vector<std::u16string> replacements;
+  const char* kOsSettingsUrl = "chrome://os-settings/";
+  replacements.push_back(base::UTF8ToUTF16(kOsSettingsUrl));
+
+  return l10n_util::GetStringFUTF16(string_id, replacements, nullptr);
+}
+
+std::unique_ptr<base::DictionaryValue> GetDataSourceUpdate() {
+  auto update = std::make_unique<base::DictionaryValue>();
+  update->SetKey("settingsLinkText", base::Value(GetSettingsLinkLabel()));
+  return update;
+}
+
 void AddDiagnosticsStrings(content::WebUIDataSource* html_source) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
       {"batteryCalculatingText", IDS_DIAGNOSTICS_BATTERY_CALCULATING_TEXT},
@@ -136,6 +154,7 @@
       {"versionInfo", IDS_DIAGNOSTICS_VERSION_INFO_TEXT},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
+  html_source->AddLocalizedStrings(*GetDataSourceUpdate());
   html_source->UseStringsJs();
 }
 // TODO(jimmyxgong): Replace with webui::SetUpWebUIDataSource() once it no
@@ -160,9 +179,9 @@
 
 DiagnosticsDialogUI::DiagnosticsDialogUI(
     content::WebUI* web_ui,
-    const chromeos::diagnostics::SessionLogHandler::SelectFilePolicyCreator&
+    const diagnostics::SessionLogHandler::SelectFilePolicyCreator&
         select_file_policy_creator,
-    ash::HoldingSpaceClient* holding_space_client)
+    HoldingSpaceClient* holding_space_client)
     : ui::MojoWebDialogUI(web_ui),
       session_log_handler_(std::make_unique<diagnostics::SessionLogHandler>(
           select_file_policy_creator,
@@ -240,4 +259,4 @@
 
 WEB_UI_CONTROLLER_TYPE_IMPL(DiagnosticsDialogUI)
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.h b/ash/webui/diagnostics_ui/diagnostics_ui.h
index ac72739c..303c8fc 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.h
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.h
@@ -19,13 +19,8 @@
 
 class HoldingSpaceClient;
 
-}  // namespace ash
-
-namespace chromeos {
 namespace diagnostics {
-
 class DiagnosticsManager;
-
 }  // namespace diagnostics
 
 // The WebDialogUI for chrome://diagnostics.
@@ -33,9 +28,9 @@
  public:
   explicit DiagnosticsDialogUI(
       content::WebUI* web_ui,
-      const chromeos::diagnostics::SessionLogHandler::SelectFilePolicyCreator&
+      const diagnostics::SessionLogHandler::SelectFilePolicyCreator&
           select_file_policy_creator,
-      ash::HoldingSpaceClient* holding_space_client);
+      HoldingSpaceClient* holding_space_client);
   ~DiagnosticsDialogUI() override;
 
   DiagnosticsDialogUI(const DiagnosticsDialogUI&) = delete;
diff --git a/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom b/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
index 9246473..4a8b5f5 100644
--- a/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
+++ b/ash/webui/diagnostics_ui/mojom/input_data_provider.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module chromeos.diagnostics.mojom;
+module ash.diagnostics.mojom;
 
 enum ConnectionType {
   kInternal,  // Includes internal USB devices.
diff --git a/ash/webui/diagnostics_ui/mojom/network_health_provider.mojom b/ash/webui/diagnostics_ui/mojom/network_health_provider.mojom
index b4f0f00..d8e0cc27 100644
--- a/ash/webui/diagnostics_ui/mojom/network_health_provider.mojom
+++ b/ash/webui/diagnostics_ui/mojom/network_health_provider.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module chromeos.diagnostics.mojom;
+module ash.diagnostics.mojom;
 
 import "mojo/public/mojom/base/string16.mojom";
 
diff --git a/ash/webui/diagnostics_ui/mojom/system_data_provider.mojom b/ash/webui/diagnostics_ui/mojom/system_data_provider.mojom
index 74ea1436..ca3635c 100644
--- a/ash/webui/diagnostics_ui/mojom/system_data_provider.mojom
+++ b/ash/webui/diagnostics_ui/mojom/system_data_provider.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module chromeos.diagnostics.mojom;
+module ash.diagnostics.mojom;
 
 import "mojo/public/mojom/base/string16.mojom";
 
diff --git a/ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom b/ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom
index abf92d64..0b0c521 100644
--- a/ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom
+++ b/ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-module chromeos.diagnostics.mojom;
+module ash.diagnostics.mojom;
 
 enum RoutineType {
   kBatteryCharge,
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html
index 4ca96529..0dfab0f0 100644
--- a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html
+++ b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html
@@ -34,6 +34,7 @@
       --diagnostics-test-status-text-color: var(--google-grey-700);
       --diagnostics-caution-banner-text-color: var(--google-grey-900);
       --diagnostics-link-text-color: var(--google-blue-300);
+      --diagnostics-settings-link-text-color: var(--google-grey-700);
 
       --diagnostics-default-font: {
           font-family: var(--diagnostics-google-sans-font-family);
@@ -126,21 +127,25 @@
         font-family: var(--diagnostics-roboto-font-family);
         font-size: var(--diagnostics-caution-banner-font-size);
         font-weight: var(--diagnostics-regular-font-weight);
-      }
-
+      };
       --diagnostics-no-ethernet-font: {
           color: var(--diagnostics-header-text-color);
           font-family: var(--diagnostics-roboto-font-family);
           font-size: var(--diagnostics-default-font-size);
           font-weight: var(--diagnostics-medium-font-weight);
       };
-
       --diagnostics-connecting-link-font: {
           color: var(--diagnostics-link-text-color);
           font-family: var(--diagnostics-roboto-font-family);
           font-size: var(--diagnostics-default-font-size);
           font-weight: var(--diagnostics-regular-font-weight);
       };
+      --diagnostics-settings-link-font: {
+        color: var(--diagnostics-settings-link-text-color);
+        font-family: var(--diagnostics-roboto-font-family);
+        font-size: var(--diagnostics-default-font-size);
+        font-weight: var(--diagnostics-regular-font-weight);
+      };
     }
   </style>
 </template>
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_types.js b/ash/webui/diagnostics_ui/resources/diagnostics_types.js
index 3a68f41..4dbdd8d 100644
--- a/ash/webui/diagnostics_ui/resources/diagnostics_types.js
+++ b/ash/webui/diagnostics_ui/resources/diagnostics_types.js
@@ -17,325 +17,325 @@
 
 /**
  * Type alias for the SystemDataProvider.
- * @typedef {chromeos.diagnostics.mojom.SystemDataProvider}
+ * @typedef {ash.diagnostics.mojom.SystemDataProvider}
  */
-export let SystemDataProvider = chromeos.diagnostics.mojom.SystemDataProvider;
+export let SystemDataProvider = ash.diagnostics.mojom.SystemDataProvider;
 
 /**
  * Type alias for the SystemDataProviderInterface.
- * @typedef {chromeos.diagnostics.mojom.SystemDataProviderInterface}
+ * @typedef {ash.diagnostics.mojom.SystemDataProviderInterface}
  */
 export let SystemDataProviderInterface =
-    chromeos.diagnostics.mojom.SystemDataProviderInterface;
+    ash.diagnostics.mojom.SystemDataProviderInterface;
 
 /**
  * Type alias for DeviceCapabilities.
- * @typedef {chromeos.diagnostics.mojom.DeviceCapabilities}
+ * @typedef {ash.diagnostics.mojom.DeviceCapabilities}
  */
-export let DeviceCapabilities = chromeos.diagnostics.mojom.DeviceCapabilities;
+export let DeviceCapabilities = ash.diagnostics.mojom.DeviceCapabilities;
 
 /**
  * Type alias for VersionInfo.
- * @typedef {chromeos.diagnostics.mojom.VersionInfo}
+ * @typedef {ash.diagnostics.mojom.VersionInfo}
  */
-export let VersionInfo = chromeos.diagnostics.mojom.VersionInfo;
+export let VersionInfo = ash.diagnostics.mojom.VersionInfo;
 
 /**
  * Type alias for SystemInfo.
- * @typedef {chromeos.diagnostics.mojom.SystemInfo}
+ * @typedef {ash.diagnostics.mojom.SystemInfo}
  */
-export let SystemInfo = chromeos.diagnostics.mojom.SystemInfo;
+export let SystemInfo = ash.diagnostics.mojom.SystemInfo;
 
 /**
  * Type alias for ExternalPowerSource.
- * @typedef {chromeos.diagnostics.mojom.ExternalPowerSource}
+ * @typedef {ash.diagnostics.mojom.ExternalPowerSource}
  */
-export let ExternalPowerSource = chromeos.diagnostics.mojom.ExternalPowerSource;
+export let ExternalPowerSource = ash.diagnostics.mojom.ExternalPowerSource;
 
 /**
  * Type alias for BatteryState.
- * @typedef {chromeos.diagnostics.mojom.BatteryState}
+ * @typedef {ash.diagnostics.mojom.BatteryState}
  */
-export let BatteryState = chromeos.diagnostics.mojom.BatteryState;
+export let BatteryState = ash.diagnostics.mojom.BatteryState;
 
 /**
  * Type alias for BatteryInfo.
- * @typedef {chromeos.diagnostics.mojom.BatteryInfo}
+ * @typedef {ash.diagnostics.mojom.BatteryInfo}
  */
-export let BatteryInfo = chromeos.diagnostics.mojom.BatteryInfo;
+export let BatteryInfo = ash.diagnostics.mojom.BatteryInfo;
 
 /**
  * Type alias for BatteryChargeStatusObserver.
- * @typedef {chromeos.diagnostics.mojom.BatteryChargeStatusObserver}
+ * @typedef {ash.diagnostics.mojom.BatteryChargeStatusObserver}
  */
 export let BatteryChargeStatusObserver =
-    chromeos.diagnostics.mojom.BatteryChargeStatusObserver;
+    ash.diagnostics.mojom.BatteryChargeStatusObserver;
 
 /**
  * Type alias for BatteryChargeStatusObserverRemote.
- * @typedef {chromeos.diagnostics.mojom.BatteryChargeStatusObserverRemote}
+ * @typedef {ash.diagnostics.mojom.BatteryChargeStatusObserverRemote}
  */
 export let BatteryChargeStatusObserverRemote =
-    chromeos.diagnostics.mojom.BatteryChargeStatusObserverRemote;
+    ash.diagnostics.mojom.BatteryChargeStatusObserverRemote;
 
 /**
  * Type alias for BatteryChargeStatusObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.BatteryChargeStatusObserverInterface}
+ * @typedef {ash.diagnostics.mojom.BatteryChargeStatusObserverInterface}
  */
 export let BatteryChargeStatusObserverInterface =
-    chromeos.diagnostics.mojom.BatteryChargeStatusObserverInterface;
+    ash.diagnostics.mojom.BatteryChargeStatusObserverInterface;
 
 /**
  * Type alias for BatteryChargeStatusObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.BatteryChargeStatusObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.BatteryChargeStatusObserverReceiver}
  */
 export let BatteryChargeStatusObserverReceiver =
-    chromeos.diagnostics.mojom.BatteryChargeStatusObserverReceiver;
+    ash.diagnostics.mojom.BatteryChargeStatusObserverReceiver;
 
 /**
  * Type alias for BatteryChargeStatus.
- * @typedef {chromeos.diagnostics.mojom.BatteryChargeStatus}
+ * @typedef {ash.diagnostics.mojom.BatteryChargeStatus}
  */
-export let BatteryChargeStatus = chromeos.diagnostics.mojom.BatteryChargeStatus;
+export let BatteryChargeStatus = ash.diagnostics.mojom.BatteryChargeStatus;
 
 /**
  * Type alias for BatteryHealthObserver.
- * @typedef {chromeos.diagnostics.mojom.BatteryHealthObserver}
+ * @typedef {ash.diagnostics.mojom.BatteryHealthObserver}
  */
 export let BatteryHealthObserver =
-    chromeos.diagnostics.mojom.BatteryHealthObserver;
+    ash.diagnostics.mojom.BatteryHealthObserver;
 
 /**
  * Type alias for BatteryHealthObserver.
- * @typedef {chromeos.diagnostics.mojom.BatteryHealthObserverRemote}
+ * @typedef {ash.diagnostics.mojom.BatteryHealthObserverRemote}
  */
 export let BatteryHealthObserverRemote =
-    chromeos.diagnostics.mojom.BatteryHealthObserverRemote;
+    ash.diagnostics.mojom.BatteryHealthObserverRemote;
 
 /**
  * Type alias for BatteryHealthObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.BatteryHealthObserverInterface}
+ * @typedef {ash.diagnostics.mojom.BatteryHealthObserverInterface}
  */
 export let BatteryHealthObserverInterface =
-    chromeos.diagnostics.mojom.BatteryHealthObserverInterface;
+    ash.diagnostics.mojom.BatteryHealthObserverInterface;
 
 /**
  * Type alias for BatteryHealthObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.BatteryHealthObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.BatteryHealthObserverReceiver}
  */
 export let BatteryHealthObserverReceiver =
-    chromeos.diagnostics.mojom.BatteryHealthObserverReceiver;
+    ash.diagnostics.mojom.BatteryHealthObserverReceiver;
 
 /**
  * Type alias for BatteryHealth.
- * @typedef {chromeos.diagnostics.mojom.BatteryHealth}
+ * @typedef {ash.diagnostics.mojom.BatteryHealth}
  */
-export let BatteryHealth = chromeos.diagnostics.mojom.BatteryHealth;
+export let BatteryHealth = ash.diagnostics.mojom.BatteryHealth;
 
 /**
  * Type alias for MemoryUsageObserver.
- * @typedef {chromeos.diagnostics.mojom.MemoryUsageObserver}
+ * @typedef {ash.diagnostics.mojom.MemoryUsageObserver}
  */
-export let MemoryUsageObserver = chromeos.diagnostics.mojom.MemoryUsageObserver;
+export let MemoryUsageObserver = ash.diagnostics.mojom.MemoryUsageObserver;
 
 /**
  * Type alias for MemoryUsageObserverRemote.
- * @typedef {chromeos.diagnostics.mojom.MemoryUsageObserverRemote}
+ * @typedef {ash.diagnostics.mojom.MemoryUsageObserverRemote}
  */
 export let MemoryUsageObserverRemote =
-    chromeos.diagnostics.mojom.MemoryUsageObserverRemote;
+    ash.diagnostics.mojom.MemoryUsageObserverRemote;
 
 /**
  * Type alias for MemoryUsageObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.MemoryUsageObserverInterface}
+ * @typedef {ash.diagnostics.mojom.MemoryUsageObserverInterface}
  */
 export let MemoryUsageObserverInterface =
-    chromeos.diagnostics.mojom.MemoryUsageObserverInterface;
+    ash.diagnostics.mojom.MemoryUsageObserverInterface;
 
 /**
  * Type alias for MemoryUsageObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.MemoryUsageObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.MemoryUsageObserverReceiver}
  */
 export let MemoryUsageObserverReceiver =
-    chromeos.diagnostics.mojom.MemoryUsageObserverReceiver;
+    ash.diagnostics.mojom.MemoryUsageObserverReceiver;
 
 /**
  * Type alias for MemoryUsage.
- * @typedef {chromeos.diagnostics.mojom.MemoryUsage}
+ * @typedef {ash.diagnostics.mojom.MemoryUsage}
  */
-export let MemoryUsage = chromeos.diagnostics.mojom.MemoryUsage;
+export let MemoryUsage = ash.diagnostics.mojom.MemoryUsage;
 
 /**
  * Type alias for CpuUsageObserver.
- * @typedef {chromeos.diagnostics.mojom.CpuUsageObserver}
+ * @typedef {ash.diagnostics.mojom.CpuUsageObserver}
  */
-export let CpuUsageObserver = chromeos.diagnostics.mojom.CpuUsageObserver;
+export let CpuUsageObserver = ash.diagnostics.mojom.CpuUsageObserver;
 
 /**
  * Type alias for CpuUsageObserverRemote.
- * @typedef {chromeos.diagnostics.mojom.CpuUsageObserverRemote}
+ * @typedef {ash.diagnostics.mojom.CpuUsageObserverRemote}
  */
 export let CpuUsageObserverRemote =
-    chromeos.diagnostics.mojom.CpuUsageObserverRemote;
+    ash.diagnostics.mojom.CpuUsageObserverRemote;
 
 /**
  * Type alias for CpuUsageObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.CpuUsageObserverInterface}
+ * @typedef {ash.diagnostics.mojom.CpuUsageObserverInterface}
  */
 export let CpuUsageObserverInterface =
-    chromeos.diagnostics.mojom.CpuUsageObserverInterface;
+    ash.diagnostics.mojom.CpuUsageObserverInterface;
 
 /**
  * Type alias for CpuUsageObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.CpuUsageObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.CpuUsageObserverReceiver}
  */
 export let CpuUsageObserverReceiver =
-    chromeos.diagnostics.mojom.CpuUsageObserverReceiver;
+    ash.diagnostics.mojom.CpuUsageObserverReceiver;
 
 /**
  * Type alias for CpuUsage.
- * @typedef {chromeos.diagnostics.mojom.CpuUsage}
+ * @typedef {ash.diagnostics.mojom.CpuUsage}
  */
-export let CpuUsage = chromeos.diagnostics.mojom.CpuUsage;
+export let CpuUsage = ash.diagnostics.mojom.CpuUsage;
 
 /**
  * Enumeration of routines.
- * @typedef {chromeos.diagnostics.mojom.RoutineType}
+ * @typedef {ash.diagnostics.mojom.RoutineType}
  */
-export let RoutineType = chromeos.diagnostics.mojom.RoutineType;
+export let RoutineType = ash.diagnostics.mojom.RoutineType;
 
 /**
  * Type alias for StandardRoutineResult.
- * @typedef {chromeos.diagnostics.mojom.StandardRoutineResult}
+ * @typedef {ash.diagnostics.mojom.StandardRoutineResult}
  */
 export let StandardRoutineResult =
-    chromeos.diagnostics.mojom.StandardRoutineResult;
+    ash.diagnostics.mojom.StandardRoutineResult;
 
 /**
  * Type alias for PowerRoutineResult.
- * @typedef {chromeos.diagnostics.mojom.PowerRoutineResult}
+ * @typedef {ash.diagnostics.mojom.PowerRoutineResult}
  */
-export let PowerRoutineResult = chromeos.diagnostics.mojom.PowerRoutineResult;
+export let PowerRoutineResult = ash.diagnostics.mojom.PowerRoutineResult;
 
 /**
  * Type alias for RoutineResult.
- * @typedef {chromeos.diagnostics.mojom.RoutineResult}
+ * @typedef {ash.diagnostics.mojom.RoutineResult}
  */
-export let RoutineResult = chromeos.diagnostics.mojom.RoutineResult;
+export let RoutineResult = ash.diagnostics.mojom.RoutineResult;
 
 /**
  * Type alias for RoutineResultInfo.
- * @typedef {chromeos.diagnostics.mojom.RoutineResultInfo}
+ * @typedef {ash.diagnostics.mojom.RoutineResultInfo}
  */
-export let RoutineResultInfo = chromeos.diagnostics.mojom.RoutineResultInfo;
+export let RoutineResultInfo = ash.diagnostics.mojom.RoutineResultInfo;
 
 /**
  * Type alias for RoutineRunnerInterface.
- * @typedef {chromeos.diagnostics.mojom.RoutineRunnerInterface}
+ * @typedef {ash.diagnostics.mojom.RoutineRunnerInterface}
  */
 export let RoutineRunnerInterface =
-    chromeos.diagnostics.mojom.RoutineRunnerInterface;
+    ash.diagnostics.mojom.RoutineRunnerInterface;
 
 /**
  * Type alias for RoutineRunnerRemote.
- * @typedef {chromeos.diagnostics.mojom.RoutineRunnerRemote}
+ * @typedef {ash.diagnostics.mojom.RoutineRunnerRemote}
  */
-export let RoutineRunnerRemote = chromeos.diagnostics.mojom.RoutineRunnerRemote;
+export let RoutineRunnerRemote = ash.diagnostics.mojom.RoutineRunnerRemote;
 
 /**
  * Type alias for RoutineRunnerReceiver.
- * @typedef {chromeos.diagnostics.mojom.RoutineRunnerReceiver}
+ * @typedef {ash.diagnostics.mojom.RoutineRunnerReceiver}
  */
 export let RoutineRunnerReceiver =
-    chromeos.diagnostics.mojom.RoutineRunnerReceiver;
+    ash.diagnostics.mojom.RoutineRunnerReceiver;
 
 /**
  * Type alias for SystemRoutineController.
- * @typedef {chromeos.diagnostics.mojom.SystemRoutineController}
+ * @typedef {ash.diagnostics.mojom.SystemRoutineController}
  */
 export let SystemRoutineController =
-    chromeos.diagnostics.mojom.SystemRoutineController;
+    ash.diagnostics.mojom.SystemRoutineController;
 
 /**
  * Type alias for SystemRoutineControllerInterface.
- * @typedef {chromeos.diagnostics.mojom.SystemRoutineControllerInterface}
+ * @typedef {ash.diagnostics.mojom.SystemRoutineControllerInterface}
  */
 export let SystemRoutineControllerInterface =
-    chromeos.diagnostics.mojom.SystemRoutineControllerInterface;
+    ash.diagnostics.mojom.SystemRoutineControllerInterface;
 
 /**
  * Type alias for NetworkListObserver.
- * @typedef {chromeos.diagnostics.mojom.NetworkListObserverRemote}
+ * @typedef {ash.diagnostics.mojom.NetworkListObserverRemote}
  */
 export let NetworkListObserverRemote =
-    chromeos.diagnostics.mojom.NetworkListObserverRemote;
+    ash.diagnostics.mojom.NetworkListObserverRemote;
 
 /**
  * Type alias for NetworkStateObserver.
- * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverRemote}
+ * @typedef {ash.diagnostics.mojom.NetworkStateObserverRemote}
  */
 export let NetworkStateObserverRemote =
-    chromeos.diagnostics.mojom.NetworkStateObserverRemote;
+    ash.diagnostics.mojom.NetworkStateObserverRemote;
 
 /**
  * Type alias for Network.
- * @typedef {chromeos.diagnostics.mojom.Network}
+ * @typedef {ash.diagnostics.mojom.Network}
  */
-export let Network = chromeos.diagnostics.mojom.Network;
+export let Network = ash.diagnostics.mojom.Network;
 
 /**
  * Type alias for NetworkHealthProvider.
- * @typedef {chromeos.diagnostics.mojom.NetworkHealthProvider}
+ * @typedef {ash.diagnostics.mojom.NetworkHealthProvider}
  */
 export let NetworkHealthProvider =
-    chromeos.diagnostics.mojom.NetworkHealthProvider;
+    ash.diagnostics.mojom.NetworkHealthProvider;
 
 /**
  * Type alias for NetworkHealthProviderInterface.
- * @typedef {chromeos.diagnostics.mojom.NetworkHealthProviderInterface}
+ * @typedef {ash.diagnostics.mojom.NetworkHealthProviderInterface}
  */
 export let NetworkHealthProviderInterface =
-    chromeos.diagnostics.mojom.NetworkHealthProviderInterface;
+    ash.diagnostics.mojom.NetworkHealthProviderInterface;
 
 /**
  * Type alias for NetworkState.
- * @typedef {chromeos.diagnostics.mojom.NetworkState}
+ * @typedef {ash.diagnostics.mojom.NetworkState}
  */
-export let NetworkState = chromeos.diagnostics.mojom.NetworkState;
+export let NetworkState = ash.diagnostics.mojom.NetworkState;
 
 /**
  * Type alias for NetworkType
- * @typedef {chromeos.diagnostics.mojom.NetworkType}
+ * @typedef {ash.diagnostics.mojom.NetworkType}
  */
-export let NetworkType = chromeos.diagnostics.mojom.NetworkType;
+export let NetworkType = ash.diagnostics.mojom.NetworkType;
 
 /**
  * Type alias for NetworkListObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.NetworkListObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.NetworkListObserverReceiver}
  */
 export let NetworkListObserverReceiver =
-    chromeos.diagnostics.mojom.NetworkListObserverReceiver;
+    ash.diagnostics.mojom.NetworkListObserverReceiver;
 
 /**
  * Type alias for NetworkListObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.NetworkListObserverInterface}
+ * @typedef {ash.diagnostics.mojom.NetworkListObserverInterface}
  */
 export let NetworkListObserverInterface =
-    chromeos.diagnostics.mojom.NetworkListObserverInterface;
+    ash.diagnostics.mojom.NetworkListObserverInterface;
 
 /**
  * Type alias for NetworkStateObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverInterface}
+ * @typedef {ash.diagnostics.mojom.NetworkStateObserverInterface}
  */
 export let NetworkStateObserverInterface =
-    chromeos.diagnostics.mojom.NetworkStateObserverInterface;
+    ash.diagnostics.mojom.NetworkStateObserverInterface;
 
 /**
  * Type alias for NetworkStateObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.NetworkStateObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.NetworkStateObserverReceiver}
  */
 export let NetworkStateObserverReceiver =
-    chromeos.diagnostics.mojom.NetworkStateObserverReceiver;
+    ash.diagnostics.mojom.NetworkStateObserverReceiver;
 
 /**
  * @typedef {{
@@ -347,70 +347,66 @@
 
 /**
  * Type alias for ConnectionType.
- * @typedef {chromeos.diagnostics.mojom.ConnectionType}
+ * @typedef {ash.diagnostics.mojom.ConnectionType}
  */
-export let ConnectionType =
-    chromeos.diagnostics.mojom.ConnectionType;
+export let ConnectionType = ash.diagnostics.mojom.ConnectionType;
 
 /**
  * Type alias for PhysicalLayout.
- * @typedef {chromeos.diagnostics.mojom.PhysicalLayout}
+ * @typedef {ash.diagnostics.mojom.PhysicalLayout}
  */
-export let PhysicalLayout = chromeos.diagnostics.mojom.PhysicalLayout;
+export let PhysicalLayout = ash.diagnostics.mojom.PhysicalLayout;
 
 /**
  * Type alias for MechanicalLayout.
- * @typedef {chromeos.diagnostics.mojom.MechanicalLayout}
+ * @typedef {ash.diagnostics.mojom.MechanicalLayout}
  */
-export let MechanicalLayout = chromeos.diagnostics.mojom.MechanicalLayout;
+export let MechanicalLayout = ash.diagnostics.mojom.MechanicalLayout;
 
 /**
  * Type alias for KeyboardInfo.
- * @typedef {chromeos.diagnostics.mojom.KeyboardInfo}
+ * @typedef {ash.diagnostics.mojom.KeyboardInfo}
  */
-export let KeyboardInfo =
-    chromeos.diagnostics.mojom.KeyboardInfo;
+export let KeyboardInfo = ash.diagnostics.mojom.KeyboardInfo;
 
 /**
  * Type alias for TouchDeviceType.
- * @typedef {chromeos.diagnostics.mojom.TouchDeviceType}
+ * @typedef {ash.diagnostics.mojom.TouchDeviceType}
  */
-export let TouchDeviceType =
-    chromeos.diagnostics.mojom.TouchDeviceType;
+export let TouchDeviceType = ash.diagnostics.mojom.TouchDeviceType;
 
 /**
  * Type alias for TouchDeviceInfo.
- * @typedef {chromeos.diagnostics.mojom.TouchDeviceInfo}
+ * @typedef {ash.diagnostics.mojom.TouchDeviceInfo}
  */
-export let TouchDeviceInfo =
-    chromeos.diagnostics.mojom.TouchDeviceInfo;
+export let TouchDeviceInfo = ash.diagnostics.mojom.TouchDeviceInfo;
 
 /**
  * Type alias for ConnectedDevicesObserver.
- * @typedef {chromeos.diagnostics.mojom.ConnectedDevicesObserver}
+ * @typedef {ash.diagnostics.mojom.ConnectedDevicesObserver}
  */
-export let ConnectedDevicesObserver = chromeos.diagnostics.mojom.CpuUsageObserver;
+export let ConnectedDevicesObserver = ash.diagnostics.mojom.CpuUsageObserver;
 
 /**
  * Type alias for ConnectedDevicesObserverRemote.
- * @typedef {chromeos.diagnostics.mojom.ConnectedDevicesObserverRemote}
+ * @typedef {ash.diagnostics.mojom.ConnectedDevicesObserverRemote}
  */
 export let ConnectedDevicesObserverRemote =
-    chromeos.diagnostics.mojom.ConnectedDevicesObserverRemote;
+    ash.diagnostics.mojom.ConnectedDevicesObserverRemote;
 
 /**
  * Type alias for ConnectedDevicesObserverInterface.
- * @typedef {chromeos.diagnostics.mojom.ConnectedDevicesObserverInterface}
+ * @typedef {ash.diagnostics.mojom.ConnectedDevicesObserverInterface}
  */
 export let ConnectedDevicesObserverInterface =
-    chromeos.diagnostics.mojom.ConnectedDevicesObserverInterface;
+    ash.diagnostics.mojom.ConnectedDevicesObserverInterface;
 
 /**
  * Type alias for ConnectedDevicesObserverReceiver.
- * @typedef {chromeos.diagnostics.mojom.ConnectedDevicesObserverReceiver}
+ * @typedef {ash.diagnostics.mojom.ConnectedDevicesObserverReceiver}
  */
 export let ConnectedDevicesObserverReceiver =
-    chromeos.diagnostics.mojom.ConnectedDevicesObserverReceiver;
+    ash.diagnostics.mojom.ConnectedDevicesObserverReceiver;
 
 
 /**
@@ -422,7 +418,7 @@
 
 /**
  * Type alias for InputDataProviderInterface.
- * @typedef {chromeos.diagnostics.mojom.InputDataProviderInterface}
+ * @typedef {ash.diagnostics.mojom.InputDataProviderInterface}
  */
 export let InputDataProviderInterface =
-    chromeos.diagnostics.mojom.InputDataProviderInterface;
+    ash.diagnostics.mojom.InputDataProviderInterface;
diff --git a/ash/webui/diagnostics_ui/resources/mojo_interface_provider.js b/ash/webui/diagnostics_ui/resources/mojo_interface_provider.js
index f040148d..f5b1d7e 100644
--- a/ash/webui/diagnostics_ui/resources/mojo_interface_provider.js
+++ b/ash/webui/diagnostics_ui/resources/mojo_interface_provider.js
@@ -162,8 +162,7 @@
  */
 export function getInputDataProvider() {
   if (!inputDataProvider) {
-    inputDataProvider =
-        chromeos.diagnostics.mojom.InputDataProvider.getRemote();
+    inputDataProvider = ash.diagnostics.mojom.InputDataProvider.getRemote();
   }
 
   assert(!!inputDataProvider);
diff --git a/ash/webui/diagnostics_ui/resources/network_list.html b/ash/webui/diagnostics_ui/resources/network_list.html
index 715fb2f..3cc9db3 100644
--- a/ash/webui/diagnostics_ui/resources/network_list.html
+++ b/ash/webui/diagnostics_ui/resources/network_list.html
@@ -1,4 +1,25 @@
 <style include="diagnostics-shared diagnostics-fonts">
+  a[href] {
+    color: var(--cr-link-color);
+    text-decoration: none;
+  }
+
+  #settingsIcon {
+    --iron-icon-height: 20px;
+    --iron-icon-width: 20px;
+    fill: var(--google-grey-700);
+    margin-right: 5px;
+    top: 1px;
+  }
+
+  #settingsLink {
+    @apply --diagnostics-settings-link-font;
+  }
+
+  .settings-link-container {
+    align-items: center;
+    display: flex;
+  }
 </style>
 
 <div id="networkListContainer" class="diagnostics-cards-container">
@@ -16,4 +37,9 @@
       </network-card>
     </template>
   </dom-repeat>
+  <div class="settings-link-container">
+    <iron-icon icon="cr:settings_icon" id="settingsIcon"></iron-icon>
+    <div id="settingsLink" inner-h-t-m-l="[[getSettingsString_()]]">
+    </div>
+  </div>
 </div>
diff --git a/ash/webui/diagnostics_ui/resources/network_list.js b/ash/webui/diagnostics_ui/resources/network_list.js
index 3b66dcd..eb91ada 100644
--- a/ash/webui/diagnostics_ui/resources/network_list.js
+++ b/ash/webui/diagnostics_ui/resources/network_list.js
@@ -7,6 +7,7 @@
 import './diagnostics_shared_css.js';
 import './network_card.js';
 
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {NetworkHealthProviderInterface, NetworkListObserverInterface, NetworkListObserverReceiver} from './diagnostics_types.js'
@@ -22,6 +23,8 @@
 
   _template: html`{__html_template__}`,
 
+  behaviors: [I18nBehavior],
+
   /**
    * @private {?NetworkHealthProviderInterface}
    */
@@ -106,4 +109,9 @@
   onNavigationPageChanged({isActive}) {
     this.isActive = isActive;
   },
+
+  /** @protected */
+  getSettingsString_() {
+    return this.i18nAdvanced('settingsLinkText');
+  },
 });
diff --git a/ash/webui/diagnostics_ui/url_constants.cc b/ash/webui/diagnostics_ui/url_constants.cc
index b1cbbf69..d9fc9df 100644
--- a/ash/webui/diagnostics_ui/url_constants.cc
+++ b/ash/webui/diagnostics_ui/url_constants.cc
@@ -4,9 +4,9 @@
 
 #include "ash/webui/diagnostics_ui/url_constants.h"
 
-namespace chromeos {
+namespace ash {
 
 const char kChromeUIDiagnosticsAppHost[] = "diagnostics";
 const char kChromeUIDiagnosticsAppUrl[] = "chrome://diagnostics";
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/ash/webui/diagnostics_ui/url_constants.h b/ash/webui/diagnostics_ui/url_constants.h
index 7314118a..2db13b6 100644
--- a/ash/webui/diagnostics_ui/url_constants.h
+++ b/ash/webui/diagnostics_ui/url_constants.h
@@ -5,11 +5,16 @@
 #ifndef ASH_WEBUI_DIAGNOSTICS_UI_URL_CONSTANTS_H_
 #define ASH_WEBUI_DIAGNOSTICS_UI_URL_CONSTANTS_H_
 
-namespace chromeos {
+namespace ash {
 
 extern const char kChromeUIDiagnosticsAppHost[];
 extern const char kChromeUIDiagnosticsAppUrl[];
 
+}  // namespace ash
+
+// TODO(https://crbug.com/1164001): remove when ChromeOS code migration is done.
+namespace chromeos {
+using ::ash::kChromeUIDiagnosticsAppUrl;
 }  // namespace chromeos
 
 #endif  // ASH_WEBUI_DIAGNOSTICS_UI_URL_CONSTANTS_H_
diff --git a/ash/webui/scanning/scanning_handler.cc b/ash/webui/scanning/scanning_handler.cc
index a41f7c6..1fbb084 100644
--- a/ash/webui/scanning/scanning_handler.cc
+++ b/ash/webui/scanning/scanning_handler.cc
@@ -116,7 +116,7 @@
 }
 
 void ScanningHandler::HandleInitialize(const base::ListValue* args) {
-  DCHECK(args && args->empty());
+  DCHECK(args && args->GetList().empty());
   AllowJavascript();
 }
 
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc
index c79e9e9..8589102 100644
--- a/ash/wm/desks/desks_unittests.cc
+++ b/ash/wm/desks/desks_unittests.cc
@@ -3189,7 +3189,7 @@
     DCHECK(prefs);
     ListPrefUpdate update(prefs, prefs::kDesksNamesList);
     base::ListValue* pref_data = update.Get();
-    ASSERT_TRUE(pref_data->empty());
+    ASSERT_TRUE(pref_data->GetList().empty());
     for (auto desk_name : desk_names)
       pref_data->Append(desk_name);
   }
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc
index 3c95bb8..e9cd874 100644
--- a/ash/wm/overview/overview_utils.cc
+++ b/ash/wm/overview/overview_utils.cc
@@ -92,8 +92,6 @@
   if (window->layer()->GetTargetOpacity() == 1.f)
     return;
 
-  gfx::Transform original_transform = window->transform();
-
   // Fade in the widget from its current opacity.
   ScopedOverviewAnimationSettings scoped_overview_animation_settings(
       animation_type, window);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 4b3cdc4..809973e9 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -1318,6 +1318,17 @@
     split_view_divider_->OnWindowDragEnded();
 }
 
+SplitViewController::SnapPosition SplitViewController::ComputeSnapPosition(
+    const gfx::Point& last_location_in_screen) {
+  const int divider_position = InSplitViewMode() ? this->divider_position()
+                                                 : GetDefaultDividerPosition();
+  const int position = IsLayoutHorizontal() ? last_location_in_screen.x()
+                                            : last_location_in_screen.y();
+  return (position <= divider_position) == IsLayoutRightSideUp()
+             ? SplitViewController::LEFT
+             : SplitViewController::RIGHT;
+}
+
 void SplitViewController::AddObserver(SplitViewObserver* observer) {
   observers_.AddObserver(observer);
 }
@@ -2344,17 +2355,6 @@
   }
 }
 
-SplitViewController::SnapPosition SplitViewController::ComputeSnapPosition(
-    const gfx::Point& last_location_in_screen) {
-  const int divider_position = InSplitViewMode() ? this->divider_position()
-                                                 : GetDefaultDividerPosition();
-  const int position = IsLayoutHorizontal() ? last_location_in_screen.x()
-                                            : last_location_in_screen.y();
-  return (position <= divider_position) == IsLayoutRightSideUp()
-             ? SplitViewController::LEFT
-             : SplitViewController::RIGHT;
-}
-
 void SplitViewController::DoSplitDividerSpawnAnimation(aura::Window* window) {
   DCHECK(window->layer()->GetAnimator()->GetTargetTransform().IsIdentity());
   SnapPosition snap_position = GetPositionOfSnappedWindow(window);
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h
index 9dee64f..3fb162b8 100644
--- a/ash/wm/splitview/split_view_controller.h
+++ b/ash/wm/splitview/split_view_controller.h
@@ -237,6 +237,13 @@
                          const gfx::Point& last_location_in_screen);
   void OnWindowDragCanceled();
 
+  // Computes the snap position for a dragged window, based on the last
+  // mouse/gesture event location. Called by |EndWindowDragImpl| when
+  // desired_snap_position is |NONE| but because split view is already active,
+  // the dragged window needs to be snapped anyway.
+  SplitViewController::SnapPosition ComputeSnapPosition(
+      const gfx::Point& last_location_in_screen);
+
   void AddObserver(SplitViewObserver* observer);
   void RemoveObserver(SplitViewObserver* observer);
 
@@ -449,13 +456,6 @@
                          SnapPosition desired_snap_position,
                          const gfx::Point& last_location_in_screen);
 
-  // Computes the snap position for a dragged window, based on the last
-  // mouse/gesture event location. Called by |EndWindowDragImpl| when
-  // desired_snap_position is |NONE| but because split view is already active,
-  // the dragged window needs to be snapped anyway.
-  SplitViewController::SnapPosition ComputeSnapPosition(
-      const gfx::Point& last_location_in_screen);
-
   // Do the split divider spawn animation. It will add a finishing touch to the
   // |window| animation that generally accommodates snapping by dragging.
   void DoSplitDividerSpawnAnimation(aura::Window* window);
diff --git a/base/BUILD.gn b/base/BUILD.gn
index b48ef948..0f8ab69 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1870,6 +1870,7 @@
         "allocator/partition_allocator/partition_alloc_hooks.h",
         "allocator/partition_allocator/partition_bucket.cc",
         "allocator/partition_allocator/partition_bucket.h",
+        "allocator/partition_allocator/partition_bucket_lookup.h",
         "allocator/partition_allocator/partition_cookie.h",
         "allocator/partition_allocator/partition_direct_map_extent.h",
         "allocator/partition_allocator/partition_freelist_entry.h",
@@ -3894,6 +3895,7 @@
       "android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
       "android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
       "android/java/src/org/chromium/base/library_loader/Linker.java",
+      "android/java/src/org/chromium/base/library_loader/LinkerJni.java",
       "android/java/src/org/chromium/base/library_loader/LoaderErrors.java",
       "android/java/src/org/chromium/base/library_loader/ModernLinker.java",
       "android/java/src/org/chromium/base/library_loader/NativeLibraryPreloader.java",
@@ -4176,6 +4178,7 @@
       "android/junit/src/org/chromium/base/jank_tracker/JankMetricUMARecorderTest.java",
       "android/junit/src/org/chromium/base/jank_tracker/JankReportingRunnableTest.java",
       "android/junit/src/org/chromium/base/jank_tracker/JankReportingSchedulerTest.java",
+      "android/junit/src/org/chromium/base/library_loader/LinkerTest.java",
       "android/junit/src/org/chromium/base/memory/MemoryPressureMonitorTest.java",
       "android/junit/src/org/chromium/base/metrics/CachingUmaRecorderTest.java",
       "android/junit/src/org/chromium/base/metrics/test/ShadowRecordHistogramTest.java",
diff --git a/base/allocator/partition_allocator/partition_address_space.cc b/base/allocator/partition_allocator/partition_address_space.cc
index 9003a4e..e7de7d2 100644
--- a/base/allocator/partition_allocator/partition_address_space.cc
+++ b/base/allocator/partition_allocator/partition_address_space.cc
@@ -5,6 +5,7 @@
 #include "base/allocator/partition_allocator/partition_address_space.h"
 
 #include <array>
+#include <ostream>
 
 #include "base/allocator/partition_allocator/address_pool_manager.h"
 #include "base/allocator/partition_allocator/page_allocator.h"
diff --git a/base/allocator/partition_allocator/partition_alloc_hooks.cc b/base/allocator/partition_allocator/partition_alloc_hooks.cc
index a611d3e..122920df 100644
--- a/base/allocator/partition_allocator/partition_alloc_hooks.cc
+++ b/base/allocator/partition_allocator/partition_alloc_hooks.cc
@@ -4,6 +4,8 @@
 
 #include "base/allocator/partition_allocator/partition_alloc_hooks.h"
 
+#include <ostream>
+
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/no_destructor.h"
 #include "base/synchronization/lock.h"
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index 928d689..c9be495 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -3173,53 +3173,71 @@
   char* ptr = reinterpret_cast<char*>(
       allocator.root()->Alloc(kTestAllocSize, type_name));
   EXPECT_TRUE(ptr);
-  EXPECT_FALSE(IsReservationStart(ptr));
-  EXPECT_TRUE(IsManagedByNormalBuckets(ptr));
-  EXPECT_FALSE(IsManagedByDirectMap(ptr));
-  EXPECT_FALSE(IsReservationStart(ptr + kTestAllocSize - 1));
-  EXPECT_TRUE(IsManagedByNormalBuckets(ptr + kTestAllocSize - 1));
-  EXPECT_FALSE(IsManagedByDirectMap(ptr + kTestAllocSize - 1));
-  EXPECT_TRUE(IsReservationStart(bits::AlignDown(ptr, kSuperPageSize)));
-  EXPECT_TRUE(IsManagedByNormalBuckets(bits::AlignDown(ptr, kSuperPageSize)));
-  EXPECT_FALSE(IsManagedByDirectMap(bits::AlignDown(ptr, kSuperPageSize)));
+  void* ptr_to_check = ptr;
+  EXPECT_FALSE(IsReservationStart(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  ptr_to_check = ptr + kTestAllocSize - 1;
+  EXPECT_FALSE(IsReservationStart(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  ptr_to_check = bits::AlignDown(ptr, kSuperPageSize);
+  EXPECT_TRUE(IsReservationStart(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
   allocator.root()->Free(ptr);
   // Freeing keeps a normal-bucket super page in memory.
-  EXPECT_TRUE(IsReservationStart(bits::AlignDown(ptr, kSuperPageSize)));
+  ptr_to_check = bits::AlignDown(ptr, kSuperPageSize);
+  EXPECT_TRUE(IsReservationStart(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  // Pick a likely unallocated super page.
+  ptr_to_check = bits::AlignUp(ptr, kSuperPageSize) + 100 * kSuperPageSize;
 #if DCHECK_IS_ON()
   // Expect to DCHECK on unallocated region.
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsReservationStart(bits::AlignUp(ptr, kSuperPageSize)), "");
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsManagedByNormalBuckets(bits::AlignUp(ptr, kSuperPageSize)), "");
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsManagedByDirectMap(bits::AlignUp(ptr, kSuperPageSize)), "");
+  EXPECT_DEATH_IF_SUPPORTED(IsReservationStart(ptr_to_check), "");
 #endif
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
 
   size_t large_size = 2 * kSuperPageSize;
   ptr = reinterpret_cast<char*>(allocator.root()->Alloc(large_size, type_name));
   EXPECT_TRUE(ptr);
-  EXPECT_FALSE(IsReservationStart(ptr));
-  EXPECT_FALSE(IsManagedByNormalBuckets(ptr));
-  EXPECT_TRUE(IsManagedByDirectMap(ptr));
-  EXPECT_FALSE(IsReservationStart(bits::AlignUp(ptr, kSuperPageSize)));
-  EXPECT_FALSE(IsManagedByNormalBuckets(bits::AlignUp(ptr, kSuperPageSize)));
-  EXPECT_TRUE(IsManagedByDirectMap(bits::AlignUp(ptr, kSuperPageSize)));
-  EXPECT_FALSE(IsReservationStart(ptr + large_size - 1));
-  EXPECT_FALSE(IsManagedByNormalBuckets(ptr + large_size - 1));
-  EXPECT_TRUE(IsManagedByDirectMap(ptr + large_size - 1));
-  EXPECT_TRUE(IsReservationStart(bits::AlignDown(ptr, kSuperPageSize)));
-  EXPECT_FALSE(IsManagedByNormalBuckets(bits::AlignDown(ptr, kSuperPageSize)));
-  EXPECT_TRUE(IsManagedByDirectMap(bits::AlignDown(ptr, kSuperPageSize)));
+  ptr_to_check = ptr;
+  EXPECT_FALSE(IsReservationStart(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_TRUE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  ptr_to_check = bits::AlignUp(ptr, kSuperPageSize);
+  EXPECT_FALSE(IsReservationStart(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_TRUE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  ptr_to_check = ptr + large_size - 1;
+  EXPECT_FALSE(IsReservationStart(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_TRUE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
+  ptr_to_check = bits::AlignDown(ptr, kSuperPageSize);
+  EXPECT_TRUE(IsReservationStart(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_TRUE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_TRUE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
   allocator.root()->Free(ptr);
+  // Freeing releases direct-map super pages.
+  ptr_to_check = bits::AlignDown(ptr, kSuperPageSize);
 #if DCHECK_IS_ON()
-  // Freeing releases direct-map super pages. Expect to DCHECK.
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsReservationStart(bits::AlignDown(ptr, kSuperPageSize)), "");
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsManagedByNormalBuckets(bits::AlignDown(ptr, kSuperPageSize)), "");
-  EXPECT_DEATH_IF_SUPPORTED(
-      IsManagedByDirectMap(bits::AlignDown(ptr, kSuperPageSize)), "");
+  // Expect to DCHECK on unallocated region.
+  EXPECT_DEATH_IF_SUPPORTED(IsReservationStart(ptr_to_check), "");
 #endif
+  EXPECT_FALSE(IsManagedByNormalBuckets(ptr_to_check));
+  EXPECT_FALSE(IsManagedByDirectMap(ptr_to_check));
+  EXPECT_FALSE(IsManagedByNormalBucketsOrDirectMap(ptr_to_check));
 }
 
 // Test for crash http://crbug.com/1169003.
diff --git a/base/allocator/partition_allocator/partition_bucket_lookup.h b/base/allocator/partition_allocator/partition_bucket_lookup.h
new file mode 100644
index 0000000..d6a3a9f
--- /dev/null
+++ b/base/allocator/partition_allocator/partition_bucket_lookup.h
@@ -0,0 +1,190 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_BUCKET_LOOKUP_H_
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_BUCKET_LOOKUP_H_
+
+#include <cstdint>
+
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
+#include "base/allocator/partition_allocator/partition_alloc_config.h"
+#include "base/allocator/partition_allocator/partition_alloc_constants.h"
+#include "base/bits.h"
+#include "base/compiler_specific.h"
+
+namespace base {
+namespace internal {
+namespace {
+
+// Precalculate some shift and mask constants used in the hot path.
+// Example: malloc(41) == 101001 binary.
+// Order is 6 (1 << 6-1) == 32 is highest bit set.
+// order_index is the next three MSB == 010 == 2.
+// sub_order_index_mask is a mask for the remaining bits == 11 (masking to 01
+// for the sub_order_index).
+constexpr uint8_t OrderIndexShift(uint8_t order) {
+  if (order < kNumBucketsPerOrderBits + 1)
+    return 0;
+
+  return order - (kNumBucketsPerOrderBits + 1);
+}
+
+constexpr size_t OrderSubIndexMask(uint8_t order) {
+  if (order == kBitsPerSizeT)
+    return static_cast<size_t>(-1) >> (kNumBucketsPerOrderBits + 1);
+
+  return ((static_cast<size_t>(1) << order) - 1) >>
+         (kNumBucketsPerOrderBits + 1);
+}
+
+#if defined(PA_HAS_64_BITS_POINTERS)
+#define BITS_PER_SIZE_T 64
+static_assert(kBitsPerSizeT == 64, "");
+#else
+#define BITS_PER_SIZE_T 32
+static_assert(kBitsPerSizeT == 32, "");
+#endif  // defined(PA_HAS_64_BITS_POINTERS)
+
+constexpr uint8_t kOrderIndexShift[BITS_PER_SIZE_T + 1] = {
+    OrderIndexShift(0),  OrderIndexShift(1),  OrderIndexShift(2),
+    OrderIndexShift(3),  OrderIndexShift(4),  OrderIndexShift(5),
+    OrderIndexShift(6),  OrderIndexShift(7),  OrderIndexShift(8),
+    OrderIndexShift(9),  OrderIndexShift(10), OrderIndexShift(11),
+    OrderIndexShift(12), OrderIndexShift(13), OrderIndexShift(14),
+    OrderIndexShift(15), OrderIndexShift(16), OrderIndexShift(17),
+    OrderIndexShift(18), OrderIndexShift(19), OrderIndexShift(20),
+    OrderIndexShift(21), OrderIndexShift(22), OrderIndexShift(23),
+    OrderIndexShift(24), OrderIndexShift(25), OrderIndexShift(26),
+    OrderIndexShift(27), OrderIndexShift(28), OrderIndexShift(29),
+    OrderIndexShift(30), OrderIndexShift(31), OrderIndexShift(32),
+#if BITS_PER_SIZE_T == 64
+    OrderIndexShift(33), OrderIndexShift(34), OrderIndexShift(35),
+    OrderIndexShift(36), OrderIndexShift(37), OrderIndexShift(38),
+    OrderIndexShift(39), OrderIndexShift(40), OrderIndexShift(41),
+    OrderIndexShift(42), OrderIndexShift(43), OrderIndexShift(44),
+    OrderIndexShift(45), OrderIndexShift(46), OrderIndexShift(47),
+    OrderIndexShift(48), OrderIndexShift(49), OrderIndexShift(50),
+    OrderIndexShift(51), OrderIndexShift(52), OrderIndexShift(53),
+    OrderIndexShift(54), OrderIndexShift(55), OrderIndexShift(56),
+    OrderIndexShift(57), OrderIndexShift(58), OrderIndexShift(59),
+    OrderIndexShift(60), OrderIndexShift(61), OrderIndexShift(62),
+    OrderIndexShift(63), OrderIndexShift(64)
+#endif
+};
+
+constexpr size_t kOrderSubIndexMask[BITS_PER_SIZE_T + 1] = {
+    OrderSubIndexMask(0),  OrderSubIndexMask(1),  OrderSubIndexMask(2),
+    OrderSubIndexMask(3),  OrderSubIndexMask(4),  OrderSubIndexMask(5),
+    OrderSubIndexMask(6),  OrderSubIndexMask(7),  OrderSubIndexMask(8),
+    OrderSubIndexMask(9),  OrderSubIndexMask(10), OrderSubIndexMask(11),
+    OrderSubIndexMask(12), OrderSubIndexMask(13), OrderSubIndexMask(14),
+    OrderSubIndexMask(15), OrderSubIndexMask(16), OrderSubIndexMask(17),
+    OrderSubIndexMask(18), OrderSubIndexMask(19), OrderSubIndexMask(20),
+    OrderSubIndexMask(21), OrderSubIndexMask(22), OrderSubIndexMask(23),
+    OrderSubIndexMask(24), OrderSubIndexMask(25), OrderSubIndexMask(26),
+    OrderSubIndexMask(27), OrderSubIndexMask(28), OrderSubIndexMask(29),
+    OrderSubIndexMask(30), OrderSubIndexMask(31), OrderSubIndexMask(32),
+#if BITS_PER_SIZE_T == 64
+    OrderSubIndexMask(33), OrderSubIndexMask(34), OrderSubIndexMask(35),
+    OrderSubIndexMask(36), OrderSubIndexMask(37), OrderSubIndexMask(38),
+    OrderSubIndexMask(39), OrderSubIndexMask(40), OrderSubIndexMask(41),
+    OrderSubIndexMask(42), OrderSubIndexMask(43), OrderSubIndexMask(44),
+    OrderSubIndexMask(45), OrderSubIndexMask(46), OrderSubIndexMask(47),
+    OrderSubIndexMask(48), OrderSubIndexMask(49), OrderSubIndexMask(50),
+    OrderSubIndexMask(51), OrderSubIndexMask(52), OrderSubIndexMask(53),
+    OrderSubIndexMask(54), OrderSubIndexMask(55), OrderSubIndexMask(56),
+    OrderSubIndexMask(57), OrderSubIndexMask(58), OrderSubIndexMask(59),
+    OrderSubIndexMask(60), OrderSubIndexMask(61), OrderSubIndexMask(62),
+    OrderSubIndexMask(63), OrderSubIndexMask(64)
+#endif
+};
+
+}  // namespace
+
+// The class used to generate the bucket lookup table at compile-time.
+class BucketIndexLookup final {
+ public:
+  ALWAYS_INLINE constexpr static size_t GetIndex(size_t size);
+
+ private:
+  constexpr BucketIndexLookup() {
+    constexpr uint16_t sentinel_bucket_index = kNumBuckets;
+
+    InitBucketSizes();
+
+    uint16_t* bucket_index_ptr = &bucket_index_lookup_[0];
+    uint16_t bucket_index = 0;
+
+    for (uint8_t order = 0; order <= kBitsPerSizeT; ++order) {
+      for (uint16_t j = 0; j < kNumBucketsPerOrder; ++j) {
+        if (order < kMinBucketedOrder) {
+          // Use the bucket of the finest granularity for malloc(0) etc.
+          *bucket_index_ptr++ = 0;
+        } else if (order > kMaxBucketedOrder) {
+          *bucket_index_ptr++ = sentinel_bucket_index;
+        } else {
+          uint16_t valid_bucket_index = bucket_index;
+          while (bucket_sizes_[valid_bucket_index] % kSmallestBucket)
+            valid_bucket_index++;
+          *bucket_index_ptr++ = valid_bucket_index;
+          bucket_index++;
+        }
+      }
+    }
+    PA_DCHECK(bucket_index == kNumBuckets);
+    PA_DCHECK(bucket_index_ptr == bucket_index_lookup_ + ((kBitsPerSizeT + 1) *
+                                                          kNumBucketsPerOrder));
+    // And there's one last bucket lookup that will be hit for e.g. malloc(-1),
+    // which tries to overflow to a non-existent order.
+    *bucket_index_ptr = sentinel_bucket_index;
+  }
+
+  constexpr void InitBucketSizes() {
+    size_t current_size = kSmallestBucket;
+    size_t current_increment = kSmallestBucket >> kNumBucketsPerOrderBits;
+    size_t* bucket_size = &bucket_sizes_[0];
+    for (size_t i = 0; i < kNumBucketedOrders; ++i) {
+      for (size_t j = 0; j < kNumBucketsPerOrder; ++j) {
+        *bucket_size = current_size;
+        // Disable pseudo buckets so that touching them faults.
+        current_size += current_increment;
+        ++bucket_size;
+      }
+      current_increment <<= 1;
+    }
+  }
+
+  size_t bucket_sizes_[kNumBuckets]{};
+  // The bucket lookup table lets us map a size_t to a bucket quickly.
+  // The trailing +1 caters for the overflow case for very large allocation
+  // sizes.  It is one flat array instead of a 2D array because in the 2D
+  // world, we'd need to index array[blah][max+1] which risks undefined
+  // behavior.
+  uint16_t
+      bucket_index_lookup_[((kBitsPerSizeT + 1) * kNumBucketsPerOrder) + 1]{};
+};
+
+// static
+ALWAYS_INLINE constexpr size_t BucketIndexLookup::GetIndex(size_t size) {
+  // This forces the bucket table to be constant-initialized and immediately
+  // materialized in the binary.
+  constexpr BucketIndexLookup lookup{};
+  const uint8_t order = kBitsPerSizeT - bits::CountLeadingZeroBitsSizeT(size);
+  // The order index is simply the next few bits after the most significant
+  // bit.
+  const size_t order_index =
+      (size >> kOrderIndexShift[order]) & (kNumBucketsPerOrder - 1);
+  // And if the remaining bits are non-zero we must bump the bucket up.
+  const size_t sub_order_index = size & kOrderSubIndexMask[order];
+  const uint16_t index =
+      lookup.bucket_index_lookup_[(order << kNumBucketsPerOrderBits) +
+                                  order_index + !!sub_order_index];
+  PA_DCHECK(index <= kNumBuckets);  // Last one is the sentinel bucket.
+  return index;
+}
+
+}  // namespace internal
+}  // namespace base
+
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_BUCKET_LOOKUP_H_
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index 81aff8c..69aa3164 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -44,6 +44,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_features.h"
 #include "base/allocator/partition_allocator/partition_alloc_forward.h"
 #include "base/allocator/partition_allocator/partition_alloc_hooks.h"
+#include "base/allocator/partition_allocator/partition_bucket_lookup.h"
 #include "base/allocator/partition_allocator/partition_direct_map_extent.h"
 #include "base/allocator/partition_allocator/partition_lock.h"
 #include "base/allocator/partition_allocator/partition_oom.h"
@@ -52,7 +53,6 @@
 #include "base/allocator/partition_allocator/reservation_offset_table.h"
 #include "base/allocator/partition_allocator/starscan/pcscan.h"
 #include "base/allocator/partition_allocator/thread_cache.h"
-#include "base/bits.h"
 #include "base/compiler_specific.h"
 #include "build/build_config.h"
 
@@ -614,177 +614,8 @@
   friend class internal::ThreadCache;
 };
 
-namespace {
-
-// Precalculate some shift and mask constants used in the hot path.
-// Example: malloc(41) == 101001 binary.
-// Order is 6 (1 << 6-1) == 32 is highest bit set.
-// order_index is the next three MSB == 010 == 2.
-// sub_order_index_mask is a mask for the remaining bits == 11 (masking to 01
-// for the sub_order_index).
-constexpr uint8_t OrderIndexShift(uint8_t order) {
-  if (order < kNumBucketsPerOrderBits + 1)
-    return 0;
-
-  return order - (kNumBucketsPerOrderBits + 1);
-}
-
-constexpr size_t OrderSubIndexMask(uint8_t order) {
-  if (order == kBitsPerSizeT)
-    return static_cast<size_t>(-1) >> (kNumBucketsPerOrderBits + 1);
-
-  return ((static_cast<size_t>(1) << order) - 1) >>
-         (kNumBucketsPerOrderBits + 1);
-}
-
-#if defined(PA_HAS_64_BITS_POINTERS)
-#define BITS_PER_SIZE_T 64
-static_assert(kBitsPerSizeT == 64, "");
-#else
-#define BITS_PER_SIZE_T 32
-static_assert(kBitsPerSizeT == 32, "");
-#endif  // defined(PA_HAS_64_BITS_POINTERS)
-
-constexpr uint8_t kOrderIndexShift[BITS_PER_SIZE_T + 1] = {
-    OrderIndexShift(0),  OrderIndexShift(1),  OrderIndexShift(2),
-    OrderIndexShift(3),  OrderIndexShift(4),  OrderIndexShift(5),
-    OrderIndexShift(6),  OrderIndexShift(7),  OrderIndexShift(8),
-    OrderIndexShift(9),  OrderIndexShift(10), OrderIndexShift(11),
-    OrderIndexShift(12), OrderIndexShift(13), OrderIndexShift(14),
-    OrderIndexShift(15), OrderIndexShift(16), OrderIndexShift(17),
-    OrderIndexShift(18), OrderIndexShift(19), OrderIndexShift(20),
-    OrderIndexShift(21), OrderIndexShift(22), OrderIndexShift(23),
-    OrderIndexShift(24), OrderIndexShift(25), OrderIndexShift(26),
-    OrderIndexShift(27), OrderIndexShift(28), OrderIndexShift(29),
-    OrderIndexShift(30), OrderIndexShift(31), OrderIndexShift(32),
-#if BITS_PER_SIZE_T == 64
-    OrderIndexShift(33), OrderIndexShift(34), OrderIndexShift(35),
-    OrderIndexShift(36), OrderIndexShift(37), OrderIndexShift(38),
-    OrderIndexShift(39), OrderIndexShift(40), OrderIndexShift(41),
-    OrderIndexShift(42), OrderIndexShift(43), OrderIndexShift(44),
-    OrderIndexShift(45), OrderIndexShift(46), OrderIndexShift(47),
-    OrderIndexShift(48), OrderIndexShift(49), OrderIndexShift(50),
-    OrderIndexShift(51), OrderIndexShift(52), OrderIndexShift(53),
-    OrderIndexShift(54), OrderIndexShift(55), OrderIndexShift(56),
-    OrderIndexShift(57), OrderIndexShift(58), OrderIndexShift(59),
-    OrderIndexShift(60), OrderIndexShift(61), OrderIndexShift(62),
-    OrderIndexShift(63), OrderIndexShift(64)
-#endif
-};
-
-constexpr size_t kOrderSubIndexMask[BITS_PER_SIZE_T + 1] = {
-    OrderSubIndexMask(0),  OrderSubIndexMask(1),  OrderSubIndexMask(2),
-    OrderSubIndexMask(3),  OrderSubIndexMask(4),  OrderSubIndexMask(5),
-    OrderSubIndexMask(6),  OrderSubIndexMask(7),  OrderSubIndexMask(8),
-    OrderSubIndexMask(9),  OrderSubIndexMask(10), OrderSubIndexMask(11),
-    OrderSubIndexMask(12), OrderSubIndexMask(13), OrderSubIndexMask(14),
-    OrderSubIndexMask(15), OrderSubIndexMask(16), OrderSubIndexMask(17),
-    OrderSubIndexMask(18), OrderSubIndexMask(19), OrderSubIndexMask(20),
-    OrderSubIndexMask(21), OrderSubIndexMask(22), OrderSubIndexMask(23),
-    OrderSubIndexMask(24), OrderSubIndexMask(25), OrderSubIndexMask(26),
-    OrderSubIndexMask(27), OrderSubIndexMask(28), OrderSubIndexMask(29),
-    OrderSubIndexMask(30), OrderSubIndexMask(31), OrderSubIndexMask(32),
-#if BITS_PER_SIZE_T == 64
-    OrderSubIndexMask(33), OrderSubIndexMask(34), OrderSubIndexMask(35),
-    OrderSubIndexMask(36), OrderSubIndexMask(37), OrderSubIndexMask(38),
-    OrderSubIndexMask(39), OrderSubIndexMask(40), OrderSubIndexMask(41),
-    OrderSubIndexMask(42), OrderSubIndexMask(43), OrderSubIndexMask(44),
-    OrderSubIndexMask(45), OrderSubIndexMask(46), OrderSubIndexMask(47),
-    OrderSubIndexMask(48), OrderSubIndexMask(49), OrderSubIndexMask(50),
-    OrderSubIndexMask(51), OrderSubIndexMask(52), OrderSubIndexMask(53),
-    OrderSubIndexMask(54), OrderSubIndexMask(55), OrderSubIndexMask(56),
-    OrderSubIndexMask(57), OrderSubIndexMask(58), OrderSubIndexMask(59),
-    OrderSubIndexMask(60), OrderSubIndexMask(61), OrderSubIndexMask(62),
-    OrderSubIndexMask(63), OrderSubIndexMask(64)
-#endif
-};
-
-}  // namespace
-
 namespace internal {
 
-// The class used to generate the bucket lookup table at compile-time.
-class BucketIndexLookup final {
- public:
-  ALWAYS_INLINE constexpr static size_t GetIndex(size_t size);
-
- private:
-  constexpr BucketIndexLookup() {
-    constexpr uint16_t sentinel_bucket_index = kNumBuckets;
-
-    InitBucketSizes();
-
-    uint16_t* bucket_index_ptr = &bucket_index_lookup_[0];
-    uint16_t bucket_index = 0;
-
-    for (uint8_t order = 0; order <= kBitsPerSizeT; ++order) {
-      for (uint16_t j = 0; j < kNumBucketsPerOrder; ++j) {
-        if (order < kMinBucketedOrder) {
-          // Use the bucket of the finest granularity for malloc(0) etc.
-          *bucket_index_ptr++ = 0;
-        } else if (order > kMaxBucketedOrder) {
-          *bucket_index_ptr++ = sentinel_bucket_index;
-        } else {
-          uint16_t valid_bucket_index = bucket_index;
-          while (bucket_sizes_[valid_bucket_index] % kSmallestBucket)
-            valid_bucket_index++;
-          *bucket_index_ptr++ = valid_bucket_index;
-          bucket_index++;
-        }
-      }
-    }
-    PA_DCHECK(bucket_index == kNumBuckets);
-    PA_DCHECK(bucket_index_ptr == bucket_index_lookup_ + ((kBitsPerSizeT + 1) *
-                                                          kNumBucketsPerOrder));
-    // And there's one last bucket lookup that will be hit for e.g. malloc(-1),
-    // which tries to overflow to a non-existent order.
-    *bucket_index_ptr = sentinel_bucket_index;
-  }
-
-  constexpr void InitBucketSizes() {
-    size_t current_size = kSmallestBucket;
-    size_t current_increment = kSmallestBucket >> kNumBucketsPerOrderBits;
-    size_t* bucket_size = &bucket_sizes_[0];
-    for (size_t i = 0; i < kNumBucketedOrders; ++i) {
-      for (size_t j = 0; j < kNumBucketsPerOrder; ++j) {
-        *bucket_size = current_size;
-        // Disable pseudo buckets so that touching them faults.
-        current_size += current_increment;
-        ++bucket_size;
-      }
-      current_increment <<= 1;
-    }
-  }
-
-  size_t bucket_sizes_[kNumBuckets]{};
-  // The bucket lookup table lets us map a size_t to a bucket quickly.
-  // The trailing +1 caters for the overflow case for very large allocation
-  // sizes.  It is one flat array instead of a 2D array because in the 2D
-  // world, we'd need to index array[blah][max+1] which risks undefined
-  // behavior.
-  uint16_t
-      bucket_index_lookup_[((kBitsPerSizeT + 1) * kNumBucketsPerOrder) + 1]{};
-};
-
-// static
-ALWAYS_INLINE constexpr size_t BucketIndexLookup::GetIndex(size_t size) {
-  // This forces the bucket table to be constant-initialized and immediately
-  // materialized in the binary.
-  constexpr BucketIndexLookup lookup{};
-  const uint8_t order = kBitsPerSizeT - bits::CountLeadingZeroBitsSizeT(size);
-  // The order index is simply the next few bits after the most significant
-  // bit.
-  const size_t order_index =
-      (size >> kOrderIndexShift[order]) & (kNumBucketsPerOrder - 1);
-  // And if the remaining bits are non-zero we must bump the bucket up.
-  const size_t sub_order_index = size & kOrderSubIndexMask[order];
-  const uint16_t index =
-      lookup.bucket_index_lookup_[(order << kNumBucketsPerOrderBits) +
-                                  order_index + !!sub_order_index];
-  PA_DCHECK(index <= kNumBuckets);  // Last one is the sentinel bucket.
-  return index;
-}
-
 // Gets the SlotSpanMetadata object of the slot span that contains |ptr|. It's
 // used with intention to do obtain the slot size.
 //
@@ -852,6 +683,7 @@
   // kPartitionPastAllocationAdjustment takes care of that detail.
   ptr = reinterpret_cast<char*>(ptr) - kPartitionPastAllocationAdjustment;
 
+  PA_DCHECK(IsManagedByNormalBucketsOrDirectMap(ptr));
 #if BUILDFLAG(ENABLE_BRP_DIRECTMAP_SUPPORT)
   DCheckIfManagedByPartitionAllocBRPPool(ptr);
 #else
diff --git a/base/allocator/partition_allocator/reservation_offset_table.h b/base/allocator/partition_allocator/reservation_offset_table.h
index fc3c8f6c..ff26db5e 100644
--- a/base/allocator/partition_allocator/reservation_offset_table.h
+++ b/base/allocator/partition_allocator/reservation_offset_table.h
@@ -162,21 +162,26 @@
 }
 
 // Returns true if |address| belongs to a normal bucket super page.
-// |address| must belong to an allocated super page.
 ALWAYS_INLINE bool IsManagedByNormalBuckets(const void* address) {
   uintptr_t address_as_uintptr = reinterpret_cast<uintptr_t>(address);
   uint16_t* offset_ptr = ReservationOffsetPointer(address_as_uintptr);
-  PA_DCHECK(*offset_ptr != kOffsetTagNotAllocated);
   return *offset_ptr == kOffsetTagNormalBuckets;
 }
 
 // Returns true if |address| belongs to a direct map region.
-// |address| must belong to an allocated super page.
 ALWAYS_INLINE bool IsManagedByDirectMap(const void* address) {
   uintptr_t address_as_uintptr = reinterpret_cast<uintptr_t>(address);
   uint16_t* offset_ptr = ReservationOffsetPointer(address_as_uintptr);
-  PA_DCHECK(*offset_ptr != kOffsetTagNotAllocated);
-  return *offset_ptr != kOffsetTagNormalBuckets;
+  return *offset_ptr != kOffsetTagNormalBuckets &&
+         *offset_ptr != kOffsetTagNotAllocated;
+}
+
+// Returns true if |address| belongs to a normal bucket super page or a direct
+// map region, i.e. belongs to an allocated super page.
+ALWAYS_INLINE bool IsManagedByNormalBucketsOrDirectMap(const void* address) {
+  uintptr_t address_as_uintptr = reinterpret_cast<uintptr_t>(address);
+  uint16_t* offset_ptr = ReservationOffsetPointer(address_as_uintptr);
+  return *offset_ptr != kOffsetTagNotAllocated;
 }
 
 }  // namespace internal
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
index 6793722..08159a0 100644
--- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc
+++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -332,7 +332,10 @@
       super_page, nonempty_slot_spans, [&snapshot](SlotSpan* slot_span) {
         auto* payload_begin =
             static_cast<uintptr_t*>(SlotSpan::ToSlotSpanStartPtr(slot_span));
-        const size_t provisioned_size = slot_span->GetProvisionedSize();
+        // For single-slot slot-spans, scan only utilized slot part.
+        const size_t provisioned_size = UNLIKELY(slot_span->CanStoreRawSize())
+                                            ? slot_span->GetRawSize()
+                                            : slot_span->GetProvisionedSize();
         // Free & decommitted slot spans are skipped.
         PA_DCHECK(provisioned_size > 0);
         auto* payload_end =
@@ -750,17 +753,17 @@
   auto* bitmap =
       QuarantineBitmapFromPointer(QuarantineBitmapType::kScanner, pcscan_epoch_,
                                   reinterpret_cast<char*>(begin));
+  const size_t slot_size_in_words = slot_size / sizeof(uintptr_t);
   for (uintptr_t* current_slot = begin; current_slot < end;
-       current_slot += (slot_size / sizeof(uintptr_t))) {
+       current_slot += slot_size_in_words) {
     // It is okay to skip objects as their payload has been zapped at this
     // point which means that the pointers no longer retain other objects.
     if (bitmap->CheckBit(reinterpret_cast<uintptr_t>(current_slot))) {
       continue;
     }
-    uintptr_t* current_slot_end =
-        current_slot + (slot_size / sizeof(uintptr_t));
-    PA_DCHECK(current_slot_end <= end);
-    scan_loop.Run(current_slot, current_slot_end);
+    uintptr_t* current_slot_end = current_slot + slot_size_in_words;
+    // |slot_size| may be larger than |raw_size| for single-slot slot spans.
+    scan_loop.Run(current_slot, std::min(current_slot_end, end));
   }
 }
 
@@ -1028,6 +1031,8 @@
   write_protector_ = std::make_unique<NoWriteProtector>();
 #endif  // defined(PA_STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED)
   PCScan::SetClearType(write_protector_->SupportedClearType());
+  scannable_roots_ = RootsMap();
+  nonscannable_roots_ = RootsMap();
   is_initialized_ = true;
 }
 
@@ -1291,8 +1296,12 @@
     Root* root = pair.first;
     root->quarantine_mode = Root::QuarantineMode::kDisabledByDefault;
   }
-  scannable_roots_.clear();     // IN-TEST
-  nonscannable_roots_.clear();  // IN-TEST
+  // Make sure to destroy maps so that on the following ReinitForTesting() call
+  // the maps don't attempt to destroy the backing.
+  scannable_roots_.clear();
+  scannable_roots_.~RootsMap();
+  nonscannable_roots_.clear();
+  nonscannable_roots_.~RootsMap();
   // Destroy write protector object, so that there is no double free on the next
   // call to ReinitForTesting();
   write_protector_.reset();
@@ -1300,7 +1309,8 @@
 
 void PCScanInternal::ReinitForTesting(PCScan::WantedWriteProtectionMode mode) {
   is_initialized_ = false;
-  Initialize(mode);
+  auto* new_this = new (this) PCScanInternal;
+  new_this->Initialize(mode);
 }
 
 void PCScanInternal::FinishScanForTesting() {
diff --git a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc
index 09117e2..34fbf4b8 100644
--- a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc
+++ b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc
@@ -238,6 +238,23 @@
         IsInFreeList(value_root->AdjustPointerForExtrasSubtract(value)));
   }
 }
+
+void TestDanglingReferenceNotVisited(PartitionAllocPCScanTest& test,
+                                     void* value) {
+  auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBuckets(
+      reinterpret_cast<char*>(value));
+  value_root->Free(value);
+  // Check that |value| is in the quarantine now.
+  EXPECT_TRUE(test.IsInQuarantine(value));
+  // Run PCScan.
+  test.RunPCScan();
+  // Check that the object is no longer in the quarantine since the pointer to
+  // it was not scanned from the non-scannable partition.
+  EXPECT_FALSE(test.IsInQuarantine(value));
+  // Check that the object is in the freelist now.
+  EXPECT_TRUE(IsInFreeList(value_root->AdjustPointerForExtrasSubtract(value)));
+}
+
 }  // namespace
 
 TEST_F(PartitionAllocPCScanTest, DanglingReferenceSameBucket) {
@@ -398,6 +415,20 @@
   TestDanglingReference(*this, source, value);
 }
 
+TEST_F(PartitionAllocPCScanTest, DanglingReferenceFromSingleSlotSlotSpan) {
+  using SourceList = List<kMaxBucketed - 4096>;
+  using ValueList = SourceList;
+
+  auto* source = SourceList::Create(root());
+  auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr(source);
+  ASSERT_TRUE(slot_span->CanStoreRawSize());
+
+  auto* value = ValueList::Create(root());
+  source->next = value;
+
+  TestDanglingReference(*this, source, value);
+}
+
 TEST_F(PartitionAllocPCScanTest, DanglingInterPartitionReference) {
   using SourceList = List<64>;
   using ValueList = SourceList;
@@ -476,17 +507,7 @@
   auto* value = ValueList::Create(value_root);
   source->next = value;
 
-  // Free |value| and leave the dangling reference in |source|.
-  ValueList::Destroy(source_root, value);
-  // Check that |value| is in the quarantine now.
-  EXPECT_TRUE(IsInQuarantine(value));
-  // Run PCScan.
-  RunPCScan();
-  // Check that the object is no longer in the quarantine since the pointer to
-  // it was not scanned from the non-scannable partition.
-  EXPECT_FALSE(IsInQuarantine(value));
-  // Check that the object is in the freelist now.
-  EXPECT_TRUE(IsInFreeList(value_root.AdjustPointerForExtrasSubtract(value)));
+  TestDanglingReferenceNotVisited(*this, value);
 }
 
 // Death tests misbehave on Android, http://crbug.com/643760.
@@ -605,6 +626,28 @@
   }();
 }
 
+TEST_F(PartitionAllocPCScanTest, DontScanUnusedRawSize) {
+  using ValueList = List<8>;
+
+  // Make sure to commit more memory than requested and have slack for storing
+  // dangling reference outside of the raw size.
+  const size_t big_size = kMaxBucketed - SystemPageSize() + 1;
+  uint8_t* source = static_cast<uint8_t*>(root().Alloc(big_size, nullptr));
+
+  auto* slot_span = SlotSpanMetadata<ThreadSafe>::FromSlotInnerPtr(source);
+  ASSERT_TRUE(slot_span->CanStoreRawSize());
+
+  uint8_t* source_end =
+      static_cast<uint8_t*>(root().AdjustPointerForExtrasSubtract(source)) +
+      slot_span->GetRawSize();
+
+  auto* value = ValueList::Create(root());
+
+  *reinterpret_cast<ValueList**>(source_end) = value;
+
+  TestDanglingReferenceNotVisited(*this, value);
+}
+
 }  // namespace internal
 }  // namespace base
 
diff --git a/base/allocator/partition_allocator/thread_cache.cc b/base/allocator/partition_allocator/thread_cache.cc
index 385133a..6dd3de5 100644
--- a/base/allocator/partition_allocator/thread_cache.cc
+++ b/base/allocator/partition_allocator/thread_cache.cc
@@ -79,7 +79,7 @@
 
 // Start with the normal size, not the maximum one.
 uint16_t ThreadCache::largest_active_bucket_index_ =
-    BucketIndexForSize(kDefaultSizeThreshold);
+    BucketIndexLookup::GetIndex(kDefaultSizeThreshold);
 
 // static
 ThreadCacheRegistry& ThreadCacheRegistry::Instance() {
@@ -310,6 +310,9 @@
 
 // static
 void ThreadCache::Init(PartitionRoot<ThreadSafe>* root) {
+#if defined(OS_NACL)
+  IMMEDIATE_CRASH();
+#endif
   PA_CHECK(root->buckets[kBucketCount - 1].slot_size == kLargeSizeThreshold);
   PA_CHECK(root->buckets[largest_active_bucket_index_].slot_size ==
            kDefaultSizeThreshold);
diff --git a/base/allocator/partition_allocator/thread_cache.h b/base/allocator/partition_allocator/thread_cache.h
index 79f2d4e..7c615a5 100644
--- a/base/allocator/partition_allocator/thread_cache.h
+++ b/base/allocator/partition_allocator/thread_cache.h
@@ -10,6 +10,7 @@
 
 #include "base/allocator/partition_allocator/partition_alloc_config.h"
 #include "base/allocator/partition_allocator/partition_alloc_forward.h"
+#include "base/allocator/partition_allocator/partition_bucket_lookup.h"
 #include "base/allocator/partition_allocator/partition_freelist_entry.h"
 #include "base/allocator/partition_allocator/partition_lock.h"
 #include "base/allocator/partition_allocator/partition_stats.h"
@@ -135,15 +136,6 @@
 #define GET_COUNTER(counter) 0
 #endif  // defined(PA_THREAD_CACHE_ENABLE_STATISTICS)
 
-ALWAYS_INLINE static constexpr int ConstexprLog2(size_t n) {
-  return n < 1 ? -1 : (n < 2 ? 0 : (1 + ConstexprLog2(n >> 1)));
-}
-
-ALWAYS_INLINE static constexpr uint16_t BucketIndexForSize(size_t size) {
-  return ((ConstexprLog2(size) - kMinBucketedOrder + 1)
-          << kNumBucketsPerOrderBits);
-}
-
 #if DCHECK_IS_ON()
 class ReentrancyGuard {
  public:
@@ -306,8 +298,14 @@
   static void SetGlobalLimits(PartitionRoot<ThreadSafe>* root,
                               float multiplier);
 
+#if defined(OS_NACL)
+  // The thread cache is never used with NaCl, but its compiler doesn't
+  // understand enough constexpr to handle the code below.
+  static constexpr uint16_t kBucketCount = 1;
+#else
   static constexpr uint16_t kBucketCount =
-      BucketIndexForSize(kLargeSizeThreshold) + 1;
+      internal::BucketIndexLookup::GetIndex(kLargeSizeThreshold) + 1;
+#endif
   static_assert(
       kBucketCount < kNumBuckets,
       "Cannot have more cached buckets than what the allocator supports");
diff --git a/base/android/java/src/org/chromium/base/PiiElider.java b/base/android/java/src/org/chromium/base/PiiElider.java
index 527041c7..e174cd1 100644
--- a/base/android/java/src/org/chromium/base/PiiElider.java
+++ b/base/android/java/src/org/chromium/base/PiiElider.java
@@ -22,36 +22,56 @@
 
     private static final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
 
-    private static final Pattern IP_ADDRESS = Pattern.compile(
+    private static final String IP_ADDRESS =
             "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
             + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
             + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
-            + "|[1-9][0-9]|[0-9]))");
+            + "|[1-9][0-9]|[0-9]))";
 
     private static final String IRI =
-            "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
+            "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
 
     private static final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
     private static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
     private static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
 
-    private static final Pattern DOMAIN_NAME =
-            Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
+    private static final String URI_ENCODED_CHAR = "(%[a-fA-F0-9]{2})";
+
+    private static final String URI_CHAR = "([a-zA-Z0-9$_.+!*'(),;?&=-]|" + URI_ENCODED_CHAR + ")";
+
+    private static final String PATH_CHAR =
+            // Either a single valid path component character or a URI-encoded character.
+            "(([" + GOOD_IRI_CHAR + ";/?:@&=#~.+!*'(),_-])|" + URI_ENCODED_CHAR + ")";
+
+    private static final String URI_SCHEME = "((http|https|Http|Https|rtsp|Rtsp)://"
+            + "(" + URI_CHAR + "{1,64}(:" + URI_CHAR + "{1,25})?@)?)";
+
+    private static final String DOMAIN_NAME = "(" + HOST_NAME + "|" + IP_ADDRESS + ")";
+
+    private static final String PORT = "(:\\d{1,5})";
+
+    private static final String URL_WITH_OPTIONAL_SCHEME_AND_PORT =
+            "(" + URI_SCHEME + "?" + DOMAIN_NAME + PORT + "?)";
+
+    private static final String PATH_COMPONENT = "(" + PATH_CHAR + "+)";
+
+    // Based on: http://www.faqs.org/rfcs/rfc2396.html#:~:text=Scheme%20Component
+    private static final String INTENT_SCHEME = "[a-zA-Z][a-zA-Z0-9+.-]+://";
+
+    private static final String INTENT = "(" + INTENT_SCHEME + PATH_COMPONENT + ")";
+
+    private static final String URL_OR_INTENT =
+            "(" + URL_WITH_OPTIONAL_SCHEME_AND_PORT + "|" + INTENT + ")";
+
+    private static final Pattern WEB_URL =
+            Pattern.compile("(\\b|^)" // Always start on a word boundary or start of string.
+                    + "(" + URL_OR_INTENT + ")" // Main URL or Intent scheme/domain/root path.
+                    + "(/" + PATH_CHAR + "*)?" // Rest of the URI path.
+                    + "(\\b|$)"); // Always end on a word boundary or end of string.
 
     private static final Pattern LIKELY_EXCEPTION_LOG =
             Pattern.compile("\\sat\\sorg\\.chromium\\.[^ ]+.");
 
-    private static final Pattern WEB_URL =
-            Pattern.compile("(?:\\b|^)((?:(http|https|Http|Https|rtsp|Rtsp):"
-                    + "\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
-                    + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
-                    + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
-                    + "(?:" + DOMAIN_NAME + ")"
-                    + "(?:\\:\\d{1,5})?)"
-                    + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~"
-                    + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
-                    + "(?:\\b|$)");
-
     private static final String IP_ELISION = "1.2.3.4";
     private static final String MAC_ELISION = "01:23:45:67:89:AB";
     private static final String CONSOLE_ELISION = "[ELIDED:CONSOLE(0)] ELIDED CONSOLE MESSAGE";
diff --git a/base/android/java/src/org/chromium/base/library_loader/Linker.java b/base/android/java/src/org/chromium/base/library_loader/Linker.java
index 68e32730..5c339ab 100644
--- a/base/android/java/src/org/chromium/base/library_loader/Linker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/Linker.java
@@ -13,6 +13,7 @@
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
 import org.chromium.base.StreamUtil;
@@ -71,7 +72,6 @@
  * - After loading the native library as a RELRO producer, the putSharedRelrosToBundle() becomes
  *   available to then send the Bundle to Linkers in other processes.
  */
-@JniIgnoreNatives
 abstract class Linker {
     private static final String TAG = "Linker";
 
@@ -186,7 +186,9 @@
             mRelroProducer = false;
             ensureInitializedLocked();
             mLocalLibInfo.mLoadAddress = baseLoadAddress;
-            if (keepMemoryReservationUntilLoad()) nativeReserveMemoryForLibrary(mLocalLibInfo);
+            if (keepMemoryReservationUntilLoad()) {
+                getLinkerJni().reserveMemoryForLibrary(mLocalLibInfo);
+            }
         }
     }
 
@@ -373,7 +375,8 @@
     /** Loads the Linker JNI library. Throws UnsatisfiedLinkError on error. */
     @SuppressLint({"UnsafeDynamicallyLoadedCode"})
     @GuardedBy("mLock")
-    private void loadLinkerJniLibraryLocked() {
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    void loadLinkerJniLibraryLocked() {
         assert mState == State.UNINITIALIZED;
 
         LibraryLoader.setEnvForNative();
@@ -406,7 +409,8 @@
             // load the library with mmap(nullptr, ... MAP_FIXED) on top of it. Unfortunately the
             // crazylinker feature to load on top of a reserved memory region is not well tested and
             // looks buggy.
-            nativeFindMemoryRegionAtRandomAddress(mLocalLibInfo, keepMemoryReservationUntilLoad());
+            getLinkerJni().findMemoryRegionAtRandomAddress(
+                    mLocalLibInfo, keepMemoryReservationUntilLoad());
             if (DEBUG) {
                 Log.i(TAG, "AsRelroProducer: chose address: 0x%x", mLocalLibInfo.mLoadAddress);
             }
@@ -446,8 +450,9 @@
      * Native code accesses the fields of this class by name. Renaming should be done on C++ size as
      * well.
      */
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
     @JniIgnoreNatives
-    protected static class LibInfo implements Parcelable {
+    static class LibInfo implements Parcelable {
         private static final String EXTRA_LINKER_LIB_INFO = "libinfo";
 
         LibInfo() {}
@@ -546,32 +551,47 @@
         public int mRelroFd = -1; // shared RELRO file descriptor, or -1
     }
 
-    /**
-     * Reserves a memory region (=mapping) of sufficient size to hold the loaded library before the
-     * real size is known. The mmap(2) being used here provides built in randomization.
-     *
-     * On failure |libInfo.mLoadAddress| should be set to 0. Observing it a subclass can:
-     * 1. Fail early and let LibraryLoader fall back to loading using the system linker
-     *    (ModernLinker)
-     * 2. Try again (LegacyLinker)
-     *
-     * @param libInfo holds the output values: |mLoadAddress| and |mLoadSize|. On failure sets
-     * the |libInfo.mLoadAddress| to 0.
-     * @param keepReserved should normally be |true|. Setting |keepReserved=false| is intended for
-     * the legacy behavior within the LegacyLinker. This way the address range is freed up
-     * (unmapped) immediately after being reserved.
-     */
-    private static native void nativeFindMemoryRegionAtRandomAddress(
-            @NonNull LibInfo libInfo, boolean keepReserved);
+    // Intentionally omitting @NativeMethods because generation of the stubs it requires (as
+    // GEN_JNI.java) is disabled by the @JniIgnoreNatives.
+    interface Natives {
+        /**
+         * Reserves a memory region (=mapping) of sufficient size to hold the loaded library before
+         * the real size is known. The mmap(2) being used here provides built in randomization.
+         *
+         * On failure |libInfo.mLoadAddress| should be set to 0. Observing it a subclass can:
+         * 1. Fail early and let LibraryLoader fall back to loading using the system linker
+         *    (ModernLinker)
+         * 2. Try again (LegacyLinker)
+         *
+         * @param libInfo holds the output values: |mLoadAddress| and |mLoadSize|. On failure sets
+         *                the |libInfo.mLoadAddress| to 0.
+         * @param keepReserved should normally be |true|. Setting |keepReserved=false| is intended
+         *                     for the legacy behavior within the LegacyLinker. This way the address
+         *                     range is freed up (unmapped) immediately after being reserved.
+         */
+        void findMemoryRegionAtRandomAddress(@NonNull LibInfo libInfo, boolean keepReserved);
 
-    /**
-     * Reserves the fixed address range starting at |libInfo.mLoadAddress| big enough to load the
-     * main native library. The size of the range is an internal detail of the native
-     * implementation.
-     *
-     *
-     * @param libInfo holds the output values: |mLoadAddress| and |mLoadSize|. On success returns
-     * the size in |libInfo.mLoadSize|. On failure sets the |libInfo.mLoadAddress| to 0.
-     */
-    private static native void nativeReserveMemoryForLibrary(@NonNull LibInfo libInfo);
+        /**
+         * Reserves the fixed address range starting at |libInfo.mLoadAddress| big enough to load
+         * the main native library. The size of the range is an internal detail of the native
+         * implementation.
+         *
+         * @param libInfo holds the output values: |mLoadAddress| and |mLoadSize|. On success
+         *                returns the size in |libInfo.mLoadSize|. On failure sets the
+         *                |libInfo.mLoadAddress| to 0.
+         */
+        void reserveMemoryForLibrary(@NonNull LibInfo libInfo);
+    }
+
+    private static Linker.Natives sNativesInstance;
+
+    static void setNativesForTesting(Natives instance) {
+        sNativesInstance = instance;
+    }
+
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    static Linker.Natives getLinkerJni() {
+        if (sNativesInstance != null) return sNativesInstance;
+        return new LinkerJni(); // R8 optimizes away all construction except the initial one.
+    }
 }
diff --git a/base/android/java/src/org/chromium/base/library_loader/LinkerJni.java b/base/android/java/src/org/chromium/base/library_loader/LinkerJni.java
new file mode 100644
index 0000000..061e511
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/library_loader/LinkerJni.java
@@ -0,0 +1,37 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.library_loader;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.base.annotations.JniIgnoreNatives;
+
+/**
+ * Mockable stub for all native methods in Linker.
+ *
+ * This functionality is usually generated from @NativeMethods, which cannot be used for the
+ * auxiliary native library used by classes in Linker and other classes in this package.
+ *
+ * Generation of JNI stubs for classes in this package is omitted via @JniIgnoreNatives because
+ * otherwise the generated native parts would have been linked into lib{,mono}chrome.so instead of
+ * lib$LINKER_JNI_LIBRARY.so, where they are needed.
+ */
+@JniIgnoreNatives
+class LinkerJni implements Linker.Natives {
+    @Override
+    public void findMemoryRegionAtRandomAddress(
+            @NonNull Linker.LibInfo libInfo, boolean keepReserved) {
+        nativeFindMemoryRegionAtRandomAddress(libInfo, keepReserved);
+    }
+
+    @Override
+    public void reserveMemoryForLibrary(@NonNull Linker.LibInfo libInfo) {
+        nativeReserveMemoryForLibrary(libInfo);
+    }
+
+    private static native void nativeFindMemoryRegionAtRandomAddress(
+            @NonNull Linker.LibInfo libInfo, boolean keepReserved);
+    private static native void nativeReserveMemoryForLibrary(@NonNull Linker.LibInfo libInfo);
+}
diff --git a/base/android/jni_generator/golden/testInnerClassNativesBothInnerAndOuterRegistrations.golden b/base/android/jni_generator/golden/testInnerClassNativesBothInnerAndOuterRegistrations.golden
index 0034740..c4702b3 100644
--- a/base/android/jni_generator/golden/testInnerClassNativesBothInnerAndOuterRegistrations.golden
+++ b/base/android/jni_generator/golden/testInnerClassNativesBothInnerAndOuterRegistrations.golden
@@ -14,7 +14,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/jni_generator/golden/testNativesRegistrations.golden b/base/android/jni_generator/golden/testNativesRegistrations.golden
index 3f1d8e2..4e3531e3 100644
--- a/base/android/jni_generator/golden/testNativesRegistrations.golden
+++ b/base/android/jni_generator/golden/testNativesRegistrations.golden
@@ -14,7 +14,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/jni_generator/golden/testProxyNativesMainDex.golden b/base/android/jni_generator/golden/testProxyNativesMainDex.golden
index bd9679b..d1f9a9d 100644
--- a/base/android/jni_generator/golden/testProxyNativesMainDex.golden
+++ b/base/android/jni_generator/golden/testProxyNativesMainDex.golden
@@ -14,7 +14,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/jni_generator/golden/testProxyNativesMainDexAndNonMainDex.golden b/base/android/jni_generator/golden/testProxyNativesMainDexAndNonMainDex.golden
index c6f6d0a7..0443c781 100644
--- a/base/android/jni_generator/golden/testProxyNativesMainDexAndNonMainDex.golden
+++ b/base/android/jni_generator/golden/testProxyNativesMainDexAndNonMainDex.golden
@@ -14,7 +14,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/jni_generator/golden/testProxyNativesRegistrations.golden b/base/android/jni_generator/golden/testProxyNativesRegistrations.golden
index f976834..bf1d1a7 100644
--- a/base/android/jni_generator/golden/testProxyNativesRegistrations.golden
+++ b/base/android/jni_generator/golden/testProxyNativesRegistrations.golden
@@ -14,7 +14,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/jni_generator/jni_registration_generator.py b/base/android/jni_generator/jni_registration_generator.py
index c6a98505..a21b89b 100755
--- a/base/android/jni_generator/jni_registration_generator.py
+++ b/base/android/jni_generator/jni_registration_generator.py
@@ -267,7 +267,7 @@
 
 #include "base/android/jni_generator/jni_generator_helper.h"
 #include "base/android/jni_int_wrapper.h"
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 
 // Step 1: Forward declarations (classes).
diff --git a/base/android/junit/src/org/chromium/base/PiiEliderTest.java b/base/android/junit/src/org/chromium/base/PiiEliderTest.java
index 47897a8..889476b 100644
--- a/base/android/junit/src/org/chromium/base/PiiEliderTest.java
+++ b/base/android/junit/src/org/chromium/base/PiiEliderTest.java
@@ -89,6 +89,13 @@
     }
 
     @Test
+    public void testElideNonHttpUrl() {
+        String original = "test some-other-scheme://address/01010?param=33&other_param=AAA !!!";
+        String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
+        assertEquals(expected, PiiElider.elideUrl(original));
+    }
+
+    @Test
     public void testDontElideFileSuffixes() {
         String original = "chromium_android_linker.so";
         assertEquals(original, PiiElider.elideUrl(original));
diff --git a/base/android/junit/src/org/chromium/base/library_loader/LinkerTest.java b/base/android/junit/src/org/chromium/base/library_loader/LinkerTest.java
new file mode 100644
index 0000000..f76d360
--- /dev/null
+++ b/base/android/junit/src/org/chromium/base/library_loader/LinkerTest.java
@@ -0,0 +1,61 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.library_loader;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+/**
+ *  Tests for {@link Linker}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+@SuppressWarnings("GuardedBy") // doNothing().when(...).methodLocked() cannot resolve |mLock|.
+public class LinkerTest {
+    @Mock
+    Linker.Natives mNativeMock;
+
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
+    @Before
+    public void setUp() {
+        Linker.setNativesForTesting(mNativeMock);
+    }
+
+    @After
+    public void tearDown() {
+        Linker.setNativesForTesting(null);
+    }
+
+    @Test
+    @SmallTest
+    public void testConsumer() {
+        Linker linker = Mockito.spy(new ModernLinker());
+
+        Mockito.doNothing().when(linker).loadLinkerJniLibraryLocked();
+
+        long someAddress = 1 << 12;
+        linker.initAsRelroConsumer(someAddress);
+
+        Mockito.verify(linker).keepMemoryReservationUntilLoad();
+        Mockito.verify(mNativeMock)
+                .reserveMemoryForLibrary(ArgumentMatchers.any(Linker.LibInfo.class));
+    }
+}
diff --git a/base/android/linker/linker_jni.cc b/base/android/linker/linker_jni.cc
index 7ffa6e9..8d84809 100644
--- a/base/android/linker/linker_jni.cc
+++ b/base/android/linker/linker_jni.cc
@@ -236,7 +236,7 @@
 
 // Performs as described in Linker.java.
 JNI_GENERATOR_EXPORT void
-Java_org_chromium_base_library_1loader_Linker_nativeFindMemoryRegionAtRandomAddress(
+Java_org_chromium_base_library_1loader_LinkerJni_nativeFindMemoryRegionAtRandomAddress(
     JNIEnv* env,
     jclass clazz,
     jobject lib_info_obj,
@@ -253,7 +253,7 @@
 
 // Performs as described in Linker.java.
 JNI_GENERATOR_EXPORT void
-Java_org_chromium_base_library_1loader_Linker_nativeReserveMemoryForLibrary(
+Java_org_chromium_base_library_1loader_LinkerJni_nativeReserveMemoryForLibrary(
     JNIEnv* env,
     jclass clazz,
     jobject lib_info_obj) {
diff --git a/base/bits.h b/base/bits.h
index a139a71..ffa4192 100644
--- a/base/bits.h
+++ b/base/bits.h
@@ -76,7 +76,10 @@
 //
 // C does not have an operator to do this, but fortunately the various
 // compilers have built-ins that map to fast underlying processor instructions.
-#if defined(COMPILER_MSVC)
+//
+// Prefer the clang path on Windows, as _BitScanReverse() and friends are not
+// constexpr.
+#if defined(COMPILER_MSVC) && !defined(__clang__)
 
 template <typename T, unsigned bits = sizeof(T) * 8>
 ALWAYS_INLINE
@@ -158,7 +161,7 @@
   return CountLeadingZeroBits(x);
 }
 
-#elif defined(COMPILER_GCC)
+#elif defined(COMPILER_GCC) || defined(__clang__)
 
 // __builtin_clz has undefined behaviour for an input of 0, even though there's
 // clearly a return value that makes sense, and even though some processor clz
diff --git a/base/containers/intrusive_heap_unittest.cc b/base/containers/intrusive_heap_unittest.cc
index 5db6d3b5..82df6dd 100644
--- a/base/containers/intrusive_heap_unittest.cc
+++ b/base/containers/intrusive_heap_unittest.cc
@@ -750,6 +750,18 @@
   EXPECT_EQ(2, heap.top().key);
 }
 
+TEST(IntrusiveHeapTest, MinDuplicates) {
+  IntrusiveHeap<TestElement> heap;
+
+  heap.insert({2, nullptr});
+  heap.insert({2, nullptr});
+  heap.insert({3, nullptr});
+
+  EXPECT_FALSE(heap.empty());
+  EXPECT_EQ(3u, heap.size());
+  EXPECT_EQ(2, heap.top().key);
+}
+
 TEST(IntrusiveHeapTest, InsertAscending) {
   IntrusiveHeap<TestElement> heap;
 
@@ -799,6 +811,23 @@
   EXPECT_FALSE(heap.empty());
 }
 
+TEST(IntrusiveHeapTest, HeapIndexDuplicates) {
+  HeapHandle index2;
+  HeapHandle index1;
+  IntrusiveHeap<TestElement> heap;
+
+  EXPECT_FALSE(index1.IsValid());
+  EXPECT_FALSE(index2.IsValid());
+
+  heap.insert({2, &index2});
+  heap.insert({2, &index1});
+
+  EXPECT_TRUE(index1.IsValid());
+  EXPECT_TRUE(index2.IsValid());
+
+  EXPECT_EQ(2U, heap.size());
+}
+
 TEST(IntrusiveHeapTest, Pop) {
   IntrusiveHeap<TestElement> heap;
   HeapHandle index1;
diff --git a/base/ios/ios_util.h b/base/ios/ios_util.h
index 8647f014..d3528dd 100644
--- a/base/ios/ios_util.h
+++ b/base/ios/ios_util.h
@@ -25,6 +25,10 @@
 // TODO(crbug.com/1129484): Remove once minimum supported version is at least 14
 BASE_EXPORT bool IsRunningOnIOS14OrLater();
 
+// Returns whether the operating system is iOS 15 or later.
+// TODO(crbug.com/1227419): Remove once minimum supported version is at least 15
+BASE_EXPORT bool IsRunningOnIOS15OrLater();
+
 // Returns whether the operating system is at the given version or later.
 BASE_EXPORT bool IsRunningOnOrLater(int32_t major,
                                     int32_t minor,
diff --git a/base/ios/ios_util.mm b/base/ios/ios_util.mm
index 6d36ec2..e3f864a 100644
--- a/base/ios/ios_util.mm
+++ b/base/ios/ios_util.mm
@@ -9,8 +9,8 @@
 
 #include <stddef.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
-#include "base/stl_util.h"
 #include "base/system/sys_info.h"
 
 namespace {
@@ -67,6 +67,11 @@
   return is_running_on_or_later;
 }
 
+bool IsRunningOnIOS15OrLater() {
+  static const bool is_running_on_or_later = IsRunningOnOrLater(15, 0, 0);
+  return is_running_on_or_later;
+}
+
 bool IsRunningOnOrLater(int32_t major, int32_t minor, int32_t bug_fix) {
   static const int32_t* current_version = OSVersionAsArray();
   int32_t version[] = {major, minor, bug_fix};
diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h
index 31f5fb1..363a7da 100644
--- a/base/json/json_value_converter.h
+++ b/base/json/json_value_converter.h
@@ -220,9 +220,7 @@
       : convert_func_(convert_func) {}
 
   bool Convert(const base::Value& value, FieldType* field) const override {
-    std::string string_value;
-    return value.GetAsString(&string_value) &&
-        convert_func_(string_value, field);
+    return value.is_string() && convert_func_(value.GetString(), field);
   }
 
  private:
diff --git a/base/location.cc b/base/location.cc
index 0af18ac..d6d6605 100644
--- a/base/location.cc
+++ b/base/location.cc
@@ -73,6 +73,7 @@
 
 Location::Location() = default;
 Location::Location(const Location& other) = default;
+Location& Location::operator=(const Location& other) = default;
 
 Location::Location(const char* file_name, const void* program_counter)
     : file_name_(file_name), program_counter_(program_counter) {}
diff --git a/base/location.h b/base/location.h
index f53fab8c..28a27b35 100644
--- a/base/location.h
+++ b/base/location.h
@@ -32,6 +32,7 @@
  public:
   Location();
   Location(const Location& other);
+  Location& operator=(const Location& other);
 
   // Only initializes the file name and program counter, the source information
   // will be null for the strings, and -1 for the line number.
diff --git a/base/mac/authorization_util.mm b/base/mac/authorization_util.mm
index cc5487b2..a679a3e 100644
--- a/base/mac/authorization_util.mm
+++ b/base/mac/authorization_util.mm
@@ -10,13 +10,13 @@
 
 #include <string>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/mac/bundle_locations.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_logging.h"
 #include "base/mac/scoped_authorizationref.h"
 #include "base/posix/eintr_wrapper.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm
index e63f0ec..622625b 100644
--- a/base/mac/foundation_util.mm
+++ b/base/mac/foundation_util.mm
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/mac/bundle_locations.h"
@@ -15,7 +16,6 @@
 #include "base/notreached.h"
 #include "base/numerics/checked_math.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
diff --git a/base/mac/foundation_util_unittest.mm b/base/mac/foundation_util_unittest.mm
index 677264b..40117cc 100644
--- a/base/mac/foundation_util_unittest.mm
+++ b/base/mac/foundation_util_unittest.mm
@@ -8,10 +8,10 @@
 #include <stddef.h>
 
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/format_macros.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm
index d21610aa..2463bcb 100644
--- a/base/mac/mac_util_unittest.mm
+++ b/base/mac/mac_util_unittest.mm
@@ -8,13 +8,13 @@
 
 #include "base/mac/mac_util.h"
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/stl_util.h"
 #include "base/system/sys_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/base/message_loop/message_pump_mac.mm b/base/message_loop/message_pump_mac.mm
index e58d77e..ebc9aa8 100644
--- a/base/message_loop/message_pump_mac.mm
+++ b/base/message_loop/message_pump_mac.mm
@@ -11,13 +11,13 @@
 
 #include "base/auto_reset.h"
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/mac/call_with_eh_frame.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 
diff --git a/base/process/process_info.h b/base/process/process_info.h
index 9bd2caca..b392e88 100644
--- a/base/process/process_info.h
+++ b/base/process/process_info.h
@@ -26,6 +26,9 @@
 // Determines whether the current process is elevated.
 BASE_EXPORT bool IsCurrentProcessElevated();
 
+// Determines whether the current process is running within an App Container.
+BASE_EXPORT bool IsCurrentProcessInAppContainer();
+
 #endif  // defined(OS_WIN)
 
 }  // namespace base
diff --git a/base/process/process_info_win.cc b/base/process/process_info_win.cc
index a08835ee..ebf1ebf1 100644
--- a/base/process/process_info_win.cc
+++ b/base/process/process_info_win.cc
@@ -83,4 +83,17 @@
   return !!elevation.TokenIsElevated;
 }
 
+bool IsCurrentProcessInAppContainer() {
+  base::win::ScopedHandle scoped_process_token(CreateCurrentProcessToken());
+
+  DWORD size;
+  DWORD appcontainer;
+  if (!GetTokenInformation(scoped_process_token.Get(), ::TokenIsAppContainer,
+                           &appcontainer, sizeof(appcontainer), &size)) {
+    PLOG(ERROR) << "GetTokenInformation() failed";
+    return false;
+  }
+  return !!appcontainer;
+}
+
 }  // namespace base
diff --git a/base/process/process_metrics.cc b/base/process/process_metrics.cc
index e91e83e0..d20ff34 100644
--- a/base/process/process_metrics.cc
+++ b/base/process/process_metrics.cc
@@ -42,7 +42,9 @@
 
 SystemMemoryInfoKB::SystemMemoryInfoKB() = default;
 
-SystemMemoryInfoKB::SystemMemoryInfoKB(const SystemMemoryInfoKB& other) =
+SystemMemoryInfoKB::SystemMemoryInfoKB(const SystemMemoryInfoKB&) = default;
+
+SystemMemoryInfoKB& SystemMemoryInfoKB::operator=(const SystemMemoryInfoKB&) =
     default;
 
 SystemMetrics::SystemMetrics() {
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h
index 2c059c0..7855d512 100644
--- a/base/process/process_metrics.h
+++ b/base/process/process_metrics.h
@@ -330,6 +330,7 @@
 struct BASE_EXPORT SystemMemoryInfoKB {
   SystemMemoryInfoKB();
   SystemMemoryInfoKB(const SystemMemoryInfoKB& other);
+  SystemMemoryInfoKB& operator=(const SystemMemoryInfoKB& other);
 
   // Serializes the platform specific fields to value.
   Value ToValue() const;
@@ -446,7 +447,8 @@
 // Data from /proc/diskstats about system-wide disk I/O.
 struct BASE_EXPORT SystemDiskInfo {
   SystemDiskInfo();
-  SystemDiskInfo(const SystemDiskInfo& other);
+  SystemDiskInfo(const SystemDiskInfo&);
+  SystemDiskInfo& operator=(const SystemDiskInfo&);
 
   // Serializes the platform specific fields to value.
   Value ToValue() const;
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc
index 3b32001..81cfc63 100644
--- a/base/process/process_metrics_linux.cc
+++ b/base/process/process_metrics_linux.cc
@@ -717,7 +717,9 @@
   weighted_io_time = 0;
 }
 
-SystemDiskInfo::SystemDiskInfo(const SystemDiskInfo& other) = default;
+SystemDiskInfo::SystemDiskInfo(const SystemDiskInfo&) = default;
+
+SystemDiskInfo& SystemDiskInfo::operator=(const SystemDiskInfo&) = default;
 
 Value SystemDiskInfo::ToValue() const {
   Value res(Value::Type::DICTIONARY);
diff --git a/base/rand_util.h b/base/rand_util.h
index 8414016..2dff3570 100644
--- a/base/rand_util.h
+++ b/base/rand_util.h
@@ -15,6 +15,13 @@
 #include "base/gtest_prod_util.h"
 #include "build/build_config.h"
 
+namespace blink {
+namespace scheduler {
+class UkmTaskSampler;
+class MainThreadMetricsHelper;
+}
+}  // namespace blink
+
 namespace base {
 
 // Returns a random number in range [0, UINT64_MAX]. Thread-safe.
@@ -139,11 +146,14 @@
   // need a secure PRNG, as it's used for ASLR and zeroing some allocations at
   // free() time.
   friend class partition_alloc::RandomGenerator;
-  // The random number generator is used to sub-sample metrics at each task
-  // execution. Task execution overhead is <1us, and is already showing as a
-  // non-trivial amount of total CPU time in sampling profiling from the wild,
-  // on Desktop and Android.
+
+  // Friend classes below are using the generator to sub-sample metrics after
+  // task execution. Task execution overhead is ~1us on a Linux desktop, and yet
+  // accounts for multiple percentage points of total CPU usage. Keeping it low
+  // is thus important.
   friend class sequence_manager::internal::SequenceManagerImpl;
+  friend class blink::scheduler::UkmTaskSampler;
+  friend class blink::scheduler::MainThreadMetricsHelper;
 
   FRIEND_TEST_ALL_PREFIXES(RandUtilTest,
                            InsecureRandomGeneratorProducesBothValuesOfAllBits);
diff --git a/base/system/sys_info_ios.mm b/base/system/sys_info_ios.mm
index 3e03c1b2..3bb3fd5 100644
--- a/base/system/sys_info_ios.mm
+++ b/base/system/sys_info_ios.mm
@@ -12,10 +12,10 @@
 #include <sys/types.h>
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/notreached.h"
 #include "base/process/process_metrics.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
diff --git a/base/system/sys_info_mac.mm b/base/system/sys_info_mac.mm
index 9c2a338..c67480e 100644
--- a/base/system/sys_info_mac.mm
+++ b/base/system/sys_info_mac.mm
@@ -13,11 +13,11 @@
 #include <sys/types.h>
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/notreached.h"
 #include "base/process/process_metrics.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc
index 396827d3..6bad341 100644
--- a/base/task/sequence_manager/task_queue_impl.cc
+++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -548,8 +548,7 @@
           : WakeUpResolution::kLow;
 
   const auto& top_task = main_thread_only().delayed_incoming_queue.top();
-  return DelayedWakeUp{top_task.delayed_run_time, top_task.sequence_num,
-                       resolution};
+  return DelayedWakeUp{top_task.delayed_run_time, resolution};
 }
 
 absl::optional<TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() {
diff --git a/base/task/sequence_manager/tasks.cc b/base/task/sequence_manager/tasks.cc
index 8fb2187..4c222b0 100644
--- a/base/task/sequence_manager/tasks.cc
+++ b/base/task/sequence_manager/tasks.cc
@@ -11,7 +11,7 @@
            TimeTicks delayed_run_time,
            EnqueueOrder sequence_order,
            EnqueueOrder enqueue_order,
-           internal::WakeUpResolution resolution)
+           WakeUpResolution resolution)
     : PendingTask(posted_task.location,
                   std::move(posted_task.callback),
                   posted_task.queue_time,
@@ -20,13 +20,13 @@
       task_type(posted_task.task_type),
       task_runner(std::move(posted_task.task_runner)),
       enqueue_order_(enqueue_order) {
-  // We use |sequence_num| in DelayedWakeUp for ordering purposes and it
-  // may wrap around to a negative number during the static cast, hence,
-  // the relevant code is especially sensitive to a potential change of
-  // |PendingTask::sequence_num|'s type.
+  // We use |sequence_num| when comparing PendingTask for ordering purposes
+  // and it may wrap around to a negative number during the static cast, hence,
+  // TaskQueueImpl::DelayedIncomingQueue is especially sensitive to a potential
+  // change of |PendingTask::sequence_num|'s type.
   static_assert(std::is_same<decltype(sequence_num), int>::value, "");
   sequence_num = static_cast<int>(sequence_order);
-  this->is_high_res = resolution == internal::WakeUpResolution::kHigh;
+  this->is_high_res = resolution == WakeUpResolution::kHigh;
 }
 
 Task::Task(Task&& move_from) = default;
diff --git a/base/task/sequence_manager/tasks.h b/base/task/sequence_manager/tasks.h
index 3e548b0..e6694e1e 100644
--- a/base/task/sequence_manager/tasks.h
+++ b/base/task/sequence_manager/tasks.h
@@ -17,8 +17,6 @@
 
 namespace internal {
 
-enum class WakeUpResolution { kLow, kHigh };
-
 // Wrapper around PostTask method arguments and the assigned task type.
 // Eventually it becomes a PendingTask once accepted by a TaskQueueImpl.
 struct BASE_EXPORT PostedTask {
@@ -45,16 +43,17 @@
   TimeTicks queue_time;
 };
 
-// Represents a time at which a task wants to run. Tasks scheduled for the
-// same point in time will be ordered by their sequence numbers.
+}  // namespace internal
+
+enum class WakeUpResolution { kLow, kHigh };
+
+// Represents a time at which a task wants to run.
 struct DelayedWakeUp {
   TimeTicks time;
-  int sequence_num;
   WakeUpResolution resolution;
 
   bool operator!=(const DelayedWakeUp& other) const {
-    return time != other.time || other.sequence_num != sequence_num ||
-           resolution != other.resolution;
+    return time != other.time || resolution != other.resolution;
   }
 
   bool operator==(const DelayedWakeUp& other) const {
@@ -63,34 +62,22 @@
 
   bool operator<=(const DelayedWakeUp& other) const {
     if (time == other.time) {
-      if (sequence_num == other.sequence_num) {
-        if (resolution == other.resolution) {
-          // Debug gcc builds can compare an element against itself.
-          DCHECK_EQ(this, &other);
-          return true;
-        }
+      if (resolution == other.resolution)
+        return true;
 
-        return resolution < other.resolution;
-      }
-
-      // |sequence_num| is int and might wrap around to a negative number when
-      // casted from EnqueueOrder. This way of comparison handles that properly.
-      return (sequence_num - other.sequence_num) < 0;
+      return resolution < other.resolution;
     }
     return time < other.time;
   }
 };
 
-}  // namespace internal
-
 // PendingTask with extra metadata for SequenceManager.
 struct BASE_EXPORT Task : public PendingTask {
   Task(internal::PostedTask posted_task,
        TimeTicks delayed_run_time,
        EnqueueOrder sequence_order,
        EnqueueOrder enqueue_order = EnqueueOrder(),
-       internal::WakeUpResolution wake_up_resolution =
-           internal::WakeUpResolution::kLow);
+       WakeUpResolution wake_up_resolution = WakeUpResolution::kLow);
   Task(Task&& move_from);
   ~Task();
   Task& operator=(Task&& other);
diff --git a/base/task/sequence_manager/test/fake_task.cc b/base/task/sequence_manager/test/fake_task.cc
index 1199bb9..f664904a 100644
--- a/base/task/sequence_manager/test/fake_task.cc
+++ b/base/task/sequence_manager/test/fake_task.cc
@@ -19,7 +19,7 @@
            TimeTicks(),
            EnqueueOrder(),
            EnqueueOrder(),
-           internal::WakeUpResolution::kLow) {}
+           WakeUpResolution::kLow) {}
 
 FakeTaskTiming::FakeTaskTiming()
     : TaskTiming(false /* has_wall_time */, false /* has_thread_time */) {}
diff --git a/base/task/sequence_manager/time_domain.cc b/base/task/sequence_manager/time_domain.cc
index af2826ca..80f62f26 100644
--- a/base/task/sequence_manager/time_domain.cc
+++ b/base/task/sequence_manager/time_domain.cc
@@ -54,16 +54,15 @@
   SetNextWakeUpForQueue(queue, absl::nullopt, &lazy_now);
 }
 
-void TimeDomain::SetNextWakeUpForQueue(
-    internal::TaskQueueImpl* queue,
-    absl::optional<internal::DelayedWakeUp> wake_up,
-    LazyNow* lazy_now) {
+void TimeDomain::SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
+                                       absl::optional<DelayedWakeUp> wake_up,
+                                       LazyNow* lazy_now) {
   DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
   DCHECK_EQ(queue->GetTimeDomain(), this);
   DCHECK(queue->IsQueueEnabled() || !wake_up);
 
   absl::optional<TimeTicks> previous_wake_up;
-  absl::optional<internal::WakeUpResolution> previous_queue_resolution;
+  absl::optional<WakeUpResolution> previous_queue_resolution;
   if (!delayed_wake_up_queue_.empty())
     previous_wake_up = delayed_wake_up_queue_.Min().wake_up.time;
   if (queue->heap_handle().IsValid()) {
@@ -92,10 +91,10 @@
     new_wake_up = delayed_wake_up_queue_.Min().wake_up.time;
 
   if (previous_queue_resolution &&
-      *previous_queue_resolution == internal::WakeUpResolution::kHigh) {
+      *previous_queue_resolution == WakeUpResolution::kHigh) {
     pending_high_res_wake_up_count_--;
   }
-  if (wake_up && wake_up->resolution == internal::WakeUpResolution::kHigh)
+  if (wake_up && wake_up->resolution == WakeUpResolution::kHigh)
     pending_high_res_wake_up_count_++;
   DCHECK_GE(pending_high_res_wake_up_count_, 0);
 
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h
index b065a3f..002bc71 100644
--- a/base/task/sequence_manager/time_domain.h
+++ b/base/task/sequence_manager/time_domain.h
@@ -110,7 +110,7 @@
   // Nullopt |wake_up| cancels a previously set wake up for |queue|.
   // NOTE: |lazy_now| is provided in TimeDomain's time.
   void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
-                             absl::optional<internal::DelayedWakeUp> wake_up,
+                             absl::optional<DelayedWakeUp> wake_up,
                              LazyNow* lazy_now);
 
   // Remove the TaskQueue from any internal data sctructures.
@@ -121,7 +121,7 @@
   void MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now);
 
   struct ScheduledDelayedWakeUp {
-    internal::DelayedWakeUp wake_up;
+    DelayedWakeUp wake_up;
     internal::TaskQueueImpl* queue;
 
     bool operator<=(const ScheduledDelayedWakeUp& other) const {
diff --git a/base/task/sequence_manager/time_domain_unittest.cc b/base/task/sequence_manager/time_domain_unittest.cc
index 7856fd6..09488e9c 100644
--- a/base/task/sequence_manager/time_domain_unittest.cc
+++ b/base/task/sequence_manager/time_domain_unittest.cc
@@ -104,8 +104,7 @@
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, delayed_runtime));
   TimeTicks now = time_domain_->Now();
   LazyNow lazy_now(now);
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{now + delay, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{now + delay});
 
   EXPECT_FALSE(time_domain_->empty());
   EXPECT_EQ(delayed_runtime, time_domain_->NextScheduledRunTime());
@@ -125,8 +124,7 @@
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, delayed_runtime1));
   TimeTicks now = time_domain_->Now();
   LazyNow lazy_now(now);
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{delayed_runtime1, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{delayed_runtime1});
 
   EXPECT_EQ(delayed_runtime1, time_domain_->NextScheduledRunTime());
 
@@ -135,8 +133,7 @@
   // Now schedule a later wake_up, which should replace the previously
   // requested one.
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, delayed_runtime2));
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{delayed_runtime2, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{delayed_runtime2});
 
   EXPECT_EQ(delayed_runtime2, time_domain_->NextScheduledRunTime());
   Mock::VerifyAndClearExpectations(time_domain_.get());
@@ -168,23 +165,19 @@
   TimeTicks now = time_domain_->Now();
   LazyNow lazy_now(now);
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, now + delay1));
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{now + delay1, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{now + delay1});
 
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   // SetNextDelayedDoWork should not be called when scheduling later tasks.
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, _)).Times(0);
-  task_queue2->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{now + delay2, 0});
-  task_queue3->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{now + delay3, 0});
+  task_queue2->SetDelayedWakeUpForTesting(DelayedWakeUp{now + delay2});
+  task_queue3->SetDelayedWakeUpForTesting(DelayedWakeUp{now + delay3});
 
   // SetNextDelayedDoWork should be called when scheduling earlier tasks.
   Mock::VerifyAndClearExpectations(time_domain_.get());
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, now + delay4));
-  task_queue4->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{now + delay4, 0});
+  task_queue4->SetDelayedWakeUpForTesting(DelayedWakeUp{now + delay4});
 
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
@@ -204,9 +197,9 @@
   LazyNow lazy_now(now);
   TimeTicks wake_up1 = now + TimeDelta::FromMilliseconds(10);
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, wake_up1)).Times(1);
-  task_queue_->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up1, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{wake_up1});
   TimeTicks wake_up2 = now + TimeDelta::FromMilliseconds(100);
-  task_queue2->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{wake_up2, 0});
+  task_queue2->SetDelayedWakeUpForTesting(DelayedWakeUp{wake_up2});
   EXPECT_FALSE(time_domain_->empty());
 
   EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue());
@@ -241,8 +234,7 @@
   LazyNow lazy_now_1(now);
   TimeTicks delayed_runtime = now + delay;
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, delayed_runtime));
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{delayed_runtime, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{delayed_runtime});
 
   EXPECT_EQ(delayed_runtime, time_domain_->NextScheduledRunTime());
 
@@ -256,40 +248,13 @@
   ASSERT_FALSE(time_domain_->NextScheduledRunTime());
 }
 
-TEST_F(TimeDomainTest, MoveReadyDelayedTasksToWorkQueuesWithIdenticalRuntimes) {
-  int sequence_num = 0;
-  TimeDelta delay = TimeDelta::FromMilliseconds(50);
-  TimeTicks now = time_domain_->Now();
-  LazyNow lazy_now(now);
-  TimeTicks delayed_runtime = now + delay;
-  EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, delayed_runtime));
-  EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, TimeTicks::Max()));
-
-  std::unique_ptr<TaskQueueImplForTest> task_queue2 =
-      std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(),
-                                             TaskQueue::Spec("test"));
-
-  task_queue2->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{delayed_runtime, ++sequence_num});
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{delayed_runtime, ++sequence_num});
-
-  time_domain_->MoveReadyDelayedTasksToWorkQueues(&lazy_now);
-
-  // The second task queue should wake up first since it has a lower sequence
-  // number.
-  EXPECT_EQ(task_queue2.get(), time_domain_->NextScheduledTaskQueue());
-
-  task_queue2->UnregisterTaskQueue();
-}
-
 TEST_F(TimeDomainTest, CancelDelayedWork) {
   TimeTicks now = time_domain_->Now();
   LazyNow lazy_now(now);
   TimeTicks run_time = now + TimeDelta::FromMilliseconds(20);
 
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, run_time));
-  task_queue_->SetDelayedWakeUpForTesting(internal::DelayedWakeUp{run_time, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{run_time});
 
   EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue());
 
@@ -308,13 +273,11 @@
   TimeTicks run_time1 = now + TimeDelta::FromMilliseconds(20);
   TimeTicks run_time2 = now + TimeDelta::FromMilliseconds(40);
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, run_time1));
-  task_queue_->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{run_time1, 0});
+  task_queue_->SetDelayedWakeUpForTesting(DelayedWakeUp{run_time1});
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   EXPECT_CALL(*time_domain_.get(), SetNextDelayedDoWork(_, _)).Times(0);
-  task_queue2->SetDelayedWakeUpForTesting(
-      internal::DelayedWakeUp{run_time2, 0});
+  task_queue2->SetDelayedWakeUpForTesting(DelayedWakeUp{run_time2});
   Mock::VerifyAndClearExpectations(time_domain_.get());
 
   EXPECT_EQ(task_queue_.get(), time_domain_->NextScheduledTaskQueue());
@@ -346,14 +309,10 @@
   // Add two high resolution wake-ups.
   EXPECT_FALSE(time_domain_->has_pending_high_resolution_tasks());
   time_domain_->SetNextWakeUpForQueue(
-      &q1,
-      internal::DelayedWakeUp{run_time1, 0, internal::WakeUpResolution::kHigh},
-      &lazy_now);
+      &q1, DelayedWakeUp{run_time1, WakeUpResolution::kHigh}, &lazy_now);
   EXPECT_TRUE(time_domain_->has_pending_high_resolution_tasks());
   time_domain_->SetNextWakeUpForQueue(
-      &q2,
-      internal::DelayedWakeUp{run_time2, 0, internal::WakeUpResolution::kHigh},
-      &lazy_now);
+      &q2, DelayedWakeUp{run_time2, WakeUpResolution::kHigh}, &lazy_now);
   EXPECT_TRUE(time_domain_->has_pending_high_resolution_tasks());
 
   // Remove one of the wake-ups.
@@ -366,21 +325,15 @@
 
   // Change a low resolution wake-up to a high resolution one.
   time_domain_->SetNextWakeUpForQueue(
-      &q1,
-      internal::DelayedWakeUp{run_time1, 0, internal::WakeUpResolution::kLow},
-      &lazy_now);
+      &q1, DelayedWakeUp{run_time1, WakeUpResolution::kLow}, &lazy_now);
   EXPECT_FALSE(time_domain_->has_pending_high_resolution_tasks());
   time_domain_->SetNextWakeUpForQueue(
-      &q1,
-      internal::DelayedWakeUp{run_time1, 0, internal::WakeUpResolution::kHigh},
-      &lazy_now);
+      &q1, DelayedWakeUp{run_time1, WakeUpResolution::kHigh}, &lazy_now);
   EXPECT_TRUE(time_domain_->has_pending_high_resolution_tasks());
 
   // Move a high resolution wake-up in time.
   time_domain_->SetNextWakeUpForQueue(
-      &q1,
-      internal::DelayedWakeUp{run_time2, 0, internal::WakeUpResolution::kHigh},
-      &lazy_now);
+      &q1, DelayedWakeUp{run_time2, WakeUpResolution::kHigh}, &lazy_now);
   EXPECT_TRUE(time_domain_->has_pending_high_resolution_tasks());
 
   // Cancel the wake-up twice.
diff --git a/base/test/gtest_util.cc b/base/test/gtest_util.cc
index 6937db8..5a1e957 100644
--- a/base/test/gtest_util.cc
+++ b/base/test/gtest_util.cc
@@ -20,6 +20,9 @@
 
 TestIdentifier::TestIdentifier(const TestIdentifier& other) = default;
 
+TestIdentifier& TestIdentifier::operator=(const TestIdentifier& other) =
+    default;
+
 std::string FormatFullTestName(const std::string& test_case_name,
                                const std::string& test_name) {
   return test_case_name + "." + test_name;
diff --git a/base/test/gtest_util.h b/base/test/gtest_util.h
index 3d3d7746..8e1d69289 100644
--- a/base/test/gtest_util.h
+++ b/base/test/gtest_util.h
@@ -76,6 +76,7 @@
 struct TestIdentifier {
   TestIdentifier();
   TestIdentifier(const TestIdentifier& other);
+  TestIdentifier& operator=(const TestIdentifier& other);
 
   std::string test_case_name;
   std::string test_name;
diff --git a/base/time/time_mac.mm b/base/time/time_mac.mm
index a04719ac..4ea1a6c 100644
--- a/base/time/time_mac.mm
+++ b/base/time/time_mac.mm
@@ -14,13 +14,13 @@
 #include <sys/types.h>
 #include <time.h>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/mac/mach_logging.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/stl_util.h"
 #include "base/time/time_override.h"
 #include "build/build_config.h"
 
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc
index aad17ddd..34c785a 100644
--- a/base/trace_event/trace_event_memory_overhead.cc
+++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -104,10 +104,8 @@
       break;
 
     case Value::Type::STRING: {
-      const Value* string_value = nullptr;
-      value.GetAsString(&string_value);
       Add(kBaseValue, sizeof(Value));
-      AddString(string_value->GetString());
+      AddString(value.GetString());
     } break;
 
     case Value::Type::BINARY: {
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 381b3d0..c43bce7 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -18,6 +18,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/containers/cxx20_erase_vector.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/location.h"
@@ -27,6 +28,7 @@
 #include "base/memory/singleton.h"
 #include "base/process/process_handle.h"
 #include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
 #include "base/strings/pattern.h"
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/waitable_event.h"
@@ -79,23 +81,25 @@
 
 class TraceEventTestFixture : public testing::Test {
  public:
+  TraceEventTestFixture() : trace_parsed_(Value::Type::LIST) {}
+
   void OnTraceDataCollected(
       WaitableEvent* flush_complete_event,
       const scoped_refptr<base::RefCountedString>& events_str,
       bool has_more_events);
-  DictionaryValue* FindMatchingTraceEntry(const JsonKeyValue* key_values);
-  DictionaryValue* FindNamePhase(const char* name, const char* phase);
-  DictionaryValue* FindNamePhaseKeyValue(const char* name,
-                                         const char* phase,
-                                         const char* key,
-                                         const char* value);
+  const Value* FindMatchingTraceEntry(const JsonKeyValue* key_values);
+  const Value* FindNamePhase(const char* name, const char* phase);
+  const Value* FindNamePhaseKeyValue(const char* name,
+                                     const char* phase,
+                                     const char* key,
+                                     const char* value);
   void DropTracedMetadataRecords();
   bool FindMatchingValue(const char* key,
                          const char* value);
   bool FindNonMatchingValue(const char* key,
                             const char* value);
   void Clear() {
-    trace_parsed_.Clear();
+    trace_parsed_ = Value(Value::Type::LIST);
     json_output_.json_output.clear();
   }
 
@@ -178,7 +182,7 @@
   }
 
   char* old_thread_name_;
-  ListValue trace_parsed_;
+  Value trace_parsed_;
   TraceResultBuffer trace_buffer_;
   TraceResultBuffer::SimpleOutput json_output_;
   size_t num_flush_callbacks_;
@@ -203,22 +207,22 @@
   trace_buffer_.AddFragment(events_str->data());
   trace_buffer_.Finish();
 
-  std::unique_ptr<Value> root = base::JSONReader::ReadDeprecated(
-      json_output_.json_output, JSON_PARSE_RFC);
+  absl::optional<Value> root =
+      base::JSONReader::Read(json_output_.json_output, JSON_PARSE_RFC);
 
-  if (!root.get()) {
+  if (!root.has_value()) {
     LOG(ERROR) << json_output_.json_output;
   }
 
-  ListValue* root_list = nullptr;
-  ASSERT_TRUE(root.get());
-  ASSERT_TRUE(root->GetAsList(&root_list));
+  ASSERT_TRUE(root->is_list());
+  Value::ListStorage root_storage = std::move(*root).TakeList();
 
   // Move items into our aggregate collection
-  for (Value& item : root_list->GetList()) {
-    trace_parsed_.Append(std::move(item));
-  }
-  root_list->ClearList();
+  Value::ListStorage storage = std::move(trace_parsed_).TakeList();
+  storage.reserve(storage.size() + root_storage.size());
+  std::move(root_storage.begin(), root_storage.end(),
+            std::back_inserter(storage));
+  trace_parsed_ = Value(std::move(storage));
 
   if (!has_more_events)
     flush_complete_event->Signal();
@@ -238,18 +242,14 @@
   return false;
 }
 
-static bool IsKeyValueInDict(const JsonKeyValue* key_value,
-                             DictionaryValue* dict) {
-  Value* value = nullptr;
-  std::string value_str;
-  if (dict->Get(key_value->key, &value) &&
-      value->GetAsString(&value_str) &&
-      CompareJsonValues(value_str, key_value->value, key_value->op))
+static bool IsKeyValueInDict(const JsonKeyValue* key_value, const Value* dict) {
+  const std::string* value_str = dict->FindStringPath(key_value->key);
+  if (value_str &&
+      CompareJsonValues(*value_str, key_value->value, key_value->op))
     return true;
 
   // Recurse to test arguments
-  DictionaryValue* args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  const Value* args_dict = dict->FindDictPath("args");
   if (args_dict)
     return IsKeyValueInDict(key_value, args_dict);
 
@@ -257,7 +257,7 @@
 }
 
 static bool IsAllKeyValueInDict(const JsonKeyValue* key_values,
-                                DictionaryValue* dict) {
+                                const Value* dict) {
   // Scan all key_values, they must all be present and equal.
   while (key_values && key_values->key) {
     if (!IsKeyValueInDict(key_values, dict))
@@ -267,50 +267,42 @@
   return true;
 }
 
-DictionaryValue* TraceEventTestFixture::FindMatchingTraceEntry(
+const Value* TraceEventTestFixture::FindMatchingTraceEntry(
     const JsonKeyValue* key_values) {
   // Scan all items
-  size_t trace_parsed_count = trace_parsed_.GetSize();
-  for (size_t i = 0; i < trace_parsed_count; i++) {
-    Value* value = nullptr;
-    trace_parsed_.Get(i, &value);
-    if (!value || value->type() != Value::Type::DICTIONARY)
+  for (const Value& value : trace_parsed_.GetList()) {
+    if (!value.is_dict())
       continue;
-    DictionaryValue* dict = static_cast<DictionaryValue*>(value);
 
-    if (IsAllKeyValueInDict(key_values, dict))
-      return dict;
+    if (IsAllKeyValueInDict(key_values, &value))
+      return &value;
   }
   return nullptr;
 }
 
 void TraceEventTestFixture::DropTracedMetadataRecords() {
-  base::Value old_trace_parsed = trace_parsed_.Clone();
-  trace_parsed_.Clear();
-
-  for (const auto& value : old_trace_parsed.GetList()) {
-    if (value.type() == Value::Type::DICTIONARY) {
-      const std::string* tmp = value.FindStringKey("ph");
-      if (tmp != nullptr && *tmp == "M")
-        continue;
-    }
-    trace_parsed_.Append(value.Clone());
-  }
+  Value::ListStorage storage = std::move(trace_parsed_).TakeList();
+  base::EraseIf(storage, [](const Value& value) {
+    if (!value.is_dict())
+      return false;
+    const std::string* ph = value.FindStringKey("ph");
+    return ph && *ph == "M";
+  });
+  trace_parsed_ = Value(std::move(storage));
 }
 
-DictionaryValue* TraceEventTestFixture::FindNamePhase(const char* name,
-                                                      const char* phase) {
+const Value* TraceEventTestFixture::FindNamePhase(const char* name,
+                                                  const char* phase) {
   JsonKeyValue key_values[] = {{"name", name, IS_EQUAL},
                                {"ph", phase, IS_EQUAL},
                                {nullptr, nullptr, IS_EQUAL}};
   return FindMatchingTraceEntry(key_values);
 }
 
-DictionaryValue* TraceEventTestFixture::FindNamePhaseKeyValue(
-    const char* name,
-    const char* phase,
-    const char* key,
-    const char* value) {
+const Value* TraceEventTestFixture::FindNamePhaseKeyValue(const char* name,
+                                                          const char* phase,
+                                                          const char* key,
+                                                          const char* value) {
   JsonKeyValue key_values[] = {{"name", name, IS_EQUAL},
                                {"ph", phase, IS_EQUAL},
                                {key, value, IS_EQUAL},
@@ -332,64 +324,54 @@
   return FindMatchingTraceEntry(key_values);
 }
 
-bool IsStringInDict(const char* string_to_match, const DictionaryValue* dict) {
-  for (DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
-    if (it.key().find(string_to_match) != std::string::npos)
+bool IsStringInDict(const char* string_to_match, const Value* dict) {
+  for (const auto& pair : dict->DictItems()) {
+    if (pair.first.find(string_to_match) != std::string::npos)
       return true;
 
-    std::string value_str;
-    it.value().GetAsString(&value_str);
-    if (value_str.find(string_to_match) != std::string::npos)
+    if (!pair.second.is_string())
+      continue;
+
+    if (pair.second.GetString().find(string_to_match) != std::string::npos)
       return true;
   }
 
   // Recurse to test arguments
-  const DictionaryValue* args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  const Value* args_dict = dict->FindDictKey("args");
   if (args_dict)
     return IsStringInDict(string_to_match, args_dict);
 
   return false;
 }
 
-const DictionaryValue* FindTraceEntry(
-    const ListValue& trace_parsed,
-    const char* string_to_match,
-    const DictionaryValue* match_after_this_item = nullptr) {
+const Value* FindTraceEntry(const Value& trace_parsed,
+                            const char* string_to_match,
+                            const Value* match_after_this_item = nullptr) {
   // Scan all items
-  size_t trace_parsed_count = trace_parsed.GetSize();
-  for (size_t i = 0; i < trace_parsed_count; i++) {
-    const Value* value = nullptr;
-    trace_parsed.Get(i, &value);
+  for (const Value& value : trace_parsed.GetList()) {
     if (match_after_this_item) {
-      if (value == match_after_this_item)
+      if (&value == match_after_this_item)
         match_after_this_item = nullptr;
       continue;
     }
-    if (!value || value->type() != Value::Type::DICTIONARY)
+    if (!value.is_dict())
       continue;
-    const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
 
-    if (IsStringInDict(string_to_match, dict))
-      return dict;
+    if (IsStringInDict(string_to_match, &value))
+      return &value;
   }
   return nullptr;
 }
 
-std::vector<const DictionaryValue*> FindTraceEntries(
-    const ListValue& trace_parsed,
-    const char* string_to_match) {
-  std::vector<const DictionaryValue*> hits;
-  size_t trace_parsed_count = trace_parsed.GetSize();
-  for (size_t i = 0; i < trace_parsed_count; i++) {
-    const Value* value = nullptr;
-    trace_parsed.Get(i, &value);
-    if (!value || value->type() != Value::Type::DICTIONARY)
+std::vector<const Value*> FindTraceEntries(const Value& trace_parsed,
+                                           const char* string_to_match) {
+  std::vector<const Value*> hits;
+  for (const Value& value : trace_parsed.GetList()) {
+    if (!value.is_dict())
       continue;
-    const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
 
-    if (IsStringInDict(string_to_match, dict))
-      hits.push_back(dict);
+    if (IsStringInDict(string_to_match, &value))
+      hits.push_back(&value);
   }
   return hits;
 }
@@ -518,8 +500,8 @@
     task_complete_event->Signal();
 }
 
-void ValidateAllTraceMacrosCreatedData(const ListValue& trace_parsed) {
-  const DictionaryValue* item = nullptr;
+void ValidateAllTraceMacrosCreatedData(const Value& trace_parsed) {
+  const Value* item = nullptr;
 
 #define EXPECT_FIND_(string) \
     item = FindTraceEntry(trace_parsed, string); \
@@ -533,11 +515,8 @@
 
   EXPECT_FIND_("TRACE_EVENT0 call");
   {
-    std::string ph;
-    std::string ph_end;
     EXPECT_TRUE((item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call")));
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("X", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "X");
     item = FindTraceEntry(trace_parsed, "TRACE_EVENT0 call", item);
     EXPECT_FALSE(item);
   }
@@ -551,25 +530,13 @@
   EXPECT_SUB_FIND_("value\\2");
 
   EXPECT_FIND_("TRACE_EVENT_INSTANT0 call");
-  {
-    std::string scope;
-    EXPECT_TRUE((item && item->GetString("s", &scope)));
-    EXPECT_EQ("g", scope);
-  }
+  { EXPECT_EQ(*item->FindStringKey("s"), "g"); }
   EXPECT_FIND_("TRACE_EVENT_INSTANT1 call");
-  {
-    std::string scope;
-    EXPECT_TRUE((item && item->GetString("s", &scope)));
-    EXPECT_EQ("p", scope);
-  }
+  { EXPECT_EQ(*item->FindStringKey("s"), "p"); }
   EXPECT_SUB_FIND_("name1");
   EXPECT_SUB_FIND_("value1");
   EXPECT_FIND_("TRACE_EVENT_INSTANT2 call");
-  {
-    std::string scope;
-    EXPECT_TRUE((item && item->GetString("s", &scope)));
-    EXPECT_EQ("t", scope);
-  }
+  { EXPECT_EQ(*item->FindStringKey("s"), "t"); }
   EXPECT_SUB_FIND_("name1");
   EXPECT_SUB_FIND_("value1");
   EXPECT_SUB_FIND_("name2");
@@ -633,117 +600,76 @@
 
   EXPECT_FIND_("TRACE_COUNTER1 call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
-    EXPECT_EQ(31415, value);
+    EXPECT_EQ(*item->FindIntPath("args.value"), 31415);
   }
 
   EXPECT_FIND_("TRACE_COUNTER2 call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
-    EXPECT_EQ(30000, value);
+    EXPECT_EQ(*item->FindIntPath("args.a"), 30000);
 
-    EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
-    EXPECT_EQ(1415, value);
+    EXPECT_EQ(*item->FindIntPath("args.b"), 1415);
   }
 
   EXPECT_FIND_("TRACE_COUNTER_WITH_TIMESTAMP1 call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
-    EXPECT_EQ(31415, value);
+    EXPECT_EQ(*item->FindIntPath("args.value"), 31415);
 
-    int ts;
-    EXPECT_TRUE((item && item->GetInteger("ts", &ts)));
-    EXPECT_EQ(42, ts);
+    EXPECT_EQ(*item->FindIntKey("ts"), 42);
   }
 
   EXPECT_FIND_("TRACE_COUNTER_WITH_TIMESTAMP2 call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
-    EXPECT_EQ(30000, value);
+    EXPECT_EQ(*item->FindIntPath("args.a"), 30000);
 
-    EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
-    EXPECT_EQ(1415, value);
+    EXPECT_EQ(*item->FindIntPath("args.b"), 1415);
 
-    int ts;
-    EXPECT_TRUE((item && item->GetInteger("ts", &ts)));
-    EXPECT_EQ(42, ts);
+    EXPECT_EQ(*item->FindIntKey("ts"), 42);
   }
 
   EXPECT_FIND_("TRACE_COUNTER_ID1 call");
   {
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x319009", id);
+    EXPECT_EQ(*item->FindStringKey("id"), "0x319009");
 
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.value", &value)));
-    EXPECT_EQ(31415, value);
+    EXPECT_EQ(*item->FindIntPath("args.value"), 31415);
   }
 
   EXPECT_FIND_("TRACE_COUNTER_ID2 call");
   {
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x319009", id);
+    EXPECT_EQ(*item->FindStringKey("id"), "0x319009");
 
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("C", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "C");
 
-    int value;
-    EXPECT_TRUE((item && item->GetInteger("args.a", &value)));
-    EXPECT_EQ(30000, value);
+    EXPECT_EQ(*item->FindIntPath("args.a"), 30000);
 
-    EXPECT_TRUE((item && item->GetInteger("args.b", &value)));
-    EXPECT_EQ(1415, value);
+    EXPECT_EQ(*item->FindIntPath("args.b"), 1415);
   }
 
   EXPECT_FIND_("TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call");
   {
-    int val;
-    EXPECT_TRUE((item && item->GetInteger("ts", &val)));
-    EXPECT_EQ(12345, val);
-    EXPECT_TRUE((item && item->GetInteger("tid", &val)));
-    EXPECT_EQ(kThreadId, val);
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ(kAsyncIdStr, id);
+    EXPECT_EQ(*item->FindIntKey("ts"), 12345);
+
+    EXPECT_EQ(*item->FindIntKey("tid"), kThreadId);
+
+    EXPECT_EQ(*item->FindStringKey("id"), kAsyncIdStr);
   }
 
   EXPECT_FIND_("TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0 call");
   {
-    int val;
-    EXPECT_TRUE((item && item->GetInteger("ts", &val)));
-    EXPECT_EQ(34567, val);
-    EXPECT_TRUE((item && item->GetInteger("tid", &val)));
-    EXPECT_EQ(kThreadId, val);
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ(kAsyncId2Str, id);
+    EXPECT_EQ(*item->FindIntKey("ts"), 34567);
+
+    EXPECT_EQ(*item->FindIntKey("tid"), kThreadId);
+
+    EXPECT_EQ(*item->FindStringKey("id"), kAsyncId2Str);
   }
 
   EXPECT_FIND_("TRACE_EVENT_ASYNC_STEP_PAST0 call");
@@ -763,109 +689,69 @@
 #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
   EXPECT_FIND_("TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0 call");
   {
-    int val;
-    EXPECT_TRUE((item && item->GetInteger("ts", &val)));
-    EXPECT_EQ(45678, val);
-    EXPECT_TRUE((item && item->GetInteger("tid", &val)));
-    EXPECT_EQ(kThreadId, val);
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ(kAsyncId2Str, id);
+    EXPECT_EQ(*item->FindIntKey("ts"), 45678);
+
+    EXPECT_EQ(*item->FindIntKey("tid"), kThreadId);
+
+    EXPECT_EQ(*item->FindStringKey("id"), kAsyncId2Str);
   }
 #endif
 
   EXPECT_FIND_("tracked object 1");
   {
-    std::string phase;
-    std::string id;
-    std::string snapshot;
-
-    EXPECT_TRUE((item && item->GetString("ph", &phase)));
-    EXPECT_EQ("N", phase);
-    EXPECT_FALSE((item && item->HasKey("scope")));
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x42", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "N");
+    EXPECT_FALSE(item->FindKey("scope"));
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
 
     item = FindTraceEntry(trace_parsed, "tracked object 1", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("O", phase);
-    EXPECT_FALSE((item && item->HasKey("scope")));
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x42", id);
-    EXPECT_TRUE(item && item->GetString("args.snapshot", &snapshot));
-    EXPECT_EQ("hello", snapshot);
+    EXPECT_EQ(*item->FindStringKey("ph"), "O");
+    EXPECT_FALSE(item->FindKey("scope"));
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
+    EXPECT_EQ(*item->FindStringPath("args.snapshot"), "hello");
 
     item = FindTraceEntry(trace_parsed, "tracked object 1", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("D", phase);
-    EXPECT_FALSE((item && item->HasKey("scope")));
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x42", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "D");
+    EXPECT_FALSE(item->FindKey("scope"));
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
   }
 
   EXPECT_FIND_("tracked object 2");
   {
-    std::string phase;
-    std::string id;
-    std::string snapshot;
-
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("N", phase);
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x2128506", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "N");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x2128506");
 
     item = FindTraceEntry(trace_parsed, "tracked object 2", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("O", phase);
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x2128506", id);
-    EXPECT_TRUE(item && item->GetString("args.snapshot", &snapshot));
-    EXPECT_EQ("world", snapshot);
+    EXPECT_EQ(*item->FindStringKey("ph"), "O");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x2128506");
+    EXPECT_EQ(*item->FindStringPath("args.snapshot"), "world");
 
     item = FindTraceEntry(trace_parsed, "tracked object 2", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("D", phase);
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x2128506", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "D");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x2128506");
   }
 
   EXPECT_FIND_("tracked object 3");
   {
-    std::string phase;
-    std::string scope;
-    std::string id;
-    std::string snapshot;
-
-    EXPECT_TRUE((item && item->GetString("ph", &phase)));
-    EXPECT_EQ("N", phase);
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
-    EXPECT_EQ("scope", scope);
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x42", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "N");
+    EXPECT_EQ(*item->FindStringKey("scope"), "scope");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
 
     item = FindTraceEntry(trace_parsed, "tracked object 3", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("O", phase);
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
-    EXPECT_EQ("scope", scope);
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x42", id);
-    EXPECT_TRUE(item && item->GetString("args.snapshot", &snapshot));
-    EXPECT_EQ("hello", snapshot);
+    EXPECT_EQ(*item->FindStringKey("ph"), "O");
+    EXPECT_EQ(*item->FindStringKey("scope"), "scope");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
+    EXPECT_EQ(*item->FindStringPath("args.snapshot"), "hello");
 
     item = FindTraceEntry(trace_parsed, "tracked object 3", item);
     EXPECT_TRUE(item);
-    EXPECT_TRUE(item && item->GetString("ph", &phase));
-    EXPECT_EQ("D", phase);
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
-    EXPECT_EQ("scope", scope);
-    EXPECT_TRUE(item && item->GetString("id", &id));
-    EXPECT_EQ("0x42", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "D");
+    EXPECT_EQ(*item->FindStringKey("scope"), "scope");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x42");
   }
 
   EXPECT_FIND_(kControlCharacters);
@@ -873,89 +759,63 @@
 
   EXPECT_FIND_("TRACE_EVENT_ENTER_CONTEXT call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("(", ph);
-
-    std::string scope;
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
-    EXPECT_EQ("scope", scope);
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x20151021", id);
+    EXPECT_EQ(*item->FindStringKey("ph"), "(");
+    EXPECT_EQ(*item->FindStringKey("scope"), "scope");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x20151021");
   }
 
   EXPECT_FIND_("TRACE_EVENT_LEAVE_CONTEXT call");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ(")", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), ")");
 
-    std::string scope;
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
-    EXPECT_EQ("scope", scope);
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x20151021", id);
+    EXPECT_EQ(*item->FindStringKey("scope"), "scope");
+    EXPECT_EQ(*item->FindStringKey("id"), "0x20151021");
   }
 
   EXPECT_FIND_("async default process scope");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("S", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "S");
 
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id", &id)));
-    EXPECT_EQ("0x1000", id);
+    EXPECT_EQ(*item->FindStringKey("id"), "0x1000");
   }
 
   EXPECT_FIND_("async local id");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("S", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "S");
 
-    std::string id;
-    EXPECT_TRUE((item && item->GetString("id2.local", &id)));
-    EXPECT_EQ("0x2000", id);
+    EXPECT_EQ(*item->FindStringPath("id2.local"), "0x2000");
   }
 
   EXPECT_FIND_("async global id");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("S", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "S");
 
-    std::string id;
 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    EXPECT_TRUE((item && item->GetString("id", &id)));
+    const char kIdPath[] = "id";
 #else
-    EXPECT_TRUE((item && item->GetString("id2.global", &id)));
+    const char kIdPath[] = "id2.global";
 #endif
-    EXPECT_EQ("0x3000", id);
+    EXPECT_EQ(*item->FindStringPath(kIdPath), "0x3000");
   }
 
   EXPECT_FIND_("async global id with scope string");
   {
-    std::string ph;
-    EXPECT_TRUE((item && item->GetString("ph", &ph)));
-    EXPECT_EQ("S", ph);
+    EXPECT_EQ(*item->FindStringKey("ph"), "S");
 
-    std::string id;
 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    EXPECT_TRUE((item && item->GetString("id", &id)));
+    const char kIdPath[] = "id";
 #else
-    EXPECT_TRUE((item && item->GetString("id2.global", &id)));
+    const char kIdPath[] = "id2.global";
 #endif
-    EXPECT_EQ("0x4000", id);
-    std::string scope;
-    EXPECT_TRUE((item && item->GetString("scope", &scope)));
+    EXPECT_EQ(*item->FindStringPath(kIdPath), "0x4000");
+
 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    EXPECT_EQ("test_all:scope string", scope);
+    const char kExpectedScope[] = "test_all:scope string";
 #else
-    EXPECT_EQ("scope string", scope);
+    const char kExpectedScope[] = "scope string";
 #endif
+
+    EXPECT_EQ(*item->FindStringPath("scope"), kExpectedScope);
   }
 }
 
@@ -971,28 +831,25 @@
     task_complete_event->Signal();
 }
 
-void ValidateInstantEventPresentOnEveryThread(const ListValue& trace_parsed,
+void ValidateInstantEventPresentOnEveryThread(const Value& trace_parsed,
                                               int num_threads,
                                               int num_events) {
-  std::map<int, std::map<int, bool> > results;
+  std::map<int, std::map<int, bool>> results;
 
-  size_t trace_parsed_count = trace_parsed.GetSize();
-  for (size_t i = 0; i < trace_parsed_count; i++) {
-    const Value* value = nullptr;
-    trace_parsed.Get(i, &value);
-    if (!value || value->type() != Value::Type::DICTIONARY)
-      continue;
-    const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
-    std::string name;
-    dict->GetString("name", &name);
-    if (name != "multi thread event")
+  for (const Value& value : trace_parsed.GetList()) {
+    if (!value.is_dict())
       continue;
 
-    int thread = 0;
-    int event = 0;
-    EXPECT_TRUE(dict->GetInteger("args.thread", &thread));
-    EXPECT_TRUE(dict->GetInteger("args.event", &event));
-    results[thread][event] = true;
+    const std::string* name = value.FindStringKey("name");
+    if (!name || *name != "multi thread event")
+      continue;
+
+    absl::optional<int> maybe_thread = value.FindIntPath("args.thread");
+    absl::optional<int> maybe_event = value.FindIntPath("args.event");
+
+    EXPECT_TRUE(maybe_thread.has_value());
+    EXPECT_TRUE(maybe_event.has_value());
+    results[maybe_thread.value_or(0)][maybe_event.value_or(0)] = true;
   }
 
   EXPECT_FALSE(results[-1][-1]);
@@ -1037,7 +894,7 @@
 
   CancelTrace();
 
-  EXPECT_TRUE(trace_parsed_.empty());
+  EXPECT_TRUE(trace_parsed_.GetList().empty());
 }
 
 class MockEnabledStateChangedObserver :
@@ -1337,7 +1194,7 @@
   TRACE_EVENT_INSTANT0("cat2", "name", TRACE_EVENT_SCOPE_THREAD);
   EndTraceAndFlush();
   DropTracedMetadataRecords();
-  EXPECT_TRUE(trace_parsed_.empty());
+  EXPECT_TRUE(trace_parsed_.GetList().empty());
 
   // Include existent category -> only events of that category
   Clear();
@@ -1467,9 +1324,9 @@
   TRACE_EVENT_ASYNC_END0("cat", "name1", ptr);
   EndTraceAndFlush();
 
-  DictionaryValue* async_begin = FindNamePhase("name1", "S");
-  DictionaryValue* async_begin2 = FindNamePhase("name2", "S");
-  DictionaryValue* async_end = FindNamePhase("name1", "F");
+  const Value* async_begin = FindNamePhase("name1", "S");
+  const Value* async_begin2 = FindNamePhase("name2", "S");
+  const Value* async_end = FindNamePhase("name1", "F");
   EXPECT_TRUE(async_begin);
   EXPECT_TRUE(async_begin2);
   EXPECT_TRUE(async_end);
@@ -1664,33 +1521,32 @@
 
   EndTraceAndFlush();
 
-  std::string tmp;
-  int tmp_int;
-  const DictionaryValue* item;
-
   // Make sure we get thread name metadata.
   // Note, the test suite may have created a ton of threads.
   // So, we'll have thread names for threads we didn't create.
-  std::vector<const DictionaryValue*> items =
+  std::vector<const Value*> items =
       FindTraceEntries(trace_parsed_, "thread_name");
-  for (int i = 0; i < static_cast<int>(items.size()); i++) {
-    item = items[i];
+  for (const Value* item : items) {
     ASSERT_TRUE(item);
-    EXPECT_TRUE(item->GetInteger("tid", &tmp_int));
+    ASSERT_TRUE(item->is_dict());
+
+    absl::optional<int> maybe_tid = item->FindIntKey("tid");
+    EXPECT_TRUE(maybe_tid.has_value());
 
     // See if this thread name is one of the threads we just created
     for (int j = 0; j < kNumThreads; j++) {
-      if (static_cast<int>(thread_ids[j]) != tmp_int)
+      if (static_cast<int>(thread_ids[j]) != maybe_tid.value())
         continue;
 
-      std::string expected_name = StringPrintf("Thread %d", j);
-      EXPECT_TRUE(item->GetString("ph", &tmp) && tmp == "M");
-      EXPECT_TRUE(item->GetInteger("pid", &tmp_int) &&
-                  tmp_int == static_cast<int>(base::GetCurrentProcId()));
+      EXPECT_EQ(*item->FindStringKey("ph"), "M");
+      EXPECT_EQ(*item->FindIntKey("pid"),
+                static_cast<int>(base::GetCurrentProcId()));
+
       // If the thread name changes or the tid gets reused, the name will be
       // a comma-separated list of thread names, so look for a substring.
-      EXPECT_TRUE(item->GetString("args.name", &tmp) &&
-                  tmp.find(expected_name) != std::string::npos);
+      std::string expected_name = StringPrintf("Thread %d", j);
+      const std::string* name = item->FindStringPath("args.name");
+      EXPECT_TRUE(name && name->find(expected_name) != std::string::npos);
     }
   }
 }
@@ -1704,8 +1560,8 @@
   TRACE_EVENT_INSTANT0("test_included", "first", TRACE_EVENT_SCOPE_THREAD);
   EndTraceAndFlush();
   {
-    const DictionaryValue* item = nullptr;
-    ListValue& trace_parsed = trace_parsed_;
+    const Value* item = nullptr;
+    Value& trace_parsed = trace_parsed_;
     EXPECT_NOT_FIND_("disabled-by-default-cc");
     EXPECT_FIND_("test_included");
   }
@@ -1719,8 +1575,8 @@
   EndTraceAndFlush();
 
   {
-    const DictionaryValue* item = nullptr;
-    ListValue& trace_parsed = trace_parsed_;
+    const Value* item = nullptr;
+    Value& trace_parsed = trace_parsed_;
     EXPECT_FIND_("disabled-by-default-cc");
     EXPECT_FIND_("test_other_included");
   }
@@ -1736,8 +1592,8 @@
   EndTraceAndFlush();
 
   {
-    const DictionaryValue* item = nullptr;
-    ListValue& trace_parsed = trace_parsed_;
+    const Value* item = nullptr;
+    Value& trace_parsed = trace_parsed_;
     EXPECT_FIND_("test,disabled-by-default-cc,test_other_included");
     EXPECT_FIND_("test_other_included,disabled-by-default-cc");
   }
@@ -1797,23 +1653,18 @@
   EXPECT_FALSE(FindTraceEntry(trace_parsed_, name2.c_str()));
   EXPECT_FALSE(FindTraceEntry(trace_parsed_, name3.c_str()));
 
-  const DictionaryValue* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
-  const DictionaryValue* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
-  const DictionaryValue* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
+  const Value* entry1 = FindTraceEntry(trace_parsed_, kOriginalName1);
+  const Value* entry2 = FindTraceEntry(trace_parsed_, kOriginalName2);
+  const Value* entry3 = FindTraceEntry(trace_parsed_, kOriginalName3);
   ASSERT_TRUE(entry1);
   ASSERT_TRUE(entry2);
   ASSERT_TRUE(entry3);
 
-  int i;
-  EXPECT_FALSE(entry2->GetInteger("args.@rg1", &i));
-  EXPECT_TRUE(entry2->GetInteger("args.arg1", &i));
-  EXPECT_EQ(5, i);
+  EXPECT_FALSE(entry2->FindIntPath("args.@rg1"));
+  EXPECT_EQ(*entry2->FindIntPath("args.arg1"), 5);
 
-  std::string s;
-  EXPECT_TRUE(entry3->GetString("args.arg1", &s));
-  EXPECT_EQ("val1", s);
-  EXPECT_TRUE(entry3->GetString("args.arg2", &s));
-  EXPECT_EQ("val2", s);
+  EXPECT_EQ(*entry3->FindStringPath("args.arg1"), "val1");
+  EXPECT_EQ(*entry3->FindStringPath("args.arg2"), "val2");
 }
 
 // Test that TraceResultBuffer outputs the correct result whether it is added
@@ -2018,92 +1869,67 @@
   EndTraceAndFlush();
 
   // One arg version.
-  DictionaryValue* dict = FindNamePhase("bar", "X");
+  const Value* dict = FindNamePhase("bar", "X");
   ASSERT_TRUE(dict);
 
-  const DictionaryValue* args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  const Value* args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  const Value* value = nullptr;
-  const DictionaryValue* convertable_dict = nullptr;
-  EXPECT_TRUE(args_dict->Get("data", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+  const Value* convertable_dict = args_dict->FindDictKey("data");
+  ASSERT_TRUE(convertable_dict);
 
-  int foo_val;
-  EXPECT_TRUE(convertable_dict->GetInteger("foo", &foo_val));
-  EXPECT_EQ(1, foo_val);
+  EXPECT_EQ(*convertable_dict->FindIntKey("foo"), 1);
 
   // Two arg version.
   dict = FindNamePhase("baz", "X");
   ASSERT_TRUE(dict);
 
-  args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  value = nullptr;
-  convertable_dict = nullptr;
-  EXPECT_TRUE(args_dict->Get("data1", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+  convertable_dict = args_dict->FindDictKey("data1");
+  ASSERT_TRUE(convertable_dict);
 
-  value = nullptr;
-  convertable_dict = nullptr;
-  EXPECT_TRUE(args_dict->Get("data2", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+  convertable_dict = args_dict->FindDictKey("data2");
+  ASSERT_TRUE(convertable_dict);
 
   // Convertable with other types.
   dict = FindNamePhase("string_first", "X");
   ASSERT_TRUE(dict);
 
-  args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  std::string str_value;
-  EXPECT_TRUE(args_dict->GetString("str", &str_value));
-  EXPECT_STREQ("string value 1", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("str"), "string value 1");
 
-  value = nullptr;
-  convertable_dict = nullptr;
-  foo_val = 0;
-  EXPECT_TRUE(args_dict->Get("convert", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
-  EXPECT_TRUE(convertable_dict->GetInteger("foo", &foo_val));
-  EXPECT_EQ(1, foo_val);
+  convertable_dict = args_dict->FindDictKey("convert");
+  ASSERT_TRUE(convertable_dict);
+
+  EXPECT_EQ(*convertable_dict->FindIntKey("foo"), 1);
 
   dict = FindNamePhase("string_second", "X");
   ASSERT_TRUE(dict);
 
-  args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  EXPECT_TRUE(args_dict->GetString("str", &str_value));
-  EXPECT_STREQ("string value 2", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("str"), "string value 2");
 
-  value = nullptr;
-  convertable_dict = nullptr;
-  foo_val = 0;
-  EXPECT_TRUE(args_dict->Get("convert", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
-  EXPECT_TRUE(convertable_dict->GetInteger("foo", &foo_val));
-  EXPECT_EQ(1, foo_val);
+  convertable_dict = args_dict->FindDictKey("convert");
+  ASSERT_TRUE(convertable_dict);
+
+  EXPECT_EQ(*convertable_dict->FindIntKey("foo"), 1);
 
   dict = FindNamePhase("both_conv", "X");
   ASSERT_TRUE(dict);
 
-  args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  value = nullptr;
-  convertable_dict = nullptr;
-  foo_val = 0;
-  EXPECT_TRUE(args_dict->Get("convert1", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
-  EXPECT_TRUE(args_dict->Get("convert2", &value));
-  ASSERT_TRUE(value->GetAsDictionary(&convertable_dict));
+  convertable_dict = args_dict->FindDictKey("convert1");
+  ASSERT_TRUE(convertable_dict);
+  convertable_dict = args_dict->FindDictKey("convert2");
+  ASSERT_TRUE(convertable_dict);
 }
 
 TEST_F(TraceEventTestFixture, PrimitiveArgs) {
@@ -2137,137 +1963,111 @@
   }
   EndTraceAndFlush();
 
-  const DictionaryValue* args_dict = nullptr;
-  DictionaryValue* dict = nullptr;
-  const Value* value = nullptr;
+  const Value* args_dict = nullptr;
+  const Value* dict = nullptr;
   std::string str_value;
-  int int_value;
-  double double_value;
-  bool bool_value;
 
   dict = FindNamePhase("event1", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("int_one", &int_value));
-  EXPECT_EQ(1, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("int_one"), 1);
 
   dict = FindNamePhase("event2", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("int_neg_ten", &int_value));
-  EXPECT_EQ(-10, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("int_neg_ten"), -10);
 
   // 1f must be serlized to JSON as "1.0" in order to be a double, not an int.
   dict = FindNamePhase("event3", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->Get("float_one", &value));
-  EXPECT_TRUE(value->is_double());
-  EXPECT_TRUE(value->GetAsDouble(&double_value));
-  EXPECT_EQ(1, double_value);
+  EXPECT_EQ(*args_dict->FindDoubleKey("float_one"), 1.0);
 
   // .5f must be serlized to JSON as "0.5".
   dict = FindNamePhase("event4", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->Get("float_half", &value));
-  EXPECT_TRUE(value->is_double());
-  EXPECT_TRUE(value->GetAsDouble(&double_value));
-  EXPECT_EQ(0.5, double_value);
+  EXPECT_EQ(*args_dict->FindDoubleKey("float_half"), 0.5);
 
   // -.5f must be serlized to JSON as "-0.5".
   dict = FindNamePhase("event5", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->Get("float_neghalf", &value));
-  EXPECT_TRUE(value->is_double());
-  EXPECT_TRUE(value->GetAsDouble(&double_value));
-  EXPECT_EQ(-0.5, double_value);
+  EXPECT_EQ(*args_dict->FindDoubleKey("float_neghalf"), -0.5);
 
   // Infinity is serialized to JSON as a string.
   dict = FindNamePhase("event6", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetString("float_infinity", &str_value));
-  EXPECT_STREQ("Infinity", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("float_infinity"), "Infinity");
   dict = FindNamePhase("event6b", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetString("float_neg_infinity", &str_value));
-  EXPECT_STREQ("-Infinity", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("float_neg_infinity"), "-Infinity");
 
   // NaN is serialized to JSON as a string.
   dict = FindNamePhase("event7", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetString("double_nan", &str_value));
-  EXPECT_STREQ("NaN", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("double_nan"), "NaN");
 
   // NULL pointers should be serialized as "0x0".
   dict = FindNamePhase("event8", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetString("pointer_null", &str_value));
-  EXPECT_STREQ("0x0", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("pointer_null"), "0x0");
 
   // Other pointers should be serlized as a hex string.
   dict = FindNamePhase("event9", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetString("pointer_badf00d", &str_value));
-  EXPECT_STREQ("0xbadf00d", str_value.c_str());
+  EXPECT_EQ(*args_dict->FindStringKey("pointer_badf00d"), "0xbadf00d");
 
   dict = FindNamePhase("event10", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetBoolean("bool_true", &bool_value));
-  EXPECT_TRUE(bool_value);
+  EXPECT_EQ(*args_dict->FindBoolKey("bool_true"), true);
 
   dict = FindNamePhase("event11", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetBoolean("bool_false", &bool_value));
-  EXPECT_FALSE(bool_value);
+  EXPECT_EQ(*args_dict->FindBoolKey("bool_false"), false);
 
   dict = FindNamePhase("event12", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("time_null", &int_value));
-  EXPECT_EQ(0, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("time_null"), 0);
 
   dict = FindNamePhase("event13", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("time_one", &int_value));
-  EXPECT_EQ(1, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("time_one"), 1);
 
   dict = FindNamePhase("event14", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("timeticks_null", &int_value));
-  EXPECT_EQ(0, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("timeticks_null"), 0);
 
   dict = FindNamePhase("event15", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("timeticks_one", &int_value));
-  EXPECT_EQ(1, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("timeticks_one"), 1);
 }
 
 TEST_F(TraceEventTestFixture, NameIsEscaped) {
@@ -2323,37 +2123,29 @@
 
   EndTraceAndFlush();
 
-  const DictionaryValue* args_dict = nullptr;
-  DictionaryValue* dict = nullptr;
-  int int_value;
+  const Value* args_dict = nullptr;
+  const Value* dict = nullptr;
 
   dict = FindNamePhase("event1", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
-  EXPECT_TRUE(args_dict->GetInteger("int_one", &int_value));
-  EXPECT_EQ(1, int_value);
+  EXPECT_EQ(*args_dict->FindIntKey("int_one"), 1);
+  EXPECT_FALSE(args_dict->FindIntKey("int_two"));
 
   dict = FindNamePhase("event2", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
-  ASSERT_TRUE(args_dict);
-  EXPECT_FALSE(args_dict->GetInteger("int_two", &int_value));
-
-  std::string args_string;
-  EXPECT_TRUE(dict->GetString("args", &args_string));
-  EXPECT_EQ(args_string, "__stripped__");
+  EXPECT_EQ(*dict->FindStringKey("args"), "__stripped__");
 
   dict = FindNamePhase("granularly_allowed", "X");
   ASSERT_TRUE(dict);
-  dict->GetDictionary("args", &args_dict);
+  args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  EXPECT_TRUE(args_dict->GetString("granular_arg_allowed", &args_string));
-  EXPECT_EQ(args_string, "allowed_value");
+  EXPECT_EQ(*args_dict->FindStringKey("granular_arg_allowed"), "allowed_value");
 
-  EXPECT_TRUE(args_dict->GetString("granular_arg_disallowed", &args_string));
-  EXPECT_EQ(args_string, "__stripped__");
+  EXPECT_EQ(*args_dict->FindStringKey("granular_arg_disallowed"),
+            "__stripped__");
 }
 #endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
 
@@ -2374,33 +2166,32 @@
 
   EndTraceAndFlush();
 
-  const DictionaryValue* trace_full_metadata = nullptr;
+  const Value* trace_full_metadata = nullptr;
 
   trace_full_metadata = FindTraceEntry(trace_parsed_,
                                        "overflowed_at_ts");
-  std::string phase;
-  double buffer_limit_reached_timestamp = 0;
 
   EXPECT_TRUE(trace_full_metadata);
-  EXPECT_TRUE(trace_full_metadata->GetString("ph", &phase));
-  EXPECT_EQ("M", phase);
-  EXPECT_TRUE(trace_full_metadata->GetDouble(
-      "args.overflowed_at_ts", &buffer_limit_reached_timestamp));
-  EXPECT_DOUBLE_EQ(
-      static_cast<double>(
-          trace_log->buffer_limit_reached_timestamp_.ToInternalValue()),
-      buffer_limit_reached_timestamp);
+  EXPECT_EQ(*trace_full_metadata->FindStringKey("ph"), "M");
+  absl::optional<double> maybe_buffer_limit_reached_timestamp =
+      trace_full_metadata->FindDoublePath("args.overflowed_at_ts");
+
+  EXPECT_EQ(*maybe_buffer_limit_reached_timestamp,
+            static_cast<double>(
+                trace_log->buffer_limit_reached_timestamp_.ToInternalValue()));
 
   // Test that buffer_limit_reached_timestamp's value is between the timestamp
   // of the last trace event and current time.
   DropTracedMetadataRecords();
-  const DictionaryValue* last_trace_event = nullptr;
-  double last_trace_event_timestamp = 0;
-  EXPECT_TRUE(trace_parsed_.GetDictionary(trace_parsed_.GetSize() - 1,
-                                          &last_trace_event));
-  EXPECT_TRUE(last_trace_event->GetDouble("ts", &last_trace_event_timestamp));
-  EXPECT_LE(last_trace_event_timestamp, buffer_limit_reached_timestamp);
-  EXPECT_LE(buffer_limit_reached_timestamp,
+  ASSERT_TRUE(!trace_parsed_.GetList().empty());
+  const Value& last_trace_event = trace_parsed_.GetList().back();
+  EXPECT_TRUE(last_trace_event.is_dict());
+  absl::optional<double> maybe_last_trace_event_timestamp =
+      last_trace_event.FindDoubleKey("ts");
+  EXPECT_TRUE(maybe_last_trace_event_timestamp.has_value());
+  EXPECT_LE(maybe_last_trace_event_timestamp.value(),
+            maybe_buffer_limit_reached_timestamp.value());
+  EXPECT_LE(maybe_buffer_limit_reached_timestamp.value(),
             trace_log->OffsetNow().ToInternalValue());
 }
 
@@ -2774,14 +2565,13 @@
   double end_time = static_cast<double>(
       (TimeTicks::Now() - time_offset).ToInternalValue());
   double last_timestamp = 0;
-  for (size_t i = 0; i < trace_parsed_.GetSize(); ++i) {
-    const DictionaryValue* item;
-    EXPECT_TRUE(trace_parsed_.GetDictionary(i, &item));
-    double timestamp;
-    EXPECT_TRUE(item->GetDouble("ts", &timestamp));
-    EXPECT_GE(timestamp, last_timestamp);
-    EXPECT_LE(timestamp, end_time);
-    last_timestamp = timestamp;
+  for (const Value& item : trace_parsed_.GetList()) {
+    EXPECT_TRUE(item.is_dict());
+    absl::optional<double> timestamp = item.FindDoubleKey("ts");
+    EXPECT_TRUE(timestamp.has_value());
+    EXPECT_GE(timestamp.value(), last_timestamp);
+    EXPECT_LE(timestamp.value(), end_time);
+    last_timestamp = timestamp.value();
   }
 }
 #endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
@@ -3002,17 +2792,14 @@
   }
   EndTraceAndFlush();
 
-  DictionaryValue* dict = FindNamePhase("Name", "X");
+  const Value* dict = FindNamePhase("Name", "X");
   ASSERT_TRUE(dict);
 
-  const DictionaryValue* args_dict = nullptr;
-  dict->GetDictionary("args", &args_dict);
+  const Value* args_dict = dict->FindDictKey("args");
   ASSERT_TRUE(args_dict);
 
-  const Value* value = nullptr;
-  EXPECT_TRUE(args_dict->Get("arg", &value));
-  ASSERT_TRUE(value->is_string());
-  EXPECT_EQ(value->GetString(), "Unsupported (crbug.com/1225176)");
+  EXPECT_EQ(*args_dict->FindStringKey("arg"),
+            "Unsupported (crbug.com/1225176)");
 }
 
 }  // namespace trace_event
diff --git a/base/values.cc b/base/values.cc
index d38acb0..9edb5ad 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1575,23 +1575,6 @@
       index, const_cast<const DictionaryValue**>(out_value));
 }
 
-bool ListValue::GetList(size_t index, const ListValue** out_value) const {
-  const Value* value;
-  bool result = Get(index, &value);
-  if (!result || !value->is_list())
-    return false;
-
-  if (out_value)
-    *out_value = static_cast<const ListValue*>(value);
-
-  return true;
-}
-
-bool ListValue::GetList(size_t index, ListValue** out_value) {
-  return as_const(*this).GetList(index,
-                                 const_cast<const ListValue**>(out_value));
-}
-
 void ListValue::Append(std::unique_ptr<Value> in_value) {
   list().push_back(std::move(*in_value));
 }
diff --git a/base/values.h b/base/values.h
index 631fda3..c67a522a 100644
--- a/base/values.h
+++ b/base/values.h
@@ -878,11 +878,6 @@
   bool GetDictionary(size_t index, const DictionaryValue** out_value) const;
   bool GetDictionary(size_t index, DictionaryValue** out_value);
 
-  using Value::GetList;
-  // DEPRECATED, use `GetList()::operator[]::GetList()` instead.
-  bool GetList(size_t index, const ListValue** out_value) const;
-  bool GetList(size_t index, ListValue** out_value);
-
   using Value::Append;
   // Appends a Value to the end of the list.
   // DEPRECATED, use `Value::Append()` instead.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index dbc15d61e..ac43417 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -1489,9 +1489,9 @@
 TEST(ValuesTest, ListDeletion) {
   ListValue list;
   list.Append(std::make_unique<Value>());
-  EXPECT_FALSE(list.empty());
+  EXPECT_FALSE(list.GetList().empty());
   list.Clear();
-  EXPECT_TRUE(list.empty());
+  EXPECT_TRUE(list.GetList().empty());
 }
 
 TEST(ValuesTest, DictionaryDeletion) {
@@ -2067,10 +2067,10 @@
 
     ListValue* inner_value;
     EXPECT_TRUE(root->GetList("list_with_empty_children", &inner_value));
-    EXPECT_EQ(1U, inner_value->GetSize());  // Dictionary was pruned.
-    ListValue* inner_value2;
-    EXPECT_TRUE(inner_value->GetList(0, &inner_value2));
-    EXPECT_EQ(1U, inner_value2->GetSize());
+    ASSERT_EQ(1U, inner_value->GetSize());  // Dictionary was pruned.
+    const Value& inner_value2 = inner_value->GetList()[0];
+    ASSERT_TRUE(inner_value2.is_list());
+    EXPECT_EQ(1U, inner_value2.GetList().size());
   }
 }
 
@@ -2481,15 +2481,6 @@
   EXPECT_TRUE(main_list.GetDictionary(5, nullptr));
   EXPECT_FALSE(main_list.GetDictionary(6, nullptr));
   EXPECT_FALSE(main_list.GetDictionary(7, nullptr));
-
-  EXPECT_FALSE(main_list.GetList(0, nullptr));
-  EXPECT_FALSE(main_list.GetList(1, nullptr));
-  EXPECT_FALSE(main_list.GetList(2, nullptr));
-  EXPECT_FALSE(main_list.GetList(3, nullptr));
-  EXPECT_FALSE(main_list.GetList(4, nullptr));
-  EXPECT_FALSE(main_list.GetList(5, nullptr));
-  EXPECT_TRUE(main_list.GetList(6, nullptr));
-  EXPECT_FALSE(main_list.GetList(7, nullptr));
 }
 
 TEST(ValuesTest, SelfSwap) {
diff --git a/base/win/security_util.cc b/base/win/security_util.cc
index 3e164389..d75d3555 100644
--- a/base/win/security_util.cc
+++ b/base/win/security_util.cc
@@ -12,6 +12,7 @@
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/win/scoped_handle.h"
 #include "base/win/scoped_localalloc.h"
 #include "base/win/win_util.h"
 
@@ -21,7 +22,8 @@
 bool GrantAccessToPath(const FilePath& path,
                        const std::vector<Sid>& sids,
                        DWORD access_mask,
-                       DWORD inheritance) {
+                       DWORD inheritance,
+                       bool recursive) {
   DCHECK(!path.empty());
   if (sids.empty())
     return true;
@@ -60,10 +62,24 @@
     return false;
   }
   auto new_dacl_ptr = TakeLocalAlloc(new_dacl);
+  if (recursive) {
+    error = ::SetNamedSecurityInfo(&object_name[0], SE_FILE_OBJECT,
+                                   DACL_SECURITY_INFORMATION, nullptr, nullptr,
+                                   new_dacl_ptr.get(), nullptr);
+  } else {
+    ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0,
+                                     nullptr, OPEN_EXISTING,
+                                     FILE_FLAG_BACKUP_SEMANTICS, nullptr));
+    if (!handle.IsValid()) {
+      DPLOG(ERROR) << "Failed opening path \"" << path.value()
+                   << "\" to write DACL";
+      return false;
+    }
+    error = ::SetSecurityInfo(handle.Get(), SE_KERNEL_OBJECT,
+                              DACL_SECURITY_INFORMATION, nullptr, nullptr,
+                              new_dacl_ptr.get(), nullptr);
+  }
 
-  error = ::SetNamedSecurityInfo(&object_name[0], SE_FILE_OBJECT,
-                                 DACL_SECURITY_INFORMATION, nullptr, nullptr,
-                                 new_dacl_ptr.get(), nullptr);
   if (error != ERROR_SUCCESS) {
     ::SetLastError(error);
     DPLOG(ERROR) << "Failed setting DACL for path \"" << path.value() << "\"";
diff --git a/base/win/security_util.h b/base/win/security_util.h
index 2dcbc36..30fca09 100644
--- a/base/win/security_util.h
+++ b/base/win/security_util.h
@@ -18,11 +18,14 @@
 namespace win {
 
 // Adds allowed ACE entries to a file or directory |path| from a list of SIDs
-// with allowed |access_mask| and |inheritance| flags.
+// with allowed |access_mask| and |inheritance| flags. If |path| is a directory
+// and |recursive| is true then any inheritable ACEs granted will be propagated
+// to its children.
 BASE_EXPORT bool GrantAccessToPath(const FilePath& path,
                                    const std::vector<Sid>& sids,
                                    DWORD access_mask,
-                                   DWORD inheritance);
+                                   DWORD inheritance,
+                                   bool recursive = true);
 
 }  // namespace win
 }  // namespace base
diff --git a/base/win/security_util_unittest.cc b/base/win/security_util_unittest.cc
index edf8c212..0a67fe3 100644
--- a/base/win/security_util_unittest.cc
+++ b/base/win/security_util_unittest.cc
@@ -23,11 +23,18 @@
 constexpr wchar_t kBaseDacl[] = L"D:P(A;;FA;;;WD)";
 constexpr wchar_t kTest1Dacl[] = L"D:PAI(A;;FR;;;AU)(A;;FA;;;WD)";
 constexpr wchar_t kTest2Dacl[] = L"D:PAI(A;;FA;;;BA)(A;;FA;;;AU)(A;;FA;;;WD)";
+constexpr wchar_t kTest1DaclNoInherit[] = L"D:P(A;;FR;;;AU)(A;;FA;;;WD)";
+constexpr wchar_t kTest2DaclNoInherit[] =
+    L"D:P(A;;FA;;;BA)(A;;FA;;;AU)(A;;FA;;;WD)";
 
 constexpr wchar_t kBaseDirDacl[] = L"D:P(A;OICI;FA;;;WD)";
 constexpr wchar_t kTest1InheritedDacl[] = L"D:(A;ID;FA;;;WD)";
 constexpr wchar_t kBaseDir2Dacl[] = L"D:PAI(A;OICI;FR;;;AU)(A;OICI;FA;;;WD)";
 constexpr wchar_t kTest2InheritedDacl[] = L"D:AI(A;ID;FR;;;AU)(A;ID;FA;;;WD)";
+constexpr wchar_t kBaseDir2DaclNoInherit[] =
+    L"D:P(A;OICI;FR;;;AU)(A;OICI;FA;;;WD)";
+constexpr wchar_t kTest2InheritedDaclNoInherit[] = L"D:P(A;;FA;;;WD)";
+constexpr wchar_t kTest3InheritedDacl[] = L"D:(A;ID;FR;;;AU)(A;ID;FA;;;WD)";
 
 constexpr wchar_t kNoWriteDacDacl[] = L"D:(D;;WD;;;OW)(A;;FRSD;;;WD)";
 
@@ -77,14 +84,20 @@
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   FilePath path = temp_dir.GetPath().Append(L"test");
   EXPECT_FALSE(
-      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE));
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, true));
+  EXPECT_FALSE(
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, false));
   ASSERT_TRUE(CreateWithDacl(path, kBaseDacl, false));
   EXPECT_TRUE(
-      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE));
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, true));
+  EXPECT_TRUE(
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, false));
   path = temp_dir.GetPath().Append(L"test_nowritedac");
   ASSERT_TRUE(CreateWithDacl(path, kNoWriteDacDacl, false));
   EXPECT_FALSE(
-      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE));
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, true));
+  EXPECT_FALSE(
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, false));
 }
 
 TEST(SecurityUtilTest, GrantAccessToPathFile) {
@@ -96,14 +109,33 @@
   auto sids = Sid::FromSddlStringVector({kAuthenticatedUsersSid});
   ASSERT_TRUE(sids);
   EXPECT_TRUE(
-      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE));
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, true));
   EXPECT_EQ(kTest1Dacl, GetFileDacl(path));
   auto sids2 = Sid::FromSddlStringVector({L"S-1-5-11", L"BA"});
   ASSERT_TRUE(sids2);
-  EXPECT_TRUE(GrantAccessToPath(path, *sids2, GENERIC_ALL, NO_INHERITANCE));
+  EXPECT_TRUE(
+      GrantAccessToPath(path, *sids2, GENERIC_ALL, NO_INHERITANCE, true));
   EXPECT_EQ(kTest2Dacl, GetFileDacl(path));
 }
 
+TEST(SecurityUtilTest, GrantAccessToPathFileNoInherit) {
+  ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+  FilePath path = temp_dir.GetPath().Append(L"test");
+  ASSERT_TRUE(CreateWithDacl(path, kBaseDacl, false));
+  EXPECT_EQ(kBaseDacl, GetFileDacl(path));
+  auto sids = Sid::FromSddlStringVector({kAuthenticatedUsersSid});
+  ASSERT_TRUE(sids);
+  EXPECT_TRUE(
+      GrantAccessToPath(path, *sids, FILE_GENERIC_READ, NO_INHERITANCE, false));
+  EXPECT_EQ(kTest1DaclNoInherit, GetFileDacl(path));
+  auto sids2 = Sid::FromSddlStringVector({L"S-1-5-11", L"BA"});
+  ASSERT_TRUE(sids2);
+  EXPECT_TRUE(
+      GrantAccessToPath(path, *sids2, GENERIC_ALL, NO_INHERITANCE, false));
+  EXPECT_EQ(kTest2DaclNoInherit, GetFileDacl(path));
+}
+
 TEST(SecurityUtilTest, GrantAccessToPathDirectory) {
   ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -118,10 +150,37 @@
   auto sids = Sid::FromSddlStringVector({kAuthenticatedUsersSid});
   ASSERT_TRUE(sids);
   EXPECT_TRUE(GrantAccessToPath(path, *sids, FILE_GENERIC_READ,
-                                OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE));
+                                OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
+                                true));
   EXPECT_EQ(kBaseDir2Dacl, GetFileDacl(path));
   EXPECT_EQ(kTest2InheritedDacl, GetFileDacl(file_path));
 }
 
+TEST(SecurityUtilTest, GrantAccessToPathDirectoryNoInherit) {
+  ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+  FilePath path = temp_dir.GetPath().Append(L"testdir");
+  ASSERT_TRUE(CreateWithDacl(path, kBaseDirDacl, true));
+  EXPECT_EQ(kBaseDirDacl, GetFileDacl(path));
+  FilePath file_path = path.Append(L"test");
+  File file(file_path, File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE);
+  ASSERT_TRUE(file.IsValid());
+  file.Close();
+  EXPECT_EQ(kTest1InheritedDacl, GetFileDacl(file_path));
+  auto sids = Sid::FromSddlStringVector({kAuthenticatedUsersSid});
+  ASSERT_TRUE(sids);
+  EXPECT_TRUE(GrantAccessToPath(path, *sids, FILE_GENERIC_READ,
+                                OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
+                                false));
+  EXPECT_EQ(kBaseDir2DaclNoInherit, GetFileDacl(path));
+  EXPECT_EQ(kTest2InheritedDaclNoInherit, GetFileDacl(file_path));
+
+  FilePath file_path2 = path.Append(L"test2");
+  File file2(file_path2, File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE);
+  ASSERT_TRUE(file2.IsValid());
+  file2.Close();
+  EXPECT_EQ(kTest3InheritedDacl, GetFileDacl(file_path2));
+}
+
 }  // namespace win
 }  // namespace base
\ No newline at end of file
diff --git a/build/android/gyp/dist_aar.py b/build/android/gyp/dist_aar.py
index 7f0de1d..6bf0573f 100755
--- a/build/android/gyp/dist_aar.py
+++ b/build/android/gyp/dist_aar.py
@@ -118,7 +118,7 @@
             z, 'AndroidManifest.xml', src_path=options.android_manifest)
 
         path_transform = filter_zip.CreatePathTransform(
-            options.jar_excluded_globs, options.jar_included_globs, [])
+            options.jar_excluded_globs, options.jar_included_globs)
         with tempfile.NamedTemporaryFile() as jar_file:
           build_utils.MergeZips(
               jar_file.name, options.jars, path_transform=path_transform)
diff --git a/build/android/gyp/filter_zip.py b/build/android/gyp/filter_zip.py
index 068ff03e..caa26eb 100755
--- a/build/android/gyp/filter_zip.py
+++ b/build/android/gyp/filter_zip.py
@@ -11,36 +11,21 @@
 from util import build_utils
 
 
-_RESOURCE_CLASSES = [
-    "R.class",
-    "R##*.class",
-    "Manifest.class",
-    "Manifest##*.class",
-]
-
-
-def CreatePathTransform(exclude_globs, include_globs,
-                        strip_resource_classes_for):
+def CreatePathTransform(exclude_globs, include_globs):
   """Returns a function to strip paths for the given patterns.
 
   Args:
     exclude_globs: List of globs that if matched should be excluded.
     include_globs: List of globs that if not matched should be excluded.
-    strip_resource_classes_for: List of Java packages for which to strip
-       R.java classes from.
 
   Returns:
     * None if no filters are needed.
     * A function "(path) -> path" that returns None when |path| should be
           stripped, or |path| otherwise.
   """
-  if not (exclude_globs or include_globs or strip_resource_classes_for):
+  if not (exclude_globs or include_globs):
     return None
   exclude_globs = list(exclude_globs or [])
-  if strip_resource_classes_for:
-    exclude_globs.extend(p.replace('.', '/') + '/' + f
-                         for p in strip_resource_classes_for
-                         for f in _RESOURCE_CLASSES)
   def path_transform(path):
     # Exclude filters take precidence over include filters.
     if build_utils.MatchesGlob(path, exclude_globs):
@@ -62,19 +47,13 @@
       help='GN list of exclude globs')
   parser.add_argument('--include-globs',
       help='GN list of include globs')
-  parser.add_argument('--strip-resource-classes-for',
-      help='GN list of java package names exclude R.class files in.')
-
   argv = build_utils.ExpandFileArgs(sys.argv[1:])
   args = parser.parse_args(argv)
 
   args.exclude_globs = build_utils.ParseGnList(args.exclude_globs)
   args.include_globs = build_utils.ParseGnList(args.include_globs)
-  args.strip_resource_classes_for = build_utils.ParseGnList(
-      args.strip_resource_classes_for)
 
-  path_transform = CreatePathTransform(args.exclude_globs, args.include_globs,
-                                       args.strip_resource_classes_for)
+  path_transform = CreatePathTransform(args.exclude_globs, args.include_globs)
   with build_utils.AtomicOutput(args.output) as f:
     if path_transform:
       build_utils.MergeZips(f.name, [args.input], path_transform=path_transform)
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 752ab30..a79f144 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -543,11 +543,6 @@
 `android_apk` and others), and contains information related to the compilation
 of Java sources, class files, and jars.
 
-* `javac['resource_packages']`
-For `java_library` targets, this is the list of package names for all resource
-dependencies for the current target. Order must match the one from
-`javac['srcjars']`. For other target types, this key does not exist.
-
 * `javac['classpath']`
 The classpath used to compile this target when annotation processors are
 present.
@@ -1494,10 +1489,6 @@
       deps_info['res_sources_path'] = options.res_sources_path
 
   if options.requires_android and options.type == 'java_library':
-    # Used to strip out R.class for android_prebuilt()s.
-    config['javac']['resource_packages'] = [
-        c['package_name'] for c in all_resources_deps if 'package_name' in c
-    ]
     if options.package_name:
       deps_info['package_name'] = options.package_name
 
diff --git a/build/args/headless.gn b/build/args/headless.gn
index 9b8392c..ed6308b 100644
--- a/build/args/headless.gn
+++ b/build/args/headless.gn
@@ -11,6 +11,8 @@
 ozone_auto_platforms = false
 ozone_platform = "headless"
 ozone_platform_headless = true
+angle_enable_vulkan = true
+angle_enable_swiftshader = true
 
 # Embed resource.pak into binary to simplify deployment.
 headless_use_embedded_resources = true
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 8e35d68e..7bd1a33 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -1828,8 +1828,6 @@
       if (defined(invoker.jar_included_patterns)) {
         _jar_included_patterns = invoker.jar_included_patterns
       }
-      _strip_resource_classes = defined(invoker.strip_resource_classes) &&
-                                invoker.strip_resource_classes
       args = [
         "--input",
         rebase_path(invoker.input_jar, root_build_dir),
@@ -1838,12 +1836,6 @@
         "--exclude-globs=${_jar_excluded_patterns}",
         "--include-globs=${_jar_included_patterns}",
       ]
-      if (_strip_resource_classes) {
-        inputs += [ invoker.build_config ]
-        _rebased_build_config =
-            rebase_path(invoker.build_config, root_build_dir)
-        args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ]
-      }
     }
   }
 
@@ -1852,7 +1844,6 @@
 
     _rebased_build_config = rebase_path(invoker.build_config, root_build_dir)
     not_needed([ "_rebased_build_config" ])
-    not_needed(invoker, [ "build_config_dep" ])
 
     _deps = invoker.jar_deps
     _previous_output_jar = invoker.input_jar_path
@@ -1871,17 +1862,11 @@
                                [
                                  "jar_excluded_patterns",
                                  "jar_included_patterns",
-                                 "strip_resource_classes",
                                ])
         deps = _deps
         input_jar = _previous_output_jar
         output_jar = _filter_jar_output_jar
         inputs = []
-        if (defined(strip_resource_classes) && strip_resource_classes) {
-          inputs += [ invoker.build_config ]
-          deps += [ invoker.build_config_dep ]
-          args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ]
-        }
         if (defined(invoker.inputs)) {
           inputs += invoker.inputs
           deps += invoker.input_deps
@@ -1969,17 +1954,11 @@
                                [
                                  "jar_excluded_patterns",
                                  "jar_included_patterns",
-                                 "strip_resource_classes",
                                ])
         deps = _deps
         input_jar = _previous_output_jar
         output_jar = _filter_jar_output_jar
         inputs = []
-        if (defined(strip_resource_classes) && strip_resource_classes) {
-          inputs += [ invoker.build_config ]
-          deps += [ invoker.build_config_dep ]
-          args += [ "--strip-resource-classes-for=@FileArg($_rebased_build_config:javac:resource_packages)" ]
-        }
         if (!defined(invoker.host_jar_path) && defined(invoker.inputs)) {
           inputs += invoker.inputs
           deps += invoker.input_deps
@@ -3962,7 +3941,6 @@
                                  "jar_included_patterns",
                                ])
         build_config = _build_config
-        build_config_dep = ":$_build_config_target_name"
         input_jar_path = _unprocessed_jar_path
         jar_deps = _unprocessed_jar_deps + _full_classpath_deps
         if (_build_host_jar) {
diff --git a/build/config/c++/BUILD.gn b/build/config/c++/BUILD.gn
index 6494bb0..09a2722c 100644
--- a/build/config/c++/BUILD.gn
+++ b/build/config/c++/BUILD.gn
@@ -33,6 +33,7 @@
   cflags = []
   cflags_cc = []
   defines = []
+  include_dirs = []
   ldflags = []
   libs = []
 
@@ -60,12 +61,9 @@
     }
   }
 
-  defines += [
-    "_LIBCPP_ENABLE_NODISCARD",
+  defines += [ "_LIBCPP_ENABLE_NODISCARD" ]
 
-    # TODO(crbug.com/1166707): libc++ requires this macro.
-    "_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS",
-  ]
+  include_dirs += [ "//buildtools/third_party/libc++" ]
 
   # Work around a symbol conflict between GRPC and the Fuchsia SDK.
   # TODO(crbug.com/1166970): Remove this when resolved.
diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni
index 8a29ede..27be1db 100644
--- a/build/config/c++/c++.gni
+++ b/build/config/c++/c++.gni
@@ -60,7 +60,7 @@
 # libc++abi needs to be exported from executables to be picked up by shared
 # libraries on certain instrumented builds.
 export_libcxxabi_from_executables =
-    use_custom_libcxx && !is_ios && !is_win && !is_component_build &&
+    use_custom_libcxx && !is_apple && !is_win && !is_component_build &&
     (is_asan || is_ubsan_vptr)
 
 # On Android, many shared libraries get loaded from the context of a JRE.  In
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index c1e14dc..88de18f 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -75,10 +75,7 @@
 
   # Enable fatal linker warnings. Building Chromium with certain versions
   # of binutils can cause linker warning.
-  # TODO(thakis): Set this to true unconditionally once lld/MachO no longer
-  # warns in mac intel->arm cross builds.
-  fatal_linker_warnings = !(is_apple && use_lld && ((target_cpu == "arm64" &&
-                            host_cpu != target_cpu) || is_asan))
+  fatal_linker_warnings = true
 
   # Build with C++ RTTI enabled. Chromium builds without RTTI by default,
   # but some sanitizers are known to require it, like CFI diagnostics
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 0614e56..32e1200 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -194,11 +194,9 @@
 
 declare_args() {
   # Set to true to use lld, the LLVM linker.
-  # Not supported for macOS (see docs/mac_lld.md), and not functional at all for
-  # iOS. But used for mac cross-compile on linux (may not work properly).
-  # The default linker everywhere else.
-  use_lld =
-      is_clang && (!is_apple || (target_os == "mac" && chrome_pgo_phase != 1))
+  # In late bring-up on macOS (see docs/mac_lld.md), and not functional at all for
+  # iOS. The default linker everywhere else.
+  use_lld = is_clang && (!is_apple || (target_os == "mac" && chrome_pgo_phase != 1))
 }
 
 declare_args() {
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index 7f4432d..19aa066 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -39,7 +39,7 @@
   # The SDK version used when making official builds. This is a single exact
   # version, not a minimum. If this version isn't available official builds
   # will fail.
-  mac_sdk_official_version = "11.1"
+  mac_sdk_official_version = "11.3"
 
   # Production builds should use hermetic Xcode. If you want to do production
   # builds with system Xcode to test new SDKs, set this.
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index df2b36f..59caa7b4 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -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("//build/config/c++/c++.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/clang/clang.gni")
 import("//build/config/compiler/compiler.gni")
@@ -490,8 +491,17 @@
 config("release_crt") {
   if (is_component_build) {
     cflags = [ "/MD" ]
+
+    if (use_custom_libcxx) {
+      # On Windows, including libcpmt[d]/msvcprt[d] explicitly links the C++
+      # standard library, which libc++ needs for exception_ptr internals.
+      ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
+    }
   } else {
     cflags = [ "/MT" ]
+    if (use_custom_libcxx) {
+      ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
+    }
   }
 }
 
@@ -499,8 +509,14 @@
   if (is_debug) {
     # This pulls in the DLL debug CRT and defines _DEBUG
     cflags = [ "/MDd" ]
+    if (use_custom_libcxx) {
+      ldflags = [ "/DEFAULTLIB:msvcprtd.lib" ]
+    }
   } else {
     cflags = [ "/MD" ]
+    if (use_custom_libcxx) {
+      ldflags = [ "/DEFAULTLIB:msvcprt.lib" ]
+    }
   }
 }
 
@@ -508,8 +524,14 @@
   if (is_debug) {
     # This pulls in the static debug CRT and defines _DEBUG
     cflags = [ "/MTd" ]
+    if (use_custom_libcxx) {
+      ldflags = [ "/DEFAULTLIB:libcpmtd.lib" ]
+    }
   } else {
     cflags = [ "/MT" ]
+    if (use_custom_libcxx) {
+      ldflags = [ "/DEFAULTLIB:libcpmt.lib" ]
+    }
   }
 }
 
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index b781a51..d8ad10ab 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-5.20210706.3.1
+5.20210708.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index cc8eb53..c6e8b97 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-5.20210706.2.1
+5.20210708.0.1
diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py
index 43d336cf..2dfdb43 100755
--- a/build/mac_toolchain.py
+++ b/build/mac_toolchain.py
@@ -38,10 +38,10 @@
     return plistlib.load(f)
 
 
-# This contains binaries from Xcode 12.4 12D4e, along with the macOS 11 SDK.
+# This contains binaries from Xcode 12.5 12E262, along with the macOS 11 SDK.
 # To build these packages, see comments in build/xcode_binaries.yaml
 MAC_BINARIES_LABEL = 'infra_internal/ios/xcode/xcode_binaries/mac-amd64'
-MAC_BINARIES_TAG = 'Za4aUIwiTUjk8rnjRow4nXbth-j7ZoN5plyOSCLidcgC'
+MAC_BINARIES_TAG = 'pBipKbKSkYGXpuOBm4-8zuvfIGeFtpGbQ4IHM9YW0xMC'
 
 # The toolchain will not be downloaded if the minimum OS version is not met. 19
 # is the major version number for macOS 10.15. 12B5044c (Xcode 12.2rc) only runs
diff --git a/build/nocompile.gni b/build/nocompile.gni
index 43193125..5b4aeb8f 100644
--- a/build/nocompile.gni
+++ b/build/nocompile.gni
@@ -103,13 +103,11 @@
         "-Wthread-safety",
         "-I" + rebase_path("//", root_build_dir),
         "-I" + rebase_path("//third_party/abseil-cpp/", root_build_dir),
+        "-I" + rebase_path("//buildtools/third_party/libc++/", root_build_dir),
         "-I" + rebase_path(root_gen_dir, root_build_dir),
 
         # TODO(https://crbug.com/989932): Track build/config/compiler/BUILD.gn
         "-Wno-implicit-int-float-conversion",
-
-        # TODO(crbug.com/1166707): libc++ now requires this macro to be defined.
-        "-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS",
       ]
 
       if (is_apple && host_os != "mac") {
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index d66c2a95..7495dd6a 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "8fa87946779682841e21e2da977eccfb6cb3bded"
+  libcxx_revision = "79a2e924d96e2fc1e4b937c42efd08898fa472d7"
 }
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
index 0dd09de..01d122a 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -10,11 +10,20 @@
 config("config") {
   cflags = [ "-fstrict-aliasing" ]
   if (is_win) {
-    # libc++ wants to redefine the macros WIN32_LEAN_AND_MEAN and _CRT_RAND_S in
-    # its implementation.
-    cflags += [ "-Wno-macro-redefined" ]
+    cflags += [
+      # libc++ wants to redefine the macros WIN32_LEAN_AND_MEAN and _CRT_RAND_S in
+      # its implementation.
+      "-Wno-macro-redefined",
+
+      # We want to use a uniform C++ version across all of chromium, but
+      # upstream libc++ requires C++17 so we have to make an exception here.
+      "-std:c++17",
+    ]
   } else {
-    cflags += [ "-fPIC" ]
+    cflags += [
+      "-fPIC",
+      "-std=c++17",
+    ]
   }
 }
 
diff --git a/buildtools/third_party/libc++/__config_site b/buildtools/third_party/libc++/__config_site
new file mode 100644
index 0000000..eedb9954
--- /dev/null
+++ b/buildtools/third_party/libc++/__config_site
@@ -0,0 +1,30 @@
+#ifndef _LIBCPP_CONFIG_SITE
+#define _LIBCPP_CONFIG_SITE
+
+/* #undef _LIBCPP_ABI_VERSION */
+/* #undef _LIBCPP_ABI_UNSTABLE */
+/* #undef _LIBCPP_ABI_FORCE_ITANIUM */
+/* #undef _LIBCPP_ABI_FORCE_MICROSOFT */
+/* #undef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT */
+/* #undef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE */
+/* #undef _LIBCPP_HAS_NO_STDIN */
+/* #undef _LIBCPP_HAS_NO_STDOUT */
+/* #undef _LIBCPP_HAS_NO_THREADS */
+/* #undef _LIBCPP_HAS_NO_MONOTONIC_CLOCK */
+/* #undef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS */
+/* #undef _LIBCPP_HAS_MUSL_LIBC */
+/* #undef _LIBCPP_HAS_THREAD_API_PTHREAD */
+/* #undef _LIBCPP_HAS_THREAD_API_EXTERNAL */
+/* #undef _LIBCPP_HAS_THREAD_API_WIN32 */
+/* #undef _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL */
+/* #undef _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS */
+#define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS
+/* #undef _LIBCPP_NO_VCRUNTIME */
+/* #undef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION */
+/* #undef _LIBCPP_ABI_NAMESPACE */
+/* #undef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY */
+/* #undef _LIBCPP_HAS_PARALLEL_ALGORITHMS */
+/* #undef _LIBCPP_HAS_NO_RANDOM_DEVICE */
+/* #undef _LIBCPP_HAS_NO_LOCALIZATION */
+
+#endif // _LIBCPP_CONFIG_SITE
diff --git a/cc/base/list_container_helper.cc b/cc/base/list_container_helper.cc
index 7b594b4..ea58696d 100644
--- a/cc/base/list_container_helper.cc
+++ b/cc/base/list_container_helper.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <cstring>
+#include <utility>
 #include <vector>
 
 #include "base/check_op.h"
@@ -271,6 +272,10 @@
 ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator(
     const ListContainerHelper::PositionInCharAllocator& other) = default;
 
+ListContainerHelper::PositionInCharAllocator&
+ListContainerHelper::PositionInCharAllocator::operator=(
+    const ListContainerHelper::PositionInCharAllocator& other) = default;
+
 ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator(
     ListContainerHelper::CharAllocator* container,
     size_t vector_ind,
diff --git a/cc/base/list_container_helper.h b/cc/base/list_container_helper.h
index 31658bc..7fc3bce 100644
--- a/cc/base/list_container_helper.h
+++ b/cc/base/list_container_helper.h
@@ -41,6 +41,7 @@
     char* item_iterator;
 
     PositionInCharAllocator(const PositionInCharAllocator& other);
+    PositionInCharAllocator& operator=(const PositionInCharAllocator& other);
 
     PositionInCharAllocator(CharAllocator* container,
                             size_t vector_ind,
diff --git a/cc/input/scroll_state_data.cc b/cc/input/scroll_state_data.cc
index 3409421c..97b5cf2 100644
--- a/cc/input/scroll_state_data.cc
+++ b/cc/input/scroll_state_data.cc
@@ -29,7 +29,9 @@
       is_scroll_chain_cut(false),
       is_main_thread_hit_tested(false) {}
 
-ScrollStateData::ScrollStateData(const ScrollStateData& other) = default;
+ScrollStateData::ScrollStateData(const ScrollStateData&) = default;
+
+ScrollStateData& ScrollStateData::operator=(const ScrollStateData&) = default;
 
 ElementId ScrollStateData::current_native_scrolling_element() const {
   return current_native_scrolling_element_;
diff --git a/cc/input/scroll_state_data.h b/cc/input/scroll_state_data.h
index 94f1506d..39fc235 100644
--- a/cc/input/scroll_state_data.h
+++ b/cc/input/scroll_state_data.h
@@ -17,6 +17,7 @@
  public:
   ScrollStateData();
   ScrollStateData(const ScrollStateData& other);
+  ScrollStateData& operator=(const ScrollStateData& other);
 
   // Scroll delta in viewport coordinates (DIP).
   double delta_x;
diff --git a/cc/metrics/begin_main_frame_metrics.cc b/cc/metrics/begin_main_frame_metrics.cc
index 04b6d8bb..effcada5 100644
--- a/cc/metrics/begin_main_frame_metrics.cc
+++ b/cc/metrics/begin_main_frame_metrics.cc
@@ -11,4 +11,7 @@
 BeginMainFrameMetrics::BeginMainFrameMetrics(
     const BeginMainFrameMetrics& other) = default;
 
+BeginMainFrameMetrics& BeginMainFrameMetrics::operator=(
+    const BeginMainFrameMetrics& other) = default;
+
 }  // namespace cc
diff --git a/cc/metrics/begin_main_frame_metrics.h b/cc/metrics/begin_main_frame_metrics.h
index 1f26384f..9514e62 100644
--- a/cc/metrics/begin_main_frame_metrics.h
+++ b/cc/metrics/begin_main_frame_metrics.h
@@ -33,6 +33,7 @@
   BeginMainFrameMetrics();
 
   BeginMainFrameMetrics(const BeginMainFrameMetrics& other);
+  BeginMainFrameMetrics& operator=(const BeginMainFrameMetrics& other);
 };
 
 }  // namespace cc
diff --git a/cc/test/task_graph_runner_test_template.h b/cc/test/task_graph_runner_test_template.h
index 21f71bee..c827015 100644
--- a/cc/test/task_graph_runner_test_template.h
+++ b/cc/test/task_graph_runner_test_template.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/simple_thread.h"
 #include "cc/raster/task_category.h"
diff --git a/cc/tiles/software_image_decode_cache_utils.cc b/cc/tiles/software_image_decode_cache_utils.cc
index e3198f2f..d3f38494 100644
--- a/cc/tiles/software_image_decode_cache_utils.cc
+++ b/cc/tiles/software_image_decode_cache_utils.cc
@@ -289,6 +289,10 @@
 SoftwareImageDecodeCacheUtils::CacheKey::CacheKey(const CacheKey& other) =
     default;
 
+SoftwareImageDecodeCacheUtils::CacheKey&
+SoftwareImageDecodeCacheUtils::CacheKey::operator=(const CacheKey& other) =
+    default;
+
 std::string SoftwareImageDecodeCacheUtils::CacheKey::ToString() const {
   std::ostringstream str;
   str << "frame_key[" << frame_key_.ToString() << "]\ntype[";
diff --git a/cc/tiles/software_image_decode_cache_utils.h b/cc/tiles/software_image_decode_cache_utils.h
index 071f7d21..964aa83 100644
--- a/cc/tiles/software_image_decode_cache_utils.h
+++ b/cc/tiles/software_image_decode_cache_utils.h
@@ -51,6 +51,7 @@
                                   SkColorType color_type);
 
     CacheKey(const CacheKey& other);
+    CacheKey& operator=(const CacheKey& other);
 
     bool operator==(const CacheKey& other) const {
       // The frame_key always has to be the same. However, after that all
diff --git a/cc/trees/clip_expander.cc b/cc/trees/clip_expander.cc
index 02df379..b4fbe77 100644
--- a/cc/trees/clip_expander.cc
+++ b/cc/trees/clip_expander.cc
@@ -14,6 +14,8 @@
 
 ClipExpander::ClipExpander(const ClipExpander& other) = default;
 
+ClipExpander& ClipExpander::operator=(const ClipExpander& other) = default;
+
 bool ClipExpander::operator==(const ClipExpander& other) const {
   return target_effect_id_ == other.target_effect_id_;
 }
diff --git a/cc/trees/clip_expander.h b/cc/trees/clip_expander.h
index 209477a..fef2ad5 100644
--- a/cc/trees/clip_expander.h
+++ b/cc/trees/clip_expander.h
@@ -16,6 +16,7 @@
  public:
   explicit ClipExpander(int filter_effect_id);
   ClipExpander(const ClipExpander& other);
+  ClipExpander& operator=(const ClipExpander& other);
 
   bool operator==(const ClipExpander& other) const;
 
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 34b7fea..eff1dd5 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -754,7 +754,7 @@
 
 void LayerTreeHost::DidPresentCompositorFrame(
     uint32_t frame_token,
-    std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+    std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks,
     const gfx::PresentationFeedback& feedback) {
   for (auto& callback : callbacks)
     std::move(callback).Run(feedback);
@@ -1127,7 +1127,7 @@
 }
 
 void LayerTreeHost::RequestPresentationTimeForNextFrame(
-    PresentationTimeCallback callback) {
+    PresentationTimeCallbackBuffer::MainCallback callback) {
   pending_presentation_time_callbacks_.push_back(std::move(callback));
 }
 
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 05cd4aa..547d5e34 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -41,6 +41,7 @@
 #include "cc/metrics/frame_sequence_tracker.h"
 #include "cc/metrics/web_vital_metrics.h"
 #include "cc/paint/node_id.h"
+#include "cc/trees//presentation_time_callback_buffer.h"
 #include "cc/trees/browser_controls_params.h"
 #include "cc/trees/compositor_mode.h"
 #include "cc/trees/layer_tree_frame_sink.h"
@@ -338,9 +339,8 @@
   // Registers a callback that is run when the next frame successfully makes it
   // to the screen (it's entirely possible some frames may be dropped between
   // the time this is called and the callback is run).
-  using PresentationTimeCallback =
-      base::OnceCallback<void(const gfx::PresentationFeedback&)>;
-  void RequestPresentationTimeForNextFrame(PresentationTimeCallback callback);
+  void RequestPresentationTimeForNextFrame(
+      PresentationTimeCallbackBuffer::MainCallback callback);
 
   // Registers a callback that is run when any ongoing scroll-animation ends. If
   // there are no ongoing animations, then the callback is run immediately.
@@ -628,7 +628,7 @@
   bool UpdateLayers();
   void DidPresentCompositorFrame(
       uint32_t frame_token,
-      std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+      std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks,
       const gfx::PresentationFeedback& feedback);
   // Called when the compositor completed page scale animation.
   void DidCompletePageScaleAnimation();
@@ -958,7 +958,8 @@
 
   // Presentation time callbacks requested for the next frame are initially
   // added here.
-  std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_;
+  std::vector<PresentationTimeCallbackBuffer::MainCallback>
+      pending_presentation_time_callbacks_;
 
   struct ScrollAnimationState {
     ScrollAnimationState();
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 41a143a1..317e9d6 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -244,16 +244,16 @@
     return;
   }
 
-  // Construct a callback that, given presentation feedback, will report the
-  // time span between the scroll input-event creation and the
+  // Construct a callback that, given a successful presentation timestamp, will
+  // report the time span between the scroll input-event creation and the
   // presentation timestamp.
-  LayerTreeHost::PresentationTimeCallback presentation_callback =
+  PresentationTimeCallbackBuffer::CompositorCallback presentation_callback =
       base::BindOnce(
           [](base::TimeTicks event_creation,
              LayerTreeHostImpl* layer_tree_host_impl,
-             const gfx::PresentationFeedback& feedback) {
+             base::TimeTicks presentation_timestamp) {
             layer_tree_host_impl->DidObserveScrollDelay(
-                feedback.timestamp - event_creation, event_creation);
+                presentation_timestamp - event_creation, event_creation);
           },
           creation_timestamp, impl);
 
@@ -2049,8 +2049,14 @@
 void LayerTreeHostImpl::DidPresentCompositorFrame(
     uint32_t frame_token,
     const viz::FrameTimingDetails& details) {
+  // Presentation callbacks registered on the compositor thread are expected to
+  // be called on the first successful presentation. So, if the presentation is
+  // failed, we only pop main thread callbacks at this point and leave
+  // compositor thread callbacks alone until a successful presentation.
+  const bool main_callbacks_only = details.presentation_feedback.failed();
   PresentationTimeCallbackBuffer::PendingCallbacks activated_callbacks =
-      presentation_time_callbacks_.PopPendingCallbacks(frame_token);
+      presentation_time_callbacks_.PopPendingCallbacks(frame_token,
+                                                       main_callbacks_only);
 
   // Send all tasks to the client so that it can decide which tasks
   // should run on which thread.
@@ -2819,20 +2825,20 @@
   SetRequiresHighResToDraw();
 }
 
-void LayerTreeHostImpl::RegisterMainThreadPresentationTimeCallback(
+void LayerTreeHostImpl::RegisterMainThreadPresentationTimeCallbackForTesting(
     uint32_t frame_token,
-    LayerTreeHost::PresentationTimeCallback callback) {
-  std::vector<LayerTreeHost::PresentationTimeCallback> as_vector;
-  as_vector.emplace_back(std::move(callback));
+    PresentationTimeCallbackBuffer::MainCallback callback) {
+  std::vector<PresentationTimeCallbackBuffer::MainCallback> as_vector;
+  as_vector.push_back(std::move(callback));
   presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks(
       frame_token, std::move(as_vector));
 }
 
 void LayerTreeHostImpl::RegisterCompositorPresentationTimeCallback(
     uint32_t frame_token,
-    LayerTreeHost::PresentationTimeCallback callback) {
-  std::vector<LayerTreeHost::PresentationTimeCallback> as_vector;
-  as_vector.emplace_back(std::move(callback));
+    PresentationTimeCallbackBuffer::CompositorCallback callback) {
+  std::vector<PresentationTimeCallbackBuffer::CompositorCallback> as_vector;
+  as_vector.push_back(std::move(callback));
   presentation_time_callbacks_.RegisterCompositorPresentationCallbacks(
       frame_token, std::move(as_vector));
 }
@@ -4970,13 +4976,12 @@
 
 void LayerTreeHostImpl::NotifyDidPresentCompositorFrameOnImplThread(
     uint32_t frame_token,
-    std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+    std::vector<PresentationTimeCallbackBuffer::CompositorCallback> callbacks,
     const viz::FrameTimingDetails& details) {
   frame_trackers_.NotifyFramePresented(frame_token,
                                        details.presentation_feedback);
-  for (LayerTreeHost::PresentationTimeCallback& callback : callbacks) {
-    std::move(callback).Run(details.presentation_feedback);
-  }
+  for (auto& callback : callbacks)
+    std::move(callback).Run(details.presentation_feedback.timestamp);
 }
 
 void LayerTreeHostImpl::AllocateLocalSurfaceId() {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 105df86..8e0337d5 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -601,21 +601,21 @@
 
   uint32_t next_frame_token() const { return *next_frame_token_; }
 
-  // Buffers |callback| until a relevant frame swap ocurrs, at which point the
-  // callback will be posted to run on the main thread. A frame swap is
-  // considered relevant if the swapped frame's token is greater than or equal
-  // to |frame_token|.
-  void RegisterMainThreadPresentationTimeCallback(
+  // Buffers `callback` until a relevant presentation feedback arrives, at which
+  // point the callback will be posted to run on the main thread. A presentation
+  // feedback is considered relevant if the frame's token is greater than or
+  // equal to `frame_token`.
+  void RegisterMainThreadPresentationTimeCallbackForTesting(
       uint32_t frame_token,
-      LayerTreeHost::PresentationTimeCallback callback);
+      PresentationTimeCallbackBuffer::MainCallback callback);
 
-  // Buffers |callback| until a relevant frame swap ocurrs, at which point the
-  // callback will be run on the compositor thread. A frame swap is considered
-  // relevant if the swapped frame's token is greater than or equal to
-  // |frame_token|.
+  // Buffers `callback` until a relevant successful presentation occurs, at
+  // which point the callback will be run on the compositor thread. A successful
+  // presentation is considered relevant if the presented frame's token is
+  // greater than or equal to `frame_token`.
   void RegisterCompositorPresentationTimeCallback(
       uint32_t frame_token,
-      LayerTreeHost::PresentationTimeCallback callback);
+      PresentationTimeCallbackBuffer::CompositorCallback callback);
 
   virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args);
   virtual void DidFinishImplFrame(const viz::BeginFrameArgs& args);
@@ -830,7 +830,7 @@
   // was presented.
   void NotifyDidPresentCompositorFrameOnImplThread(
       uint32_t frame_token,
-      std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+      std::vector<PresentationTimeCallbackBuffer::CompositorCallback> callbacks,
       const viz::FrameTimingDetails& details);
 
   CompositorFrameReportingController* compositor_frame_reporting_controller()
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 7788c5de..c499105 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1691,10 +1691,8 @@
     auto main_thread_callbacks = std::move(activated.main_thread_callbacks);
     host_impl_->NotifyDidPresentCompositorFrameOnImplThread(
         frame_token, std::move(activated.compositor_thread_callbacks), details);
-    for (LayerTreeHost::PresentationTimeCallback& callback :
-         main_thread_callbacks) {
+    for (auto& callback : main_thread_callbacks)
       std::move(callback).Run(details.presentation_feedback);
-    }
   }
 };
 
@@ -1704,25 +1702,27 @@
        PresentationFeedbackCallbacksFire) {
   bool compositor_thread_callback_fired = false;
   bool main_thread_callback_fired = false;
-  gfx::PresentationFeedback feedback_seen_by_compositor_thread_callback;
+  base::TimeTicks presentation_time_seen_by_compositor_thread_callback;
   gfx::PresentationFeedback feedback_seen_by_main_thread_callback;
 
   // Register a compositor-thread callback to run when the frame for
   // |frame_token_1| gets presented.
   constexpr uint32_t frame_token_1 = 1;
   host_impl_->RegisterCompositorPresentationTimeCallback(
-      frame_token_1, base::BindLambdaForTesting(
-                         [&](const gfx::PresentationFeedback& feedback) {
-                           compositor_thread_callback_fired = true;
-                           feedback_seen_by_compositor_thread_callback =
-                               feedback;
-                         }));
+      frame_token_1,
+      base::BindLambdaForTesting([&](base::TimeTicks presentation_timestamp) {
+        DCHECK(presentation_time_seen_by_compositor_thread_callback.is_null());
+        DCHECK(!presentation_timestamp.is_null());
+        compositor_thread_callback_fired = true;
+        presentation_time_seen_by_compositor_thread_callback =
+            presentation_timestamp;
+      }));
 
   // Register a main-thread callback to run when the frame for |frame_token_2|
   // gets presented.
   constexpr uint32_t frame_token_2 = 2;
   ASSERT_GT(frame_token_2, frame_token_1);
-  host_impl_->RegisterMainThreadPresentationTimeCallback(
+  host_impl_->RegisterMainThreadPresentationTimeCallbackForTesting(
       frame_token_2, base::BindLambdaForTesting(
                          [&](const gfx::PresentationFeedback& feedback) {
                            main_thread_callback_fired = true;
@@ -1735,8 +1735,8 @@
   host_impl_->DidPresentCompositorFrame(frame_token_1, mock_details);
 
   EXPECT_TRUE(compositor_thread_callback_fired);
-  EXPECT_EQ(feedback_seen_by_compositor_thread_callback,
-            mock_details.presentation_feedback);
+  EXPECT_EQ(presentation_time_seen_by_compositor_thread_callback,
+            mock_details.presentation_feedback.timestamp);
 
   // Since |frame_token_2| is strictly greater than |frame_token_1|, the
   // main-thread callback must remain queued for now.
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 3816eb5..152aba7e 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -805,15 +805,15 @@
 }
 
 void LayerTreeImpl::AddPresentationCallbacks(
-    std::vector<LayerTreeHost::PresentationTimeCallback> callbacks) {
+    std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks) {
   std::copy(std::make_move_iterator(callbacks.begin()),
             std::make_move_iterator(callbacks.end()),
             std::back_inserter(presentation_callbacks_));
 }
 
-std::vector<LayerTreeHost::PresentationTimeCallback>
+std::vector<PresentationTimeCallbackBuffer::MainCallback>
 LayerTreeImpl::TakePresentationCallbacks() {
-  std::vector<LayerTreeHost::PresentationTimeCallback> callbacks;
+  std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks;
   callbacks.swap(presentation_callbacks_);
   return callbacks;
 }
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 1972afa..58076d0 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -284,8 +284,8 @@
   gfx::ScrollOffset TotalMaxScrollOffset() const;
 
   void AddPresentationCallbacks(
-      std::vector<LayerTreeHost::PresentationTimeCallback> callbacks);
-  std::vector<LayerTreeHost::PresentationTimeCallback>
+      std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks);
+  std::vector<PresentationTimeCallbackBuffer::MainCallback>
   TakePresentationCallbacks();
   bool has_presentation_callbacks() const {
     return !presentation_callbacks_.empty();
@@ -918,7 +918,8 @@
   // Display transform hint to tag frames generated from this tree.
   gfx::OverlayTransform display_transform_hint_ = gfx::OVERLAY_TRANSFORM_NONE;
 
-  std::vector<LayerTreeHost::PresentationTimeCallback> presentation_callbacks_;
+  std::vector<PresentationTimeCallbackBuffer::MainCallback>
+      presentation_callbacks_;
 
   // Event metrics that are reported back from the main thread.
   EventMetrics::List events_metrics_from_main_thread_;
diff --git a/cc/trees/presentation_time_callback_buffer.cc b/cc/trees/presentation_time_callback_buffer.cc
index c6de964c..7ae602b 100644
--- a/cc/trees/presentation_time_callback_buffer.cc
+++ b/cc/trees/presentation_time_callback_buffer.cc
@@ -7,6 +7,8 @@
 #include <utility>
 #include <vector>
 
+#include "components/viz/common/quads/compositor_frame_metadata.h"
+
 namespace cc {
 
 PresentationTimeCallbackBuffer::PresentationTimeCallbackBuffer() = default;
@@ -37,7 +39,7 @@
 
 void PresentationTimeCallbackBuffer::RegisterMainThreadPresentationCallbacks(
     uint32_t frame_token,
-    std::vector<CallbackType> callbacks) {
+    std::vector<MainCallback> callbacks) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   FrameTokenInfo& frame_info = GetOrMakeRegistration(frame_token);
 
@@ -45,20 +47,16 @@
   auto& sink = frame_info.main_thread_callbacks;
   sink.reserve(sink.size() + callbacks.size());
   std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink));
-
-  DCHECK_LE(frame_token_infos_.size(), 25u);
 }
 
 void PresentationTimeCallbackBuffer::RegisterCompositorPresentationCallbacks(
     uint32_t frame_token,
-    std::vector<CallbackType> callbacks) {
+    std::vector<CompositorCallback> callbacks) {
   // Splice the given |callbacks| onto the vector of existing callbacks.
-  std::vector<LayerTreeHost::PresentationTimeCallback>& sink =
+  std::vector<CompositorCallback>& sink =
       GetOrMakeRegistration(frame_token).compositor_thread_callbacks;
   sink.reserve(sink.size() + callbacks.size());
   std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink));
-
-  DCHECK_LE(frame_token_infos_.size(), 25u);
 }
 
 PresentationTimeCallbackBuffer::PendingCallbacks::PendingCallbacks() = default;
@@ -70,29 +68,33 @@
 PresentationTimeCallbackBuffer::PendingCallbacks::~PendingCallbacks() = default;
 
 PresentationTimeCallbackBuffer::PendingCallbacks
-PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token) {
+PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token,
+                                                    bool main_only) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   PendingCallbacks result;
 
-  while (!frame_token_infos_.empty()) {
-    auto info = frame_token_infos_.begin();
+  for (auto info = frame_token_infos_.begin();
+       info != frame_token_infos_.end();) {
     if (viz::FrameTokenGT(info->token, frame_token))
       break;
 
-    // Collect the main-thread callbacks. It's the caller's job to post them to
-    // the main thread.
     std::move(info->main_thread_callbacks.begin(),
               info->main_thread_callbacks.end(),
               std::back_inserter(result.main_thread_callbacks));
+    info->main_thread_callbacks.clear();
 
-    // Collect the compositor-thread callbacks. It's the caller's job to run
-    // them on the compositor thread.
-    std::move(info->compositor_thread_callbacks.begin(),
-              info->compositor_thread_callbacks.end(),
-              std::back_inserter(result.compositor_thread_callbacks));
+    const bool should_keep_callbacks =
+        main_only && !info->compositor_thread_callbacks.empty();
 
-    frame_token_infos_.erase(info);
+    if (should_keep_callbacks) {
+      ++info;
+    } else {
+      std::move(info->compositor_thread_callbacks.begin(),
+                info->compositor_thread_callbacks.end(),
+                std::back_inserter(result.compositor_thread_callbacks));
+      info = frame_token_infos_.erase(info);
+    }
   }
 
   return result;
@@ -105,6 +107,7 @@
   if (frame_token_infos_.empty() ||
       viz::FrameTokenGT(frame_token, frame_token_infos_.back().token)) {
     frame_token_infos_.emplace_back(frame_token);
+    DCHECK_LE(frame_token_infos_.size(), 25u);
   }
 
   // Registrations should use monotonically increasing frame tokens.
diff --git a/cc/trees/presentation_time_callback_buffer.h b/cc/trees/presentation_time_callback_buffer.h
index 820b8fc3..ab36aa5 100644
--- a/cc/trees/presentation_time_callback_buffer.h
+++ b/cc/trees/presentation_time_callback_buffer.h
@@ -6,9 +6,11 @@
 
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/containers/circular_deque.h"
 #include "base/sequence_checker.h"
-#include "cc/trees/layer_tree_host.h"
+#include "cc/cc_export.h"
+#include "ui/gfx/presentation_feedback.h"
 
 namespace cc {
 
@@ -32,7 +34,15 @@
 // CC_EXPORT is only needed for testing.
 class CC_EXPORT PresentationTimeCallbackBuffer {
  public:
-  using CallbackType = LayerTreeHost::PresentationTimeCallback;
+  // TODO(crbug.com/1199373): Compositor thread callbacks are only run for
+  // successful presentations and only need the presentation timestamp. On the
+  // other hand, main thread callbacks can be run on both successful and failed
+  // presentations and need a full `gfx::PresentationFeedback`. Conceptually,
+  // main thread callbacks should only be run for successful presentations, too,
+  // in which case the two callback signatures can be unified.
+  using MainCallback =
+      base::OnceCallback<void(const gfx::PresentationFeedback&)>;
+  using CompositorCallback = base::OnceCallback<void(base::TimeTicks)>;
 
   PresentationTimeCallbackBuffer();
 
@@ -51,14 +61,14 @@
   // main thread once they're popped.
   void RegisterMainThreadPresentationCallbacks(
       uint32_t frame_token,
-      std::vector<CallbackType> callbacks);
+      std::vector<MainCallback> callbacks);
 
   // Buffers the given |callbacks| in preparation for a GPU frame swap at or
   // after the given |frame_token|. Calling code invokes these callbacks on the
   // compositor thread once they're popped.
   void RegisterCompositorPresentationCallbacks(
       uint32_t frame_token,
-      std::vector<CallbackType> callbacks);
+      std::vector<CompositorCallback> callbacks);
 
   // Structured return value for |PopPendingCallbacks|. CC_EXPORT is only
   // needed for testing.
@@ -75,18 +85,19 @@
 
     // Holds callbacks registered through
     // |RegisterMainThreadPresentationCallbacks|.
-    std::vector<CallbackType> main_thread_callbacks;
+    std::vector<MainCallback> main_thread_callbacks;
 
     // Holds callbacks registered through
     // |RegisterCompositorPresentationCallbacks|.
-    std::vector<CallbackType> compositor_thread_callbacks;
+    std::vector<CompositorCallback> compositor_thread_callbacks;
   };
 
-  // Call this once the presentation for the given |frame_token| has completed.
+  // Call this once the presentation for the given `frame_token` has completed.
   // Yields any pending callbacks that were registered against a frame token
-  // that was less than or equal to the given |frame_token|. It is the caller's
+  // that was less than or equal to the given `frame_token`. If `main_only` is
+  // true, only callbacks for the main thread are returned. It is the caller's
   // responsibility to run the callbacks on the right threads/sequences.
-  PendingCallbacks PopPendingCallbacks(uint32_t frame_token);
+  PendingCallbacks PopPendingCallbacks(uint32_t frame_token, bool main_only);
 
  private:
   // Stores information needed once we get a response for a particular
@@ -104,10 +115,10 @@
     uint32_t token;
 
     // The callbacks to send back to the main thread.
-    std::vector<CallbackType> main_thread_callbacks;
+    std::vector<MainCallback> main_thread_callbacks;
 
     // The callbacks to invoke on the compositor thread.
-    std::vector<CallbackType> compositor_thread_callbacks;
+    std::vector<CompositorCallback> compositor_thread_callbacks;
   };
 
   // Returns a reference to a |FrameTokenInfo| with the given |frame_token|.
diff --git a/cc/trees/presentation_time_callback_buffer_unittest.cc b/cc/trees/presentation_time_callback_buffer_unittest.cc
index 6b8aa1e0..ee68a89 100644
--- a/cc/trees/presentation_time_callback_buffer_unittest.cc
+++ b/cc/trees/presentation_time_callback_buffer_unittest.cc
@@ -4,16 +4,18 @@
 
 #include "cc/trees/presentation_time_callback_buffer.h"
 
+#include "base/bind.h"
+#include "base/callback.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
 
-std::vector<cc::PresentationTimeCallbackBuffer::CallbackType> GenerateCallbacks(
-    int num_callbacks) {
-  std::vector<cc::PresentationTimeCallbackBuffer::CallbackType> result;
+std::vector<cc::PresentationTimeCallbackBuffer::MainCallback>
+GenerateMainCallbacks(int num_callbacks) {
+  std::vector<cc::PresentationTimeCallbackBuffer::MainCallback> result;
 
   while (num_callbacks-- > 0) {
-    // PresentationTimeCallbackBuffer isn't supposed to invoke any callbacks.
+    // `PresentationTimeCallbackBuffer` isn't supposed to invoke any callbacks.
     // We can check for that by passing callbacks which cause test failure.
     result.push_back(base::BindOnce([](const gfx::PresentationFeedback&) {
       FAIL() << "Callbacks should not be directly invoked by "
@@ -24,6 +26,22 @@
   return result;
 }
 
+std::vector<cc::PresentationTimeCallbackBuffer::CompositorCallback>
+GenerateCompositorCallbacks(int num_callbacks) {
+  std::vector<cc::PresentationTimeCallbackBuffer::CompositorCallback> result;
+
+  while (num_callbacks-- > 0) {
+    // `PresentationTimeCallbackBuffer` isn't supposed to invoke any callbacks.
+    // We can check for that by passing callbacks which cause test failure.
+    result.push_back(base::BindOnce([](base::TimeTicks presentation_timestamp) {
+      FAIL() << "Callbacks should not be directly invoked by "
+                "PresentationTimeCallbackBuffer";
+    }));
+  }
+
+  return result;
+}
+
 constexpr uint32_t kFrameToken1 = 234;
 constexpr uint32_t kFrameToken2 = 345;
 constexpr uint32_t kFrameToken3 = 456;
@@ -36,7 +54,7 @@
 TEST(PresentationTimeCallbackBufferTest, TestNoCallbacks) {
   PresentationTimeCallbackBuffer buffer;
 
-  auto result = buffer.PopPendingCallbacks(kFrameToken1);
+  auto result = buffer.PopPendingCallbacks(kFrameToken1, false);
 
   EXPECT_TRUE(result.main_thread_callbacks.empty());
   EXPECT_TRUE(result.compositor_thread_callbacks.empty());
@@ -46,25 +64,25 @@
   PresentationTimeCallbackBuffer buffer;
 
   buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
-                                                 GenerateCallbacks(1));
+                                                 GenerateMainCallbacks(1));
 
   // Make sure that popping early frame tokens doesn't return irrelevant
   // entries.
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken1);
+    auto result = buffer.PopPendingCallbacks(kFrameToken1, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
 
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
 
   // Make sure that the buffer has removed the registration since the "pop".
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
@@ -73,26 +91,26 @@
 TEST(PresentationTimeCallbackBufferTest, TestOneCompositorThreadCallback) {
   PresentationTimeCallbackBuffer buffer;
 
-  buffer.RegisterCompositorPresentationCallbacks(kFrameToken2,
-                                                 GenerateCallbacks(1));
+  buffer.RegisterCompositorPresentationCallbacks(
+      kFrameToken2, GenerateCompositorCallbacks(1));
 
   // Make sure that popping early frame tokens doesn't return irrelevant
   // entries.
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken1);
+    auto result = buffer.PopPendingCallbacks(kFrameToken1, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
 
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull);
   }
 
   // Make sure that the buffer has removed the registration since the "pop".
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
@@ -102,27 +120,27 @@
   PresentationTimeCallbackBuffer buffer;
 
   buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
-                                                 GenerateCallbacks(1));
-  buffer.RegisterCompositorPresentationCallbacks(kFrameToken2,
-                                                 GenerateCallbacks(1));
+                                                 GenerateMainCallbacks(1));
+  buffer.RegisterCompositorPresentationCallbacks(
+      kFrameToken2, GenerateCompositorCallbacks(1));
 
   // Make sure that popping early frame tokens doesn't return irrelevant
   // entries.
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken1);
+    auto result = buffer.PopPendingCallbacks(kFrameToken1, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
 
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
     EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull);
   }
 
   // Make sure that the buffer has removed the registrations since the "pop".
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken2);
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, false);
     EXPECT_TRUE(result.main_thread_callbacks.empty());
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
@@ -133,19 +151,66 @@
 
   // Register one callback for frame1, two for frame2 and two for frame4.
   buffer.RegisterMainThreadPresentationCallbacks(kFrameToken1,
-                                                 GenerateCallbacks(1));
+                                                 GenerateMainCallbacks(1));
   buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
-                                                 GenerateCallbacks(2));
+                                                 GenerateMainCallbacks(2));
   buffer.RegisterMainThreadPresentationCallbacks(kFrameToken4,
-                                                 GenerateCallbacks(2));
+                                                 GenerateMainCallbacks(2));
 
   // Pop callbacks up to and including frame3. Should be three in total; one
   // from frame1 and two from frame2.
   {
-    auto result = buffer.PopPendingCallbacks(kFrameToken3);
+    auto result = buffer.PopPendingCallbacks(kFrameToken3, false);
     EXPECT_EQ(result.main_thread_callbacks.size(), 3ull);
     EXPECT_TRUE(result.compositor_thread_callbacks.empty());
   }
 }
 
+// Tests that popping callbacks for main thread only vs. for both main and
+// compositor threads works properly.
+TEST(PresentationTimeCallbackBufferTest, PopMainCallbacksOnly) {
+  PresentationTimeCallbackBuffer buffer;
+
+  // Register callbacks for main and compositor threads of 3 frames.
+  buffer.RegisterMainThreadPresentationCallbacks(kFrameToken1,
+                                                 GenerateMainCallbacks(1));
+  buffer.RegisterCompositorPresentationCallbacks(
+      kFrameToken1, GenerateCompositorCallbacks(1));
+  buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2,
+                                                 GenerateMainCallbacks(1));
+  buffer.RegisterCompositorPresentationCallbacks(
+      kFrameToken2, GenerateCompositorCallbacks(1));
+  buffer.RegisterMainThreadPresentationCallbacks(kFrameToken3,
+                                                 GenerateMainCallbacks(1));
+  buffer.RegisterCompositorPresentationCallbacks(
+      kFrameToken3, GenerateCompositorCallbacks(1));
+
+  // Pop only main thread callbacks up to and including frame1. The result
+  // should only contain 1 main thread callback of frame1 and no compositor
+  // thread callback.
+  {
+    auto result = buffer.PopPendingCallbacks(kFrameToken1, true);
+    EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
+    EXPECT_TRUE(result.compositor_thread_callbacks.empty());
+  }
+
+  // Pop only main thread callbacks up to and including frame2. The result
+  // should only contain 1 main thread callback of frame2 and no compositor
+  // thread callback.
+  {
+    auto result = buffer.PopPendingCallbacks(kFrameToken2, true);
+    EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
+    EXPECT_TRUE(result.compositor_thread_callbacks.empty());
+  }
+
+  // Pop both main and compositor thread callbacks up to and including frame3.
+  // The result should contain 1 main thread callback of frame3 and all 3
+  // compositor thread callbacks of the 3 frames.
+  {
+    auto result = buffer.PopPendingCallbacks(kFrameToken3, false);
+    EXPECT_EQ(result.main_thread_callbacks.size(), 1ull);
+    EXPECT_EQ(result.compositor_thread_callbacks.size(), 3ull);
+  }
+}
+
 }  // namespace cc
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc
index ce7d26f..c91c070 100644
--- a/cc/trees/proxy_main.cc
+++ b/cc/trees/proxy_main.cc
@@ -387,7 +387,7 @@
 
 void ProxyMain::DidPresentCompositorFrame(
     uint32_t frame_token,
-    std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+    std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks,
     const gfx::PresentationFeedback& feedback) {
   layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks),
                                               feedback);
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h
index 3c7d3bb8..d133549 100644
--- a/cc/trees/proxy_main.h
+++ b/cc/trees/proxy_main.h
@@ -58,7 +58,7 @@
       std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state);
   void DidPresentCompositorFrame(
       uint32_t frame_token,
-      std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
+      std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks,
       const gfx::PresentationFeedback& feedback);
   void NotifyThroughputTrackerResults(CustomTrackerResults results);
   void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay,
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index a7daf89..c46ce98 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -540,15 +540,13 @@
     uint32_t frame_token,
     PresentationTimeCallbackBuffer::PendingCallbacks callbacks,
     const viz::FrameTimingDetails& details) {
-  std::vector<LayerTreeHost::PresentationTimeCallback> main_thread_callbacks =
-      std::move(callbacks.main_thread_callbacks);
   DebugScopedSetImplThread impl(task_runner_provider_);
   host_impl_->NotifyDidPresentCompositorFrameOnImplThread(
       frame_token, std::move(callbacks.compositor_thread_callbacks), details);
   {
     DebugScopedSetMainThread main(task_runner_provider_);
     layer_tree_host_->DidPresentCompositorFrame(
-        frame_token, std::move(main_thread_callbacks),
+        frame_token, std::move(callbacks.main_thread_callbacks),
         details.presentation_feedback);
   }
   if (scheduler_on_impl_thread_) {
diff --git a/cc/trees/sticky_position_constraint.cc b/cc/trees/sticky_position_constraint.cc
index 19f4cabe..bc16393 100644
--- a/cc/trees/sticky_position_constraint.cc
+++ b/cc/trees/sticky_position_constraint.cc
@@ -19,6 +19,9 @@
 StickyPositionConstraint::StickyPositionConstraint(
     const StickyPositionConstraint& other) = default;
 
+StickyPositionConstraint& StickyPositionConstraint::operator=(
+    const StickyPositionConstraint& other) = default;
+
 bool StickyPositionConstraint::operator==(
     const StickyPositionConstraint& other) const {
   return is_anchored_left == other.is_anchored_left &&
diff --git a/cc/trees/sticky_position_constraint.h b/cc/trees/sticky_position_constraint.h
index 3a6ac240..94b0167 100644
--- a/cc/trees/sticky_position_constraint.h
+++ b/cc/trees/sticky_position_constraint.h
@@ -17,6 +17,7 @@
 struct CC_EXPORT StickyPositionConstraint {
   StickyPositionConstraint();
   StickyPositionConstraint(const StickyPositionConstraint& other);
+  StickyPositionConstraint& operator=(const StickyPositionConstraint& other);
 
   bool is_anchored_left : 1;
   bool is_anchored_right : 1;
diff --git a/cc/trees/transform_node.cc b/cc/trees/transform_node.cc
index 1c91fcae..765b6fb 100644
--- a/cc/trees/transform_node.cc
+++ b/cc/trees/transform_node.cc
@@ -39,6 +39,8 @@
 
 TransformNode::TransformNode(const TransformNode&) = default;
 
+TransformNode& TransformNode::operator=(const TransformNode&) = default;
+
 #if DCHECK_IS_ON()
 bool TransformNode::operator==(const TransformNode& other) const {
   return id == other.id && parent_id == other.parent_id &&
diff --git a/cc/trees/transform_node.h b/cc/trees/transform_node.h
index 71d8e98f..2e62467 100644
--- a/cc/trees/transform_node.h
+++ b/cc/trees/transform_node.h
@@ -23,6 +23,7 @@
 struct CC_EXPORT TransformNode {
   TransformNode();
   TransformNode(const TransformNode&);
+  TransformNode& operator=(const TransformNode&);
 
   // The node index of this node in the transform tree node vector.
   int id;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 2119244..cbf2ef11 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/cipd/cipd.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/compiler/compiler.gni")
@@ -1360,6 +1359,10 @@
     public_deps += [ "//components/nacl/browser" ]
   }
 
+  if (is_chromeos_ash || is_chromeos_lacros) {
+    public_deps += [ "//chromeos/dbus/constants" ]
+  }
+
   if (is_chromeos_lacros) {
     public_deps += [ "//chromeos/lacros" ]
   }
@@ -1369,7 +1372,6 @@
       "//ash/constants",
       "//chrome/browser/chromeos",
       "//chromeos",
-      "//chromeos/dbus/constants",
       "//chromeos/memory",
     ]
   }
@@ -1831,17 +1833,3 @@
     deps = [ ":chrome" ]
   }
 }
-
-# This target is for Lacros version skew testing.
-if (is_chromeos_ash) {
-  cipd_package_definition_by_file("gen_linux_ash_chromium_cipd_yaml") {
-    testonly = true
-    buildtype = "dev"
-    arch = "64bit"
-    files_file = "//chrome/tools/build/chromeos/FILES.cfg"
-    package = "chromium/testing/linux-ash-chromium/x86_64/ash.zip"
-    description = "Prebuilt test binary."
-    install_mode = "copy"
-    deps = [ ":chrome" ]
-  }
-}
diff --git a/chrome/VERSION b/chrome/VERSION
index f3be993..0217f36 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=93
 MINOR=0
-BUILD=4569
+BUILD=4570
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index b120b2ad..08999fee 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -320,6 +320,7 @@
     "//chrome/android/webapk/libs/common:common_java",
     "//chrome/android/webapk/libs/common:splash_java",
     "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/android/browserservices/intents:java",
     "//chrome/browser/android/browserservices/metrics:java",
     "//chrome/browser/android/browserservices/verification:java",
@@ -810,8 +811,6 @@
     "//chrome/browser/android/webapk/webapk_install_service.h",
     "//chrome/browser/android/webapk/webapk_installer.h",
     "//chrome/browser/download/android/download_open_source.h",
-    "//chrome/browser/installable/installed_webapp_geolocation_bridge.cc",
-    "//chrome/browser/installable/quality_enforcer.cc",
     "//chrome/browser/long_screenshots/long_screenshots_tab_service.h",
     "//chrome/browser/notifications/notification_handler.h",
     "//chrome/browser/notifications/notification_platform_bridge_android.cc",
@@ -898,6 +897,7 @@
     "//chrome/android/webapk/libs/common:common_java",
     "//chrome/android/webapk/libs/common:splash_java",
     "//chrome/android/webapk/test:junit_test_support",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/android/browserservices/intents:java",
     "//chrome/browser/android/browserservices/intents:junit",
     "//chrome/browser/android/browserservices/verification:java",
@@ -1197,6 +1197,7 @@
     "//chrome/android/features/tab_ui:java_resources",
     "//chrome/android/webapk/libs/client:client_java",
     "//chrome/android/webapk/libs/common:common_java",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/android/browserservices/intents:java",
     "//chrome/browser/android/browserservices/verification:java",
     "//chrome/browser/android/browserservices/verification:javatests",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
index 80a65538..5ae9a58af 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayCoordinator.java
@@ -5,8 +5,8 @@
 package org.chromium.chrome.browser.autofill_assistant.overlay;
 
 import android.content.Context;
-import android.graphics.RectF;
 
+import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel.AssistantOverlayRect;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
@@ -50,11 +50,11 @@
                 mEventFilter.setWebContents(webContents);
                 mDrawable.setWebContents(webContents);
             } else if (AssistantOverlayModel.TOUCHABLE_AREA == propertyKey) {
-                List<RectF> area = model.get(AssistantOverlayModel.TOUCHABLE_AREA);
+                List<AssistantOverlayRect> area = model.get(AssistantOverlayModel.TOUCHABLE_AREA);
                 mEventFilter.setTouchableArea(area);
                 mDrawable.setTransparentArea(area);
             } else if (AssistantOverlayModel.RESTRICTED_AREA == propertyKey) {
-                List<RectF> area = model.get(AssistantOverlayModel.RESTRICTED_AREA);
+                List<AssistantOverlayRect> area = model.get(AssistantOverlayModel.RESTRICTED_AREA);
                 mEventFilter.setRestrictedArea(area);
                 mDrawable.setRestrictedArea(area);
             } else if (AssistantOverlayModel.DELEGATE == propertyKey) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java
index 1d93d605..fda10d6 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayDrawable.java
@@ -31,6 +31,7 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.autofill_assistant.R;
+import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel.AssistantOverlayRect;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.content.browser.RenderCoordinatesImpl;
 import org.chromium.content_public.browser.GestureListenerManager;
@@ -94,7 +95,7 @@
     private WebContents mWebContents;
 
     private final List<Box> mTransparentArea = new ArrayList<>();
-    private List<RectF> mRestrictedArea = Collections.emptyList();
+    private List<AssistantOverlayRect> mRestrictedArea = Collections.emptyList();
 
     /** Padding added between the element area and the grayed-out area. */
     private final float mPaddingPx;
@@ -214,14 +215,14 @@
     }
 
     /** Set or updates the transparent area. */
-    void setTransparentArea(List<RectF> transparentArea) {
+    void setTransparentArea(List<AssistantOverlayRect> transparentArea) {
         // Add or update boxes for each rectangle in the area.
         for (int i = 0; i < transparentArea.size(); i++) {
             while (i >= mTransparentArea.size()) {
                 mTransparentArea.add(new Box());
             }
             Box box = mTransparentArea.get(i);
-            RectF rect = transparentArea.get(i);
+            AssistantOverlayRect rect = transparentArea.get(i);
             boolean isNew = box.mRect.isEmpty() && !rect.isEmpty();
             box.mRect.set(rect);
             if (mPartial && isNew) {
@@ -265,7 +266,7 @@
     }
 
     /** Set or update the restricted area. */
-    void setRestrictedArea(List<RectF> restrictedArea) {
+    void setRestrictedArea(List<AssistantOverlayRect> restrictedArea) {
         mRestrictedArea = restrictedArea;
         invalidateSelf();
     }
@@ -328,16 +329,19 @@
         float top = renderCoordinates.getScrollY();
 
         // Don't draw on top of the restricted area.
-        for (RectF rect : mRestrictedArea) {
-            mDrawRect.left = renderCoordinates.fromLocalCssToPix(rect.left - left);
+        for (AssistantOverlayRect rect : mRestrictedArea) {
+            mDrawRect.left =
+                    rect.isFullWidth() ? 0 : renderCoordinates.fromLocalCssToPix(rect.left - left);
             mDrawRect.top = yTop + renderCoordinates.fromLocalCssToPix(rect.top - top);
-            mDrawRect.right = renderCoordinates.fromLocalCssToPix(rect.right - left);
+            mDrawRect.right = rect.isFullWidth()
+                    ? width
+                    : renderCoordinates.fromLocalCssToPix(rect.right - left);
             mDrawRect.bottom = yTop + renderCoordinates.fromLocalCssToPix(rect.bottom - top);
             canvas.clipRect(mDrawRect, Region.Op.DIFFERENCE);
         }
 
         for (Box box : mTransparentArea) {
-            RectF rect = box.getRectToDraw();
+            AssistantOverlayRect rect = box.getRectToDraw();
             if (rect.isEmpty() || (!mPartial && box.mAnimationType != AnimationType.FADE_IN)) {
                 continue;
             }
@@ -346,9 +350,13 @@
             int fillAlpha = (int) (mBackgroundAlpha * (1f - box.getVisibility()));
             mBoxFill.setAlpha(fillAlpha);
 
-            mDrawRect.left = renderCoordinates.fromLocalCssToPix(rect.left - left) - mPaddingPx;
+            mDrawRect.left = rect.isFullWidth()
+                    ? 0
+                    : (renderCoordinates.fromLocalCssToPix(rect.left - left) - mPaddingPx);
             mDrawRect.top = yTop + renderCoordinates.fromLocalCssToPix(rect.top - top) - mPaddingPx;
-            mDrawRect.right = renderCoordinates.fromLocalCssToPix(rect.right - left) + mPaddingPx;
+            mDrawRect.right = rect.isFullWidth()
+                    ? width
+                    : (renderCoordinates.fromLocalCssToPix(rect.right - left) + mPaddingPx);
             mDrawRect.bottom =
                     yTop + renderCoordinates.fromLocalCssToPix(rect.bottom - top) + mPaddingPx;
             if (mDrawRect.left <= 0 && mDrawRect.right >= width) {
@@ -410,11 +418,11 @@
 
     private class Box {
         /** Current rectangle and touchable area, as reported by the model. */
-        final RectF mRect = new RectF();
+        final AssistantOverlayRect mRect = new AssistantOverlayRect();
 
         /** A copy of the rectangle that used to be displayed in mRect while fading in. */
         @Nullable
-        RectF mFadeInRect;
+        AssistantOverlayRect mFadeInRect;
 
         /** Type of {@link #mAnimator}. */
         @AnimationType
@@ -434,7 +442,7 @@
         }
 
         /** Returns the rectangle that should be drawn. */
-        RectF getRectToDraw() {
+        AssistantOverlayRect getRectToDraw() {
             return mFadeInRect != null ? mFadeInRect : mRect;
         }
 
@@ -453,7 +461,7 @@
                         AnimationType.FADE_IN, 1f, 0f, BakedBezierInterpolator.FADE_IN_CURVE)) {
                 return;
             }
-            mFadeInRect = new RectF(mRect);
+            mFadeInRect = new AssistantOverlayRect(mRect);
             mAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator ignored) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java
index aefed975..a9d45be2 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayEventFilter.java
@@ -13,6 +13,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 
+import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel.AssistantOverlayRect;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.content.browser.RenderCoordinatesImpl;
 import org.chromium.content_public.browser.GestureListenerManager;
@@ -77,10 +78,10 @@
     private WebContents mWebContents;
 
     /** Touchable area, expressed in CSS pixels relative to the layout viewport. */
-    private List<RectF> mTouchableArea = Collections.emptyList();
+    private List<AssistantOverlayRect> mTouchableArea = Collections.emptyList();
 
     /** Restricted area, expressed in CSS pixels relative to the layout viewport. */
-    private List<RectF> mRestrictedArea = Collections.emptyList();
+    private List<AssistantOverlayRect> mRestrictedArea = Collections.emptyList();
 
     /**
      * Detects taps: {@link GestureDetector#onTouchEvent} returns {@code true} after a tap event.
@@ -169,14 +170,14 @@
     /**
      * Set the touchable area. This only applies if current state is AssistantOverlayState.PARTIAL.
      */
-    void setTouchableArea(List<RectF> touchableArea) {
+    void setTouchableArea(List<AssistantOverlayRect> touchableArea) {
         mTouchableArea = touchableArea;
     }
 
     /**
      * Set the restricted area. This only applies if current state is AssistantOverlayState.PARTIAL.
      */
-    void setRestrictedArea(List<RectF> restrictedArea) {
+    void setRestrictedArea(List<AssistantOverlayRect> restrictedArea) {
         mRestrictedArea = restrictedArea;
     }
 
@@ -359,6 +360,18 @@
         }
     }
 
+    private boolean rectContains(AssistantOverlayRect rect, float absoluteXCss, float absoluteYCss,
+            RenderCoordinatesImpl renderCoordinates) {
+        if (!rect.isFullWidth()) {
+            return rect.contains(absoluteXCss, absoluteYCss);
+        }
+        RectF rectCompare = new RectF(/* left= */ renderCoordinates.getScrollX(), rect.top,
+                /* right= */ renderCoordinates.getScrollX()
+                        + renderCoordinates.getContentWidthCss(),
+                rect.bottom);
+        return rectCompare.contains(absoluteXCss, absoluteYCss);
+    }
+
     private boolean isInTouchableArea(float x, float y) {
         if (mWebContents == null || mTouchableArea.isEmpty()) return false;
 
@@ -374,12 +387,12 @@
         float absoluteXCss = (x * physicalToCssPixels) + renderCoordinates.getScrollX();
         float absoluteYCss = (y * physicalToCssPixels) + renderCoordinates.getScrollY();
 
-        for (RectF rect : mRestrictedArea) {
-            if (rect.contains(absoluteXCss, absoluteYCss)) return false;
+        for (AssistantOverlayRect rect : mRestrictedArea) {
+            if (rectContains(rect, absoluteXCss, absoluteYCss, renderCoordinates)) return false;
         }
 
-        for (RectF rect : mTouchableArea) {
-            if (rect.contains(absoluteXCss, absoluteYCss)) return true;
+        for (AssistantOverlayRect rect : mTouchableArea) {
+            if (rectContains(rect, absoluteXCss, absoluteYCss, renderCoordinates)) return true;
         }
         return false;
     }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java
index 6eb5fb3..7050056 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/AssistantOverlayModel.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.autofill_assistant.overlay;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.RectF;
 
 import androidx.annotation.ColorInt;
@@ -25,15 +26,46 @@
  */
 @JNINamespace("autofill_assistant")
 public class AssistantOverlayModel extends PropertyModel {
+    /** Wrapper model for {@code RectF}. */
+    public static class AssistantOverlayRect extends RectF {
+        private boolean mIsFullWidth;
+
+        public AssistantOverlayRect() {
+            super();
+        }
+
+        public AssistantOverlayRect(
+                float left, float top, float right, float bottom, boolean fullWidth) {
+            super(left, top, right, bottom);
+            mIsFullWidth = fullWidth;
+        }
+
+        public AssistantOverlayRect(AssistantOverlayRect rect) {
+            set(rect);
+        }
+
+        public AssistantOverlayRect(Rect rect) {
+            super.set(rect);
+        }
+
+        public void set(AssistantOverlayRect rect) {
+            super.set(rect);
+            mIsFullWidth = rect.mIsFullWidth;
+        }
+
+        public boolean isFullWidth() {
+            return mIsFullWidth;
+        }
+    }
     public static final WritableIntPropertyKey STATE = new WritableIntPropertyKey();
 
     public static final WritableObjectPropertyKey<WebContents> WEB_CONTENTS =
             new WritableObjectPropertyKey<>();
 
-    public static final WritableObjectPropertyKey<List<RectF>> TOUCHABLE_AREA =
+    public static final WritableObjectPropertyKey<List<AssistantOverlayRect>> TOUCHABLE_AREA =
             new WritableObjectPropertyKey<>();
 
-    public static final WritableObjectPropertyKey<List<RectF>> RESTRICTED_AREA =
+    public static final WritableObjectPropertyKey<List<AssistantOverlayRect>> RESTRICTED_AREA =
             new WritableObjectPropertyKey<>();
 
     public static final WritableObjectPropertyKey<AssistantOverlayDelegate> DELEGATE =
@@ -71,11 +103,12 @@
         set(WEB_CONTENTS, webContents);
     }
 
-    private static List<RectF> toRectangles(float[] coords) {
-        List<RectF> boxes = new ArrayList<>();
-        for (int i = 0; i < coords.length; i += 4) {
-            boxes.add(new RectF(/* left= */ coords[i], /* top= */ coords[i + 1],
-                    /* right= */ coords[i + 2], /* bottom= */ coords[i + 3]));
+    private static List<AssistantOverlayRect> toRectangles(float[] coords) {
+        List<AssistantOverlayRect> boxes = new ArrayList<>();
+        for (int i = 0; i < coords.length; i += 5) {
+            boxes.add(new AssistantOverlayRect(/* left= */ coords[i], /* top= */ coords[i + 1],
+                    /* right= */ coords[i + 2], /* bottom= */ coords[i + 3],
+                    /* fullWidth= */ (int) coords[i + 4] == 1));
         }
         return boxes;
     }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
index 8e2c794c..3636711e 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java
@@ -16,15 +16,17 @@
 import static org.junit.Assert.assertTrue;
 
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementOnScreen;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getBoundingRectForElement;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.scrollIntoViewIfNeeded;
 import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitForElementRemoved;
+import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil;
 import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.support.test.InstrumentationRegistry;
 import android.view.View;
 
@@ -41,13 +43,14 @@
 import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayCoordinator;
 import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayImage;
 import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel;
+import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayModel.AssistantOverlayRect;
 import org.chromium.chrome.browser.autofill_assistant.overlay.AssistantOverlayState;
 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
 import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
 
 import java.util.Collections;
 import java.util.concurrent.ExecutionException;
@@ -166,9 +169,10 @@
         assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true));
 
         Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_one");
-        runOnUiThreadBlocking(()
-                                      -> model.set(AssistantOverlayModel.TOUCHABLE_AREA,
-                                              Collections.singletonList(new RectF(rect))));
+        runOnUiThreadBlocking(
+                ()
+                        -> model.set(AssistantOverlayModel.TOUCHABLE_AREA,
+                                Collections.singletonList(new AssistantOverlayRect(rect))));
 
         // Touchable area set, but no viewport given: equivalent to full overlay.
         tapElement("touch_area_one");
@@ -193,15 +197,17 @@
     @MediumTest
     public void testSimpleScrollPartialOverlay() throws Exception {
         AssistantOverlayModel model = new AssistantOverlayModel();
-        AssistantOverlayCoordinator coordinator = createCoordinator(model);
+        createCoordinator(model);
 
-        scrollIntoViewIfNeeded("touch_area_five");
+        ChromeTabUtils.waitForInteractable(mTestRule.getActivity().getActivityTab());
+        scrollIntoViewIfNeeded(mTestRule.getWebContents(), "touch_area_five");
+        waitUntil(() -> checkElementOnScreen(mTestRule, "touch_area_five"));
         Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_five");
         runOnUiThreadBlocking(() -> {
             model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL);
             model.set(AssistantOverlayModel.WEB_CONTENTS, getWebContents());
             model.set(AssistantOverlayModel.TOUCHABLE_AREA,
-                    Collections.singletonList(new RectF(rect)));
+                    Collections.singletonList(new AssistantOverlayRect(rect)));
         });
         assertScrimDisplayed(true);
         tapElement("touch_area_five");
@@ -275,18 +281,4 @@
     void tapElement(String elementId) throws Exception {
         AutofillAssistantUiTestUtil.tapElement(mTestRule, elementId);
     }
-
-    /**
-     * Scrolls to the specified element on the webpage, if necessary.
-     */
-    private void scrollIntoViewIfNeeded(String elementId) throws Exception {
-        TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
-                new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
-        javascriptHelper.evaluateJavaScriptForTests(getWebContents(),
-                "(function() {"
-                        + " document.getElementById('" + elementId + "').scrollIntoViewIfNeeded();"
-                        + " return true;"
-                        + "})()");
-        javascriptHelper.waitUntilHasValue();
-    }
 }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
index c153d4b..50cf8f14 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -560,6 +560,21 @@
         TestTouchUtils.singleClick(InstrumentationRegistry.getInstrumentation(), x, y);
     }
 
+    /** Scrolls to the specified element on the webpage, if necessary. */
+    public static void scrollIntoViewIfNeeded(WebContents webContents, String... elementIds)
+            throws Exception {
+        TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
+                new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
+        javascriptHelper.evaluateJavaScriptForTests(webContents,
+                "(function() {"
+                        + " " + getElementSelectorString(elementIds) + ".scrollIntoViewIfNeeded();"
+                        + " return [true];"
+                        + "})()");
+        javascriptHelper.waitUntilHasValue();
+        JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
+        assert result.getBoolean(0);
+    }
+
     /** Computes the bounding rectangle of the specified DOM element in absolute screen space. */
     public static Rect getAbsoluteBoundingRect(
             ChromeActivityTestRule testRule, String... elementIds) throws Exception {
@@ -656,21 +671,6 @@
                 () -> !checkElementExists(webContents, id), "Element is still on the page!");
     }
 
-    /** Checks whether the specified element is displayed in the DOM tree. */
-    public static boolean checkElementIsDisplayed(WebContents webContents, String... elementIds)
-            throws Exception {
-        TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
-                new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
-        javascriptHelper.evaluateJavaScriptForTests(webContents,
-                "(function() {"
-                        + " return [" + getElementSelectorString(elementIds)
-                        + ".style.display != \"none\"]; "
-                        + "})()");
-        javascriptHelper.waitUntilHasValue();
-        JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
-        return result.getBoolean(0);
-    }
-
     /**
      * Retrieves the value of the specified element.
      */
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
index b05d808..e9db1d5 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/PasswordChangeFixtureTest.java
@@ -214,7 +214,7 @@
 
         // Should fail during login. Wait for error opening site's settings.
         waitUntilViewMatchesCondition(
-                withText("Can't open site's settings"), isDisplayed(), MAX_WAIT_TIME_IN_MS);
+                withText("Can't change your password"), isDisplayed(), MAX_WAIT_TIME_IN_MS);
 
         // Assert initial credential has not changed.
         PasswordStoreCredential newCredential = getCredentialForDomainAndUser(
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java
index fe791bb9..df52954 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryIPHUtils.java
@@ -43,6 +43,7 @@
                 return;
             case FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_FILLING_FEATURE:
             case FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_OFFER_FEATURE:
+            case FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_VIRTUAL_CARD_FEATURE:
                 tracker.notifyEvent(EventConstants.KEYBOARD_ACCESSORY_PAYMENT_AUTOFILLED);
                 return;
         }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
index b9e390c..8dd281c 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
@@ -68,7 +68,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -364,15 +363,14 @@
         siteSuggestions.add(new SiteSuggestion("0 EXPLORE_SITES",
                 // Use pre-serialized GURL to avoid loading native.
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL), "", TileTitleSource.UNKNOWN,
-                TileSource.EXPLORE, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.EXPLORE, TileSectionType.PERSONALIZED));
 
         String urlTemplate = JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_1_NUMERAL).serialize();
         for (int i = 0; i < 7; i++) {
             siteSuggestions.add(new SiteSuggestion(String.valueOf(i),
                     // Use pre-serialized GURL to avoid loading native.
                     GURL.deserialize(urlTemplate.replace("www.1.com", "www." + i + ".com")), "",
-                    TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
-                    new Date()));
+                    TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         }
 
         return siteSuggestions;
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn
index 401cd02..83bb70e 100644
--- a/chrome/android/features/tab_ui/BUILD.gn
+++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -85,6 +85,7 @@
     "java/res/layout/tab_selection_editor_toolbar.xml",
     "java/res/layout/tab_strip_item.xml",
     "java/res/layout/tasks_view_layout.xml",
+    "java/res/values-night/dimens.xml",
     "java/res/values/colors.xml",
     "java/res/values/dimens.xml",
     "java/res/values/drawables.xml",
diff --git a/chrome/android/features/tab_ui/java/res/values-night/dimens.xml b/chrome/android/features/tab_ui/java/res/values-night/dimens.xml
new file mode 100644
index 0000000..087a641
--- /dev/null
+++ b/chrome/android/features/tab_ui/java/res/values-night/dimens.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+<resources>
+    <integer name="tab_thumbnail_placeholder_color_alpha">38</integer>
+    <integer name="tab_thumbnail_placeholder_selected_color_alpha">255</integer>
+</resources>
diff --git a/chrome/android/features/tab_ui/java/res/values/colors.xml b/chrome/android/features/tab_ui/java/res/values/colors.xml
index 423e7c1..ea75dd99 100644
--- a/chrome/android/features/tab_ui/java/res/values/colors.xml
+++ b/chrome/android/features/tab_ui/java/res/values/colors.xml
@@ -54,4 +54,10 @@
 
     <color name="incognito_tab_title_color">@color/baseline_neutral_100</color>
     <color name="incognito_tab_title_selected_color">@color/baseline_primary_800</color>
+
+    <color name="incognito_tab_thumbnail_placeholder_color">@color/baseline_neutral_variant_200_alpha_15</color>
+    <color name="incognito_tab_thumbnail_placeholder_selected_color">@color/baseline_primary_100</color>
+
+    <color name="incognito_tab_tile_number_color">@color/baseline_neutral_100</color>
+    <color name="incognito_tab_tile_number_selected_color">@color/baseline_primary_900</color>
 </resources>
diff --git a/chrome/android/features/tab_ui/java/res/values/dimens.xml b/chrome/android/features/tab_ui/java/res/values/dimens.xml
index 7e892a5..21713600 100644
--- a/chrome/android/features/tab_ui/java/res/values/dimens.xml
+++ b/chrome/android/features/tab_ui/java/res/values/dimens.xml
@@ -49,4 +49,7 @@
 
     <!-- Elevation -->
     <dimen name="tab_bg_elevation">@dimen/default_elevation_4</dimen>
+
+    <integer name="tab_thumbnail_placeholder_color_alpha">255</integer>
+    <integer name="tab_thumbnail_placeholder_selected_color_alpha">97</integer>
 </resources>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
index 83d65f9..a32b2d80 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
@@ -50,8 +50,11 @@
     private final int mThumbnailHeight;
     private final Paint mEmptyThumbnailPaint;
     private final Paint mThumbnailFramePaint;
+    private final Paint mThumbnailBasePaint;
     private final Paint mTextPaint;
     private final Paint mFaviconBackgroundPaint;
+    private final Paint mSelectedEmptyThumbnailPaint;
+    private final Paint mSelectedTextPaint;
     private final int mFaviconBackgroundPaintColor;
     private final List<Rect> mFaviconRects = new ArrayList<>(4);
     private final List<RectF> mThumbnailRects = new ArrayList<>(4);
@@ -64,6 +67,7 @@
         private final Callback<Bitmap> mFinalCallback;
         private final boolean mForceUpdate;
         private final boolean mWriteToCache;
+        private final boolean mIsTabSelected;
         private final List<PseudoTab> mTabs = new ArrayList<>(4);
         private final AtomicInteger mThumbnailsToFetch = new AtomicInteger();
 
@@ -72,14 +76,17 @@
         private String mText;
 
         /**
+         * Fetcher that get the thumbnail drawable depending on if the tab is selected.
          * @see TabContentManager#getTabThumbnailWithCallback
+         * @param isTabSelected Whether the thumbnail is for a currently selected tab.
          */
         MultiThumbnailFetcher(PseudoTab initialTab, Callback<Bitmap> finalCallback,
-                boolean forceUpdate, boolean writeToCache) {
+                boolean forceUpdate, boolean writeToCache, boolean isTabSelected) {
             mFinalCallback = finalCallback;
             mInitialTab = initialTab;
             mForceUpdate = forceUpdate;
             mWriteToCache = writeToCache;
+            mIsTabSelected = isTabSelected;
         }
 
         private void initializeAndStartFetching(PseudoTab tab) {
@@ -142,35 +149,38 @@
                     drawThumbnailBitmapOnCanvasWithFrame(null, i);
                     if (mText != null && i == 3) {
                         // Draw the text exactly centered on the thumbnail rect.
+                        Paint textPaint = mIsTabSelected ? mSelectedTextPaint : mTextPaint;
                         mCanvas.drawText(mText,
                                 (mThumbnailRects.get(i).left + mThumbnailRects.get(i).right) / 2,
                                 (mThumbnailRects.get(i).top + mThumbnailRects.get(i).bottom) / 2
                                         - ((mTextPaint.descent() + mTextPaint.ascent()) / 2),
-                                mTextPaint);
+                                textPaint);
                     }
                 }
             }
         }
 
         private void drawThumbnailBitmapOnCanvasWithFrame(Bitmap thumbnail, int index) {
-            // Draw the rounded rect. If Bitmap is not null, this is used for XferMode.
-            mCanvas.drawRoundRect(
-                    mThumbnailRects.get(index), mRadius, mRadius, mEmptyThumbnailPaint);
+            if (thumbnail == null) {
+                Paint emptyThumbnailPaint =
+                        mIsTabSelected ? mSelectedEmptyThumbnailPaint : mEmptyThumbnailPaint;
+                mCanvas.drawRoundRect(
+                        mThumbnailRects.get(index), mRadius, mRadius, emptyThumbnailPaint);
+                return;
+            }
 
-            if (thumbnail == null) return;
+            mCanvas.drawRoundRect(
+                    mThumbnailRects.get(index), mRadius, mRadius, mThumbnailBasePaint);
 
             thumbnail =
                     Bitmap.createScaledBitmap(thumbnail, (int) mThumbnailRects.get(index).width(),
                             (int) mThumbnailRects.get(index).height(), true);
-
-            mEmptyThumbnailPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+            mThumbnailBasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
             mCanvas.drawBitmap(thumbnail,
                     new Rect(0, 0, thumbnail.getWidth(), thumbnail.getHeight()),
-                    mThumbnailRects.get(index), mEmptyThumbnailPaint);
+                    mThumbnailRects.get(index), mThumbnailBasePaint);
             thumbnail.recycle();
 
-            mEmptyThumbnailPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
-
             mCanvas.drawRoundRect(
                     mThumbnailRects.get(index), mRadius, mRadius, mThumbnailFramePaint);
         }
@@ -217,9 +227,18 @@
         // Initialize Paints to use.
         mEmptyThumbnailPaint = new Paint();
         mEmptyThumbnailPaint.setStyle(Paint.Style.FILL);
-        mEmptyThumbnailPaint.setColor(ApiCompatibilityUtils.getColor(
-                resource, R.color.tab_list_mini_card_default_background_color));
         mEmptyThumbnailPaint.setAntiAlias(true);
+        mEmptyThumbnailPaint.setColor(
+                TabUiColorProvider.getMiniThumbnailPlaceHolderColor(context, false, false));
+
+        mSelectedEmptyThumbnailPaint = new Paint(mEmptyThumbnailPaint);
+        mSelectedEmptyThumbnailPaint.setColor(
+                TabUiColorProvider.getMiniThumbnailPlaceHolderColor(context, false, true));
+
+        // Paint used to set base for thumbnails, in case mEmptyThumbnailPaint has transparency.
+        mThumbnailBasePaint = new Paint(mEmptyThumbnailPaint);
+        mThumbnailBasePaint.setColor(Color.BLACK);
+        mThumbnailBasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
 
         mThumbnailFramePaint = new Paint();
         mThumbnailFramePaint.setStyle(Paint.Style.STROKE);
@@ -236,7 +255,11 @@
         mTextPaint.setFakeBoldText(true);
         mTextPaint.setAntiAlias(true);
         mTextPaint.setTextAlign(Paint.Align.CENTER);
-        mTextPaint.setColor(ApiCompatibilityUtils.getColor(resource, R.color.default_text_color));
+        mTextPaint.setColor(TabUiColorProvider.getTabGroupNumberTextColor(context, false, false));
+
+        mSelectedTextPaint = new Paint(mTextPaint);
+        mSelectedTextPaint.setColor(
+                TabUiColorProvider.getTabGroupNumberTextColor(context, false, true));
 
         mFaviconBackgroundPaintColor =
                 ApiCompatibilityUtils.getColor(resource, R.color.favicon_background_color);
@@ -297,14 +320,20 @@
             @Override
             public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
                 boolean isIncognito = newModel.isIncognito();
-                mEmptyThumbnailPaint.setColor(
-                        TabUiColorProvider.getMiniThumbnailPlaceHolderColor(context, isIncognito));
+                mEmptyThumbnailPaint.setColor(TabUiColorProvider.getMiniThumbnailPlaceHolderColor(
+                        context, isIncognito, false));
+                mTextPaint.setColor(
+                        TabUiColorProvider.getTabGroupNumberTextColor(context, isIncognito, false));
                 mThumbnailFramePaint.setColor(
                         TabUiColorProvider.getMiniThumbnailFrameColor(context, isIncognito));
-                mTextPaint.setColor(
-                        TabUiColorProvider.getTabGroupNumberTextColor(context, isIncognito));
                 mFaviconBackgroundPaint.setColor(
                         TabUiColorProvider.getFaviconBackgroundColor(context, isIncognito));
+
+                mSelectedEmptyThumbnailPaint.setColor(
+                        TabUiColorProvider.getMiniThumbnailPlaceHolderColor(
+                                context, isIncognito, true));
+                mSelectedTextPaint.setColor(
+                        TabUiColorProvider.getTabGroupNumberTextColor(context, isIncognito, true));
             }
         };
         mTabModelSelector.addObserver(mTabModelSelectorObserver);
@@ -333,7 +362,8 @@
                     tabId, finalCallback, forceUpdate, writeToCache);
             return;
         }
-
-        new MultiThumbnailFetcher(tab, finalCallback, forceUpdate, writeToCache).fetch();
+        boolean isSelected = tabId == mTabModelSelector.getCurrentTabId();
+        new MultiThumbnailFetcher(tab, finalCallback, forceUpdate, writeToCache, isSelected)
+                .fetch();
     }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
index e603e59..9a9348a 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -6,6 +6,7 @@
 
 import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_ALPHA;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
@@ -113,6 +114,7 @@
             if (CachedFeatureFlags.isEnabled(ChromeFeatureList.THEME_REFACTOR_ANDROID)) {
                 updateColor(view, model.get(TabProperties.IS_INCOGNITO),
                         model.get(TabProperties.IS_SELECTED));
+                updateThumbnail(view, model);
             } else {
                 int selectedTabBackground =
                         model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID);
@@ -415,6 +417,11 @@
         if (thumbnail.getDrawable() == null) {
             thumbnail.setImageResource(
                     TabUiColorProvider.getThumbnailPlaceHolderColorResource(isIncognito));
+            if (CachedFeatureFlags.isEnabled(ChromeFeatureList.THEME_REFACTOR_ANDROID)) {
+                thumbnail.setImageTintList(
+                        ColorStateList.valueOf(TabUiColorProvider.getMiniThumbnailPlaceHolderColor(
+                                backgroundView.getContext(), isIncognito, isSelected)));
+            }
         }
 
         if (TabUiFeatureUtilities.isTabGroupsAndroidEnabled(rootView.getContext())) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
index 83d051a..acd2185 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -401,6 +401,12 @@
                                         .indexOf(toTab);
 
             RecordUserAction.record("MobileTabSwitched." + mComponentName);
+            if (PriceTrackingUtilities.isTrackPricesOnTabsEnabled()
+                    && TabSwitcherCoordinator.COMPONENT_NAME.equals(mComponentName)) {
+                RecordUserAction.record("Commerce.TabGridSwitched."
+                        + (ShoppingPersistedTabData.hasPriceDrop(toTab) ? "HasPriceDrop"
+                                                                        : "NoPriceDrop"));
+            }
             if (TabUiFeatureUtilities.isConditionalTabStripEnabled()) {
                 assert fromFilterIndex != toFilterIndex;
                 RecordHistogram.recordSparseHistogram("Tabs.TabOffsetOfSwitch." + mComponentName,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java
index 8828958..62d9f03 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiColorProvider.java
@@ -77,13 +77,27 @@
      *
      * @param context {@link Context} used to retrieve color.
      * @param isIncognito Whether the color is used for incognito mode.
+     * @param isSelected Whether the tab is currently selected.
      * @return The text color for the number used on the tab group cards.
      */
     @ColorInt
-    public static int getTabGroupNumberTextColor(Context context, boolean isIncognito) {
-        return ApiCompatibilityUtils.getColor(context.getResources(),
-                isIncognito ? R.color.tab_group_number_text_color_incognito
-                            : R.color.tab_group_number_text_color);
+    public static int getTabGroupNumberTextColor(
+            Context context, boolean isIncognito, boolean isSelected) {
+        if (!themeRefactorEnabled()) {
+            return ApiCompatibilityUtils.getColor(context.getResources(),
+                    isIncognito ? R.color.tab_group_number_text_color_incognito
+                                : R.color.tab_group_number_text_color);
+        }
+        if (isIncognito) {
+            @ColorRes
+            int colorRes = isSelected ? R.color.incognito_tab_tile_number_selected_color
+                                      : R.color.incognito_tab_tile_number_color;
+            return ApiCompatibilityUtils.getColor(context.getResources(), colorRes);
+        } else {
+            return isSelected
+                    ? MaterialColors.getColor(context, R.attr.colorOnPrimaryContainer, TAG)
+                    : MaterialColors.getColor(context, R.attr.colorOnSurface, TAG);
+        }
     }
 
     /**
@@ -188,13 +202,34 @@
      *
      * @param context {@link Context} used to retrieve color.
      * @param isIncognito Whether the color is used for incognito mode.
+     * @param isSelected Whether the tab is currently selected.
      * @return The mini-thumbnail placeholder color.
      */
     @ColorInt
-    public static int getMiniThumbnailPlaceHolderColor(Context context, boolean isIncognito) {
-        return ApiCompatibilityUtils.getColor(context.getResources(),
-                isIncognito ? R.color.tab_list_mini_card_default_background_color_incognito
-                            : R.color.tab_list_mini_card_default_background_color);
+    public static int getMiniThumbnailPlaceHolderColor(
+            Context context, boolean isIncognito, boolean isSelected) {
+        if (!themeRefactorEnabled()) {
+            return ApiCompatibilityUtils.getColor(context.getResources(),
+                    isIncognito ? R.color.tab_list_mini_card_default_background_color_incognito
+                                : R.color.tab_list_mini_card_default_background_color);
+        }
+
+        if (isIncognito) {
+            @ColorRes
+            int colorRes = isSelected ? R.color.incognito_tab_thumbnail_placeholder_selected_color
+                                      : R.color.incognito_tab_thumbnail_placeholder_color;
+            return ApiCompatibilityUtils.getColor(context.getResources(), colorRes);
+        } else {
+            int alpha = context.getResources().getInteger(isSelected
+                            ? R.integer.tab_thumbnail_placeholder_selected_color_alpha
+                            : R.integer.tab_thumbnail_placeholder_color_alpha);
+            @ColorInt
+            int baseColor = isSelected
+                    ? MaterialColors.getColor(context, R.attr.colorPrimaryContainer, TAG)
+                    // TODO (crrev.com/c/2994242): Change light mode to Surface1.
+                    : MaterialColors.getColor(context, R.attr.colorOnSurfaceVariant, TAG);
+            return MaterialColors.compositeARGBWithAlpha(baseColor, alpha);
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
index cb5193c..79bc528 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
@@ -219,6 +219,7 @@
                         new ChromeShareExtras.Builder()
                                 .setSaveLastUsed(true)
                                 .setIsUserHighlightedText(true)
+                                .setRenderFrameHost(mHelper.getRenderFrameHost())
                                 .build(),
                         ShareOrigin.MOBILE_ACTION_MODE);
             } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
index 9537f56..ddbbb55e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser;
 
+import static org.chromium.chrome.browser.base.SplitCompatUtils.CHROME_SPLIT_NAME;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
@@ -18,6 +20,7 @@
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.base.SplitChromeApplication;
 import org.chromium.chrome.browser.base.SplitCompatUtils;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -42,6 +45,15 @@
     @Override
     protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
+
+        // Make sure the "chrome" split is loaded before checking if ClassLoaders are equal.
+        SplitChromeApplication.finishPreload(CHROME_SPLIT_NAME);
+        if (!ChromeBaseAppCompatActivity.class.getClassLoader().equals(
+                    ContextUtils.getApplicationContext().getClassLoader())) {
+            // This should only happen on Android O. See crbug.com/1146745 for more info.
+            throw new IllegalStateException("ClassLoader mismatch detected.");
+        }
+
         mNightModeStateProvider = createNightModeStateProvider();
 
         Configuration config = new Configuration();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
index cb0b8121..5f3ccb7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java
@@ -139,16 +139,17 @@
         });
     }
 
-    protected Impl createNonBrowserApplication() {
-        return new Impl();
-    }
-
-    /* package */ static void finishPreload(String name) {
+    /** Waits for the specified split to finish preloading if necessary. */
+    public static void finishPreload(String name) {
         if (sSplitPreloader != null) {
             sSplitPreloader.wait(name);
         }
     }
 
+    protected Impl createNonBrowserApplication() {
+        return new Impl();
+    }
+
     /**
      * Fixes Activity ClassLoader if necessary. Isolated splits can cause a ClassLoader mismatch
      * between the Application and Activity ClassLoaders. We have a workaround in
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
index b544c9e..7e0285a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/QualityEnforcer.java
@@ -17,6 +17,7 @@
 import org.chromium.base.Promise;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browserservices.constants.QualityEnforcementViolationType;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
 import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
 import org.chromium.chrome.browser.browserservices.ui.controller.trustedwebactivity.ClientPackageNameProvider;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
index c091e3d..788651d8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeApplicationImpl;
 import org.chromium.chrome.browser.browserservices.TrustedWebActivityUmaRecorder.DelegatedNotificationSmallIconFallback;
+import org.chromium.chrome.browser.browserservices.constants.LocationUpdateError;
 import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionManager;
 import org.chromium.chrome.browser.notifications.NotificationBuilderBase;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java
index 35d95da..56672f5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityUmaRecorder.java
@@ -11,6 +11,8 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
+import org.chromium.chrome.browser.browserservices.constants.LocationUpdateError;
+import org.chromium.chrome.browser.browserservices.constants.QualityEnforcementViolationType;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.components.content_settings.ContentSettingsType;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
index 7e4e4b2..8fb000b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -157,10 +157,10 @@
     private final ObservableSupplierImpl<TabModelSelector> mTabModelSelectorSupplier =
             new ObservableSupplierImpl<>();
     private final ObservableSupplier<TabContentManager> mTabContentManagerSupplier;
-    private final ObservableSupplierImpl<BrowserControlsStateProvider>
-            mBrowserControlsStateProviderSupplier = new ObservableSupplierImpl<>();
     private final CompositorModelChangeProcessor.FrameRequestSupplier mFrameRequestSupplier;
 
+    private BrowserControlsStateProvider mBrowserControlsStateProvider;
+
     /** The overlays that can be drawn on top of the active layout. */
     protected final List<SceneOverlay> mSceneOverlays = new ArrayList<>();
 
@@ -468,19 +468,15 @@
             TopUiThemeColorProvider topUiColorProvider) {
         LayoutRenderHost renderHost = mHost.getLayoutRenderHost();
 
+        mBrowserControlsStateProvider = mHost.getBrowserControlsManager();
+
         // Build Layouts
         mStaticLayout = new StaticLayout(mContext, this, renderHost, mHost, mFrameRequestSupplier,
-                selector, mTabContentManagerSupplier.get(), mBrowserControlsStateProviderSupplier,
+                selector, mTabContentManagerSupplier.get(), mBrowserControlsStateProvider,
                 mTopUiThemeColorProvider);
 
         setNextLayout(null);
 
-        // Initialize Layouts
-        mStaticLayout.onFinishNativeInitialization();
-
-        // Initialize Layouts
-        mBrowserControlsStateProviderSupplier.set(mHost.getBrowserControlsManager());
-
         // Set the dynamic resource loader for all overlay panels.
         mOverlayPanelManager.setDynamicResourceLoader(dynamicResourceLoader);
         mOverlayPanelManager.setContainerView(mContentContainer);
@@ -594,9 +590,9 @@
                 mCachedVisibleViewport, mLayerTitleCacheSupplier.get(), tabContentManager,
                 resourceManager, browserControlsManager);
 
-        float offsetPx = mBrowserControlsStateProviderSupplier.get() == null
+        float offsetPx = mBrowserControlsStateProvider == null
                 ? 0
-                : mBrowserControlsStateProviderSupplier.get().getTopControlOffset();
+                : mBrowserControlsStateProvider.getTopControlOffset();
 
         for (int i = 0; i < mSceneOverlays.size(); i++) {
             // If the SceneOverlay is not showing, don't bother adding it to the tree.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
index f931f6c33..4d48221 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
@@ -11,8 +11,6 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import org.chromium.base.Callback;
-import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.LayerTitleCache;
@@ -100,7 +98,6 @@
     private final Supplier<TopUiThemeColorProvider> mTopUiThemeColorProvider;
 
     private boolean mIsActive;
-    private boolean mIsInitialized;
 
     private static Integer sToolbarTextBoxBackgroundColorForTesting;
     private static Float sToolbarTextBoxAlphaForTesting;
@@ -116,15 +113,28 @@
      * @param requestSupplier Frame request supplier for Compositor MCP.
      * @param tabModelSelector {@link TabModelSelector} instance.
      * @param tabContentManager {@link TabContentsManager} instance.
-     * @param browserControlsStateProviderSupplier Supplier of {@link BrowserControlsStateProvider}.
+     * @param browserControlsStateProvider A {@link BrowserControlsStateProvider}.
      * @param topUiThemeColorProvider {@link ThemeColorProvider} for top UI.
      */
     public StaticLayout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost,
             LayoutManagerHost viewHost,
             CompositorModelChangeProcessor.FrameRequestSupplier requestSupplier,
             TabModelSelector tabModelSelector, TabContentManager tabContentManager,
-            ObservableSupplier<BrowserControlsStateProvider> browserControlsStateProviderSupplier,
+            BrowserControlsStateProvider browserControlsStateProvider,
             Supplier<TopUiThemeColorProvider> topUiThemeColorProvider) {
+        this(context, updateHost, renderHost, viewHost, requestSupplier, tabModelSelector,
+                tabContentManager, browserControlsStateProvider, topUiThemeColorProvider, null);
+    }
+
+    /** Protected constructor for testing, allows specifying a custom SceneLayer. */
+    @VisibleForTesting
+    StaticLayout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost,
+            LayoutManagerHost viewHost,
+            CompositorModelChangeProcessor.FrameRequestSupplier requestSupplier,
+            TabModelSelector tabModelSelector, TabContentManager tabContentManager,
+            BrowserControlsStateProvider browserControlsStateProvider,
+            Supplier<TopUiThemeColorProvider> topUiThemeColorProvider,
+            StaticTabSceneLayer testSceneLayer) {
         super(context, updateHost, renderHost);
         mContext = context;
         // Only handle tab lifecycle on tablets.
@@ -137,16 +147,6 @@
         assert tabModelSelector != null;
         setTabModelSelector(tabModelSelector);
 
-        browserControlsStateProviderSupplier.addObserver(
-                new Callback<BrowserControlsStateProvider>() {
-                    @Override
-                    public void onResult(
-                            BrowserControlsStateProvider browserControlsStateProvider) {
-                        setBrowserControlsStateProvider(browserControlsStateProvider);
-                        browserControlsStateProviderSupplier.removeObserver(this);
-                    }
-                });
-
         mModel = new PropertyModel.Builder(LayoutTab.ALL_KEYS)
                          .with(LayoutTab.TAB_ID, Tab.INVALID_TAB_ID)
                          .with(LayoutTab.SCALE, 1.0f)
@@ -169,6 +169,28 @@
         Resources res = context.getResources();
         float dpToPx = res.getDisplayMetrics().density;
         mPxToDp = 1.0f / dpToPx;
+
+        mBrowserControlsStateProvider = browserControlsStateProvider;
+        mModel.set(LayoutTab.CONTENT_OFFSET, mBrowserControlsStateProvider.getContentOffset());
+        mBrowserControlsStateProviderObserver = new BrowserControlsStateProvider.Observer() {
+            @Override
+            public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset,
+                    int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) {
+                mModel.set(
+                        LayoutTab.CONTENT_OFFSET, mBrowserControlsStateProvider.getContentOffset());
+            }
+        };
+        mBrowserControlsStateProvider.addObserver(mBrowserControlsStateProviderObserver);
+
+        if (testSceneLayer != null) {
+            mSceneLayer = testSceneLayer;
+        } else {
+            mSceneLayer = new StaticTabSceneLayer();
+        }
+        mSceneLayer.setTabContentManager(mTabContentManager);
+
+        mMcp = CompositorModelChangeProcessor.create(
+                mModel, mSceneLayer, StaticTabSceneLayer::bind, mRequestSupplier);
     }
 
     private void setTabModelSelector(TabModelSelector tabModelSelector) {
@@ -215,39 +237,6 @@
         };
     }
 
-    private void setBrowserControlsStateProvider(
-            BrowserControlsStateProvider browserControlsStateProvider) {
-        assert browserControlsStateProvider != null;
-        assert mBrowserControlsStateProvider
-                == null : "The ChromeFullscreenManager should set at most once";
-
-        mModel.set(LayoutTab.CONTENT_OFFSET, browserControlsStateProvider.getContentOffset());
-        mBrowserControlsStateProvider = browserControlsStateProvider;
-        mBrowserControlsStateProviderObserver = new BrowserControlsStateProvider.Observer() {
-            @Override
-            public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset,
-                    int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) {
-                mModel.set(
-                        LayoutTab.CONTENT_OFFSET, browserControlsStateProvider.getContentOffset());
-            }
-        };
-        mBrowserControlsStateProvider.addObserver(mBrowserControlsStateProviderObserver);
-    }
-
-    @Override
-    public void onFinishNativeInitialization() {
-        assert !mIsInitialized : "StaticLayoutMediator should initialize at most once";
-
-        mIsInitialized = true;
-        if (mSceneLayer == null) {
-            mSceneLayer = new StaticTabSceneLayer();
-            mSceneLayer.setTabContentManager(mTabContentManager);
-        }
-
-        mMcp = CompositorModelChangeProcessor.create(
-                mModel, mSceneLayer, StaticTabSceneLayer::bind, mRequestSupplier);
-    }
-
     @Override
     public @ViewportMode int getViewportMode() {
         return ViewportMode.DYNAMIC_BROWSER_CONTROLS;
@@ -484,11 +473,6 @@
     }
 
     @VisibleForTesting
-    void setSceneLayerForTesting(StaticTabSceneLayer sceneLayer) {
-        mSceneLayer = sceneLayer;
-    }
-
-    @VisibleForTesting
     TabModelSelector getTabModelSelectorForTesting() {
         return mTabModelSelector;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index de0ad63..688e697 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -451,7 +451,7 @@
 
     @Override
     public int getBaseStatusBarColor(Tab tab) {
-        return mStatusBarColorProvider.getBaseStatusBarColor(tab, super.getBaseStatusBarColor(tab));
+        return mStatusBarColorProvider.getBaseStatusBarColor(tab);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java
index 842e27d..1ca3f54 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProvider.java
@@ -44,9 +44,7 @@
         mStatusBarColorController.updateStatusBarColor();
     }
 
-    int getBaseStatusBarColor(Tab tab, int fallbackStatusBarColor) {
-        if (mIntentDataProvider.isOpenedByChrome()) return fallbackStatusBarColor;
-
+    int getBaseStatusBarColor(Tab tab) {
         @ToolbarColorType
         int toolbarColorType = CustomTabToolbarColorController.computeToolbarColorType(
                 mIntentDataProvider, mUseTabThemeColor, tab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
index 21d7468..b579df8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarColorController.java
@@ -78,6 +78,9 @@
     public static int computeToolbarColorType(BrowserServicesIntentDataProvider intentDataProvider,
             boolean useTabThemeColor, @Nullable Tab tab) {
         if (intentDataProvider.isOpenedByChrome()) {
+            if (intentDataProvider.getColorProvider().hasCustomToolbarColor()) {
+                return ToolbarColorType.INTENT_TOOLBAR_COLOR;
+            }
             return (tab == null) ? ToolbarColorType.DEFAULT_COLOR : ToolbarColorType.THEME_COLOR;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
index 4fc5dac..4d9a4bf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
@@ -568,7 +568,6 @@
         mTrustedVaultOptIn.setKey(PREF_TRUSTED_VAULT_OPT_IN);
         mTrustedVaultOptIn.setTitle(R.string.android_trusted_vault_opt_in_label);
         mTrustedVaultOptIn.setOrder(ORDER_TRUSTED_VAULT_OPT_IN);
-        mTrustedVaultOptIn.setIcon(android.R.drawable.ic_lock_lock);
         mTrustedVaultOptIn.setSummary(R.string.android_trusted_vault_opt_in_sub_label);
         mTrustedVaultOptIn.setOnPreferenceClickListener(preference -> {
             assert SyncService.get() != null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSuggestion.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSuggestion.java
index cdc0515..15dbc8fb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSuggestion.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SiteSuggestion.java
@@ -9,8 +9,6 @@
 import org.chromium.chrome.browser.suggestions.tile.TileTitleSource;
 import org.chromium.url.GURL;
 
-import java.util.Date;
-
 /**
  * Data class that holds the site suggestion data provided by the tiles component.
  */
@@ -41,19 +39,14 @@
     @TileSectionType
     public final int sectionType;
 
-    /** The instant in time representing when the tile was originally generated
-        (produced by a ranking algorithm). */
-    public final Date dataGenerationTime;
-
     public SiteSuggestion(String title, GURL url, String allowlistIconPath, int titleSource,
-            int source, int sectionType, Date dataGenerationTime) {
+            int source, int sectionType) {
         this.title = title;
         this.url = url;
         this.allowlistIconPath = allowlistIconPath;
         this.source = source;
         this.titleSource = titleSource;
         this.sectionType = sectionType;
-        this.dataGenerationTime = (Date) dataGenerationTime.clone();
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java
index 015f801..82a5bf2f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesBridge.java
@@ -13,7 +13,6 @@
 import org.chromium.url.GURL;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -88,8 +87,7 @@
         if (mNativeMostVisitedSitesBridge == 0) return;
         MostVisitedSitesBridgeJni.get().recordTileImpression(mNativeMostVisitedSitesBridge,
                 MostVisitedSitesBridge.this, tile.getIndex(), tile.getType(), tile.getIconType(),
-                tile.getTitleSource(), tile.getSource(),
-                tile.getData().dataGenerationTime.getTime(), tile.getUrl());
+                tile.getTitleSource(), tile.getSource(), tile.getUrl());
     }
 
     @Override
@@ -97,7 +95,7 @@
         if (mNativeMostVisitedSitesBridge == 0) return;
         MostVisitedSitesBridgeJni.get().recordOpenedMostVisitedItem(mNativeMostVisitedSitesBridge,
                 MostVisitedSitesBridge.this, tile.getIndex(), tile.getType(), tile.getTitleSource(),
-                tile.getSource(), tile.getData().dataGenerationTime.getTime());
+                tile.getSource());
     }
 
     /**
@@ -105,12 +103,11 @@
      * {@link SiteSuggestion}s.
      */
     public static List<SiteSuggestion> buildSiteSuggestions(String[] titles, GURL[] urls,
-            int[] sections, String[] allowlistIconPaths, int[] titleSources, int[] sources,
-            long[] dataGenerationTimesMs) {
+            int[] sections, String[] allowlistIconPaths, int[] titleSources, int[] sources) {
         List<SiteSuggestion> siteSuggestions = new ArrayList<>(titles.length);
         for (int i = 0; i < titles.length; ++i) {
             siteSuggestions.add(new SiteSuggestion(titles[i], urls[i], allowlistIconPaths[i],
-                    titleSources[i], sources[i], sections[i], new Date(dataGenerationTimesMs[i])));
+                    titleSources[i], sources[i], sections[i]));
         }
         return siteSuggestions;
     }
@@ -129,15 +126,14 @@
      */
     @CalledByNative
     private void onURLsAvailable(String[] titles, GURL[] urls, int[] sections,
-            String[] allowlistIconPaths, int[] titleSources, int[] sources,
-            long[] dataGenerationTimesMs) {
+            String[] allowlistIconPaths, int[] titleSources, int[] sources) {
         // Don't notify observer if we've already been destroyed.
         if (mNativeMostVisitedSitesBridge == 0) return;
 
         List<SiteSuggestion> suggestions = new ArrayList<>();
 
-        suggestions.addAll(buildSiteSuggestions(titles, urls, sections, allowlistIconPaths,
-                titleSources, sources, dataGenerationTimesMs));
+        suggestions.addAll(buildSiteSuggestions(
+                titles, urls, sections, allowlistIconPaths, titleSources, sources));
 
         mWrappedObserver.onSiteSuggestionsAvailable(suggestions);
     }
@@ -171,10 +167,9 @@
         void recordPageImpression(
                 long nativeMostVisitedSitesBridge, MostVisitedSitesBridge caller, int tilesCount);
         void recordTileImpression(long nativeMostVisitedSitesBridge, MostVisitedSitesBridge caller,
-                int index, int type, int iconType, int titleSource, int source,
-                long dataGenerationTimeMs, GURL url);
+                int index, int type, int iconType, int titleSource, int source, GURL url);
         void recordOpenedMostVisitedItem(long nativeMostVisitedSitesBridge,
-                MostVisitedSitesBridge caller, int index, int tileType, int titleSource, int source,
-                long dataGenerationTimeMs);
+                MostVisitedSitesBridge caller, int index, int tileType, int titleSource,
+                int source);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java
index 7abb2c2fa..7222b63 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtils.java
@@ -27,7 +27,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -172,7 +171,6 @@
             stream.writeInt(suggestionInfo.titleSource);
             stream.writeInt(suggestionInfo.source);
             stream.writeInt(suggestionInfo.sectionType);
-            stream.writeLong(suggestionInfo.dataGenerationTime.getTime());
         }
         stream.close();
         Log.i(TAG, "Serializing top sites lists finished; count: " + topSitesCount);
@@ -186,8 +184,6 @@
 
         DataInputStream stream = new DataInputStream(new ByteArrayInputStream(listData));
 
-        Date dataGenerationTime;
-
         // Get how many top sites there are.
         final int count = stream.readInt();
 
@@ -207,9 +203,8 @@
             int titleSource = stream.readInt();
             int source = stream.readInt();
             int sectionType = stream.readInt();
-            dataGenerationTime = new Date(stream.readLong());
-            SiteSuggestion newSite = new SiteSuggestion(title, url, allowlistIconPath, titleSource,
-                    source, sectionType, dataGenerationTime);
+            SiteSuggestion newSite = new SiteSuggestion(
+                    title, url, allowlistIconPath, titleSource, source, sectionType);
             Tile newTile = new Tile(newSite, index);
             tiles.add(newTile);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java
index 8ca4266..a67e5a9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java
@@ -53,18 +53,7 @@
          * @return a promise which indicates completion and also represents whether the operation
          * took any effect (false positives acceptable).
          */
-        // TODO(crbug.com/1100279): Switch to non-default method once all implementations are ready.
-        default Promise<Boolean> markLocalKeysAsStale(CoreAccountInfo accountInfo) {
-            return markKeysAsStale(accountInfo);
-        }
-
-        /**
-         * Same as above. Kept around temporarily only until all subclasses rename the method.
-         */
-        // TODO(crbug.com/1100279): Delete once all implementations have migrated off.
-        default Promise<Boolean> markKeysAsStale(CoreAccountInfo accountInfo) {
-            return Promise.fulfilled(false);
-        }
+        Promise<Boolean> markLocalKeysAsStale(CoreAccountInfo accountInfo);
 
         /**
          * Returns whether recoverability of the keys is degraded and user action is required to add
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 8dd9e32..f1987d7 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
@@ -1543,6 +1543,7 @@
     }
 
     @CalledByNative
+    @Override
     public boolean isCustomTab() {
         ChromeActivity activity = getActivity();
         return activity != null && activity.isCustomTab();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
index 88c4345..758a612b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasicTest.java
@@ -10,8 +10,11 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
+import android.view.View;
+
 import androidx.preference.CheckBoxPreference;
 import androidx.preference.PreferenceScreen;
+import androidx.test.filters.LargeTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -24,16 +27,21 @@
 
 import org.chromium.base.CollectionUtil;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragment.DialogOption;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
 import org.chromium.chrome.browser.sync.SyncService;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
+import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
 import org.chromium.components.sync.ModelType;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
+import java.io.IOException;
 import java.util.HashSet;
 
 /**
@@ -57,6 +65,10 @@
     @Rule
     public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
 
+    @Rule
+    public ChromeRenderTestRule mRenderTestRule =
+            ChromeRenderTestRule.Builder.withPublicCorpus().build();
+
     private static final String GOOGLE_ACCOUNT = "Google Account";
     private static final String OTHER_ACTIVITY = "other forms of browsing history";
     private static final String SYNCED_DEVICES = "synced devices";
@@ -173,4 +185,45 @@
             assertThat(historySummary, containsString(SYNCED_DEVICES));
         });
     }
+
+    @Test
+    @LargeTest
+    @Feature({"RenderTest"})
+    @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK)
+    public void testRenderNotSignedIn() throws IOException {
+        mSettingsActivityTestRule.startSettingsActivity();
+        View view = mSettingsActivityTestRule.getActivity()
+                            .findViewById(android.R.id.content)
+                            .getRootView();
+        mRenderTestRule.render(view, "clear_browsing_data_basic_signed_out");
+    }
+
+    @Test
+    @LargeTest
+    @Feature({"RenderTest"})
+    @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK)
+    public void testRenderSignedInNotSyncing() throws IOException {
+        mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync();
+        // Simulate that Sync was stopped but the primary account remained.
+        setSyncable(false);
+        mSettingsActivityTestRule.startSettingsActivity();
+        View view = mSettingsActivityTestRule.getActivity()
+                            .findViewById(android.R.id.content)
+                            .getRootView();
+        mRenderTestRule.render(view, "clear_browsing_data_basic_signed_in_no_sync");
+    }
+
+    @Test
+    @LargeTest
+    @Feature({"RenderTest"})
+    @DisableFeatures(ChromeFeatureList.SEARCH_HISTORY_LINK)
+    public void testRenderSignedInAndSyncing() throws IOException {
+        mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync();
+        setSyncable(true);
+        mSettingsActivityTestRule.startSettingsActivity();
+        View view = mSettingsActivityTestRule.getActivity()
+                            .findViewById(android.R.id.content)
+                            .getRootView();
+        mRenderTestRule.render(view, "clear_browsing_data_basic_signed_in_sync");
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java
index 567f46b6..ed74e5d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/mostvisited/MostVisitedSitesMetadataUtilsTest.java
@@ -32,7 +32,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -146,13 +145,11 @@
     private static List<Tile> createFakeSiteSuggestionTiles1() {
         List<Tile> suggestionTiles = new ArrayList<>();
         SiteSuggestion data = new SiteSuggestion("0 TOP_SITES", new GURL("https://www.foo.com"), "",
-                TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
-                new Date());
+                TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED);
         suggestionTiles.add(new Tile(data, 0));
 
         data = new SiteSuggestion("1 ALLOWLIST", new GURL("https://www.bar.com"), "",
-                TileTitleSource.UNKNOWN, TileSource.ALLOWLIST, TileSectionType.PERSONALIZED,
-                new Date());
+                TileTitleSource.UNKNOWN, TileSource.ALLOWLIST, TileSectionType.PERSONALIZED);
         suggestionTiles.add(new Tile(data, 1));
 
         return suggestionTiles;
@@ -161,8 +158,7 @@
     private static List<Tile> createFakeSiteSuggestionTiles2() {
         List<Tile> suggestionTiles = new ArrayList<>();
         SiteSuggestion data = new SiteSuggestion("0 TOP_SITES", new GURL("https://www.baz.com"), "",
-                TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED,
-                new Date());
+                TileTitleSource.TITLE_TAG, TileSource.TOP_SITES, TileSectionType.PERSONALIZED);
         suggestionTiles.add(new Tile(data, 0));
 
         return suggestionTiles;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java
index 10e5f698..2159fa1e8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/suggestions/tile/TileGroupTest.java
@@ -51,7 +51,6 @@
 import org.chromium.url.GURL;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
@@ -273,7 +272,7 @@
 
         SiteSuggestion exploreTile = new SiteSuggestion("chrome-native://explore",
                 new GURL("chrome-native://explore"), "", TileTitleSource.UNKNOWN,
-                TileSource.EXPLORE, TileSectionType.PERSONALIZED, new Date());
+                TileSource.EXPLORE, TileSectionType.PERSONALIZED);
         currentSuggestions.add(exploreTile);
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> mMostVisitedSites.setTileSuggestions(currentSuggestions));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
index 049043f..cebe00d4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTest.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.tab.state;
 
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 import android.support.test.filters.SmallTest;
 
@@ -20,6 +21,7 @@
 import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.UiThreadTest;
+import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
@@ -31,6 +33,8 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.MockTab;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabImpl;
+import org.chromium.chrome.browser.tab.state.PriceDropMetricsLogger.MetricsResult;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
@@ -43,6 +47,7 @@
 import java.nio.ByteBuffer;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Test relating to {@link ShoppingPersistedTabData}
@@ -108,6 +113,46 @@
                 ShoppingPersistedTabDataTestUtils.PRICE_MICROS, deserialized.getPriceMicros());
         Assert.assertEquals(
                 ShoppingPersistedTabData.NO_PRICE_KNOWN, deserialized.getPreviousPriceMicros());
+        MetricsResult metricsResult =
+                deserialized.getPriceDropMetricsLoggerForTesting().getMetricsResultForTesting();
+        Assert.assertFalse(metricsResult.isProductDetailPage);
+        Assert.assertTrue(metricsResult.containsPrice);
+        Assert.assertFalse(metricsResult.containsPriceDrop);
+    }
+
+    @UiThreadTest
+    @SmallTest
+    @Test
+    public void testMetricDerivations() {
+        Tab tab = new MockTab(ShoppingPersistedTabDataTestUtils.TAB_ID,
+                ShoppingPersistedTabDataTestUtils.IS_INCOGNITO);
+        ShoppingPersistedTabData shoppingPersistedTabData = new ShoppingPersistedTabData(tab);
+        ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>();
+        supplier.set(true);
+        shoppingPersistedTabData.registerIsTabSaveEnabledSupplier(supplier);
+        for (boolean isProductDetailPage : new boolean[] {false, true}) {
+            for (boolean containsPrice : new boolean[] {false, true}) {
+                for (boolean containsPriceDrop : new boolean[] {false, true}) {
+                    shoppingPersistedTabData.setMainOfferId(
+                            isProductDetailPage ? "non-empty-offer-id" : null);
+                    shoppingPersistedTabData.setPriceMicros(containsPrice || containsPriceDrop
+                                    ? 42_000_000L
+                                    : ShoppingPersistedTabData.NO_PRICE_KNOWN);
+                    shoppingPersistedTabData.setPreviousPriceMicros(containsPriceDrop
+                                    ? 30_000_000L
+                                    : ShoppingPersistedTabData.NO_PRICE_KNOWN);
+                    ByteBuffer serialized = shoppingPersistedTabData.getSerializeSupplier().get();
+                    ShoppingPersistedTabData deserialized = new ShoppingPersistedTabData(tab);
+                    deserialized.deserialize(serialized);
+                    MetricsResult metricsResult = deserialized.getPriceDropMetricsLoggerForTesting()
+                                                          .getMetricsResultForTesting();
+                    Assert.assertEquals(isProductDetailPage, metricsResult.isProductDetailPage);
+                    Assert.assertEquals(
+                            containsPrice || containsPriceDrop, metricsResult.containsPrice);
+                    Assert.assertEquals(containsPriceDrop, metricsResult.containsPriceDrop);
+                }
+            }
+        }
     }
 
     @SmallTest
@@ -661,4 +706,32 @@
         Assert.assertEquals(ShoppingPersistedTabData.NO_PRICE_KNOWN,
                 shoppingPersistedTabData.getPreviousPriceMicros());
     }
+
+    @UiThreadTest
+    @SmallTest
+    @Test
+    public void testIncognitoTabDisabled() throws TimeoutException {
+        TabImpl tab = mock(TabImpl.class);
+        doReturn(true).when(tab).isIncognito();
+        CallbackHelper callbackHelper = new CallbackHelper();
+        ShoppingPersistedTabData.from(tab, (res) -> {
+            Assert.assertNull(res);
+            callbackHelper.notifyCalled();
+        });
+        callbackHelper.waitForCallback(0);
+    }
+
+    @UiThreadTest
+    @SmallTest
+    @Test
+    public void testCustomTabsDisabled() throws TimeoutException {
+        TabImpl tab = mock(TabImpl.class);
+        doReturn(true).when(tab).isCustomTab();
+        CallbackHelper callbackHelper = new CallbackHelper();
+        ShoppingPersistedTabData.from(tab, (res) -> {
+            Assert.assertNull(res);
+            callbackHelper.notifyCalled();
+        });
+        callbackHelper.waitForCallback(0);
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java
index 727d685..40f73e2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java
@@ -7,7 +7,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -34,7 +33,6 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.UserDataHost;
-import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
@@ -120,8 +118,6 @@
     private ArgumentCaptor<TabObserver> mTabObserverCaptor;
 
     private CompositorAnimationHandler mCompositorAnimationHandler;
-    private ObservableSupplierImpl<BrowserControlsStateProvider>
-            mBrowserControlsStateProviderSupplier = new ObservableSupplierImpl<>();
 
     private StaticLayout mStaticLayout;
     private PropertyModel mModel;
@@ -164,14 +160,12 @@
         doReturn(HEIGHT).when(mViewHost).getHeight();
         doReturn(mCompositorAnimationHandler).when(mUpdateHost).getAnimationHandler();
 
-        mStaticLayout = new StaticLayout(mContext, mUpdateHost, mRenderHost, mViewHost,
-                mRequestSupplier, mTabModelSelector, mTabContentManager,
-                mBrowserControlsStateProviderSupplier, () -> mTopUiThemeColorProvider);
+        mStaticLayout =
+                new StaticLayout(mContext, mUpdateHost, mRenderHost, mViewHost, mRequestSupplier,
+                        mTabModelSelector, mTabContentManager, mBrowserControlsStateProvider,
+                        () -> mTopUiThemeColorProvider, mStaticTabSceneLayer);
         mModel = mStaticLayout.getModelForTesting();
 
-        mStaticLayout.setSceneLayerForTesting(mStaticTabSceneLayer);
-        mStaticLayout.onFinishNativeInitialization();
-
         doReturn(BACKGROUND_COLOR).when(mTopUiThemeColorProvider).getBackgroundColor(any());
         doReturn(TOOLBAR_BACKGROUND_COLOR)
                 .when(mTopUiThemeColorProvider)
@@ -188,7 +182,6 @@
     @After
     public void tearDown() {
         CompositorAnimationHandler.setTestingMode(false);
-        mStaticLayout.setSceneLayerForTesting(null);
         mStaticLayout.setTextBoxBackgroundColorForTesting(null);
         mStaticLayout.setToolbarTextBoxAlphaForTesting(null);
         mStaticLayout.destroy();
@@ -198,8 +191,6 @@
         assertEquals(mTabModelSelector, mStaticLayout.getTabModelSelectorForTesting());
         assertEquals(mTabContentManager, mStaticLayout.getTabContentManagerForTesting());
 
-        assertNull(mStaticLayout.getBrowserControlsStateProviderForTesting());
-        mBrowserControlsStateProviderSupplier.set(mBrowserControlsStateProvider);
         assertEquals(mBrowserControlsStateProvider,
                 mStaticLayout.getBrowserControlsStateProviderForTesting());
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java
index 6ed6b39d..836b341 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabStatusBarColorProviderTest.java
@@ -58,10 +58,17 @@
     }
 
     @Test
-    public void fallsBackWhenOpenedByChrome() {
+    public void undefinedWhenOpenedByChromeNoCustom() {
         when(mCustomTabIntentDataProvider.isOpenedByChrome()).thenReturn(true);
+        when(mColorProvider.hasCustomToolbarColor()).thenReturn(false);
+        Assert.assertEquals(UNDEFINED_STATUS_BAR_COLOR, getStatusBarColor(mTab));
+    }
 
-        Assert.assertEquals(FALLBACK_COLOR, getStatusBarColor(mTab));
+    @Test
+    public void openedByChromeWithCustom() {
+        when(mCustomTabIntentDataProvider.isOpenedByChrome()).thenReturn(true);
+        when(mColorProvider.hasCustomToolbarColor()).thenReturn(true);
+        Assert.assertEquals(USER_PROVIDED_COLOR, getStatusBarColor(mTab));
     }
 
     @Test
@@ -108,6 +115,6 @@
     }
 
     private int getStatusBarColor(Tab tab) {
-        return mStatusBarColorProvider.getBaseStatusBarColor(tab, FALLBACK_COLOR);
+        return mStatusBarColorProvider.getBaseStatusBarColor(tab);
     }
 }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 6aa4e560..dd05a92 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-93.0.4567.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-93.0.4568.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index 7590e4b..9ae049251 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -172,12 +172,15 @@
     ]
   }
 
+  if (is_chromeos_ash || is_chromeos_lacros) {
+    deps += [ "//chromeos/dbus/constants" ]
+  }
+
   if (is_chromeos_ash) {
     deps += [
       "//ash/constants",
       "//chrome/browser/chromeos",
       "//chromeos",
-      "//chromeos/dbus/constants",
       "//chromeos/memory:memory",
     ]
   }
diff --git a/chrome/app/app_management_strings.grdp b/chrome/app/app_management_strings.grdp
index 2de07fc..0cecba8 100644
--- a/chrome/app/app_management_strings.grdp
+++ b/chrome/app/app_management_strings.grdp
@@ -58,4 +58,10 @@
   <message name="IDS_APP_MANAGEMENT_INTENT_SHARING_BROWSER_OPEN" desc="Label for the intent sharing option to open in the browser.">
     Open in Chrome browser
   </message>
+  <message name="IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_EXPLANATION" desc="Label for the intent sharing description for when the app is set to open in tab mode.">
+    <ph name="APP_NAME">$1<ex>Gmail</ex></ph> is set to open in a new browser tab, supported links will also open in the browser.
+  </message>
+  <message name="IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_LEARN_MORE" desc="Label for the learn more link for when the app is set to open in tab mode.">
+    Learn more.
+  </message>
 </grit-part>
diff --git a/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_EXPLANATION.png.sha1 b/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_EXPLANATION.png.sha1
new file mode 100644
index 0000000..0c7d6fe6
--- /dev/null
+++ b/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_EXPLANATION.png.sha1
@@ -0,0 +1 @@
+594a0a8e956b72122e513eea65b874ce48494a70
\ No newline at end of file
diff --git a/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_LEARN_MORE.png.sha1 b/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_LEARN_MORE.png.sha1
new file mode 100644
index 0000000..0c7d6fe6
--- /dev/null
+++ b/chrome/app/app_management_strings_grdp/IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_LEARN_MORE.png.sha1
@@ -0,0 +1 @@
+594a0a8e956b72122e513eea65b874ce48494a70
\ No newline at end of file
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 8898d0a..495893e 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -107,7 +107,6 @@
 #include <signal.h>
 
 #include "chrome/app/chrome_crash_reporter_client.h"
-#include "chrome/app/shutdown_signal_handlers_posix.h"
 #endif
 
 #if BUILDFLAG(ENABLE_NACL) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
@@ -115,6 +114,10 @@
 #include "components/nacl/zygote/nacl_fork_delegate_linux.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/dbus/constants/dbus_paths.h"
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_paths.h"
 #include "ash/constants/ash_switches.h"
@@ -122,7 +125,6 @@
 #include "chrome/browser/ash/dbus/ash_dbus_helper.h"
 #include "chrome/browser/chromeos/boot_times_recorder.h"
 #include "chrome/browser/chromeos/startup_settings_cache.h"
-#include "chromeos/dbus/constants/dbus_paths.h"
 #include "chromeos/hugepage_text/hugepage_text.h"
 #include "chromeos/memory/kstaled.h"
 #include "chromeos/memory/memory.h"
@@ -181,6 +183,7 @@
 #include "chrome/common/chrome_paths_lacros.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"  // nogncheck
 #include "chromeos/lacros/lacros_chrome_service_impl.h"
+#include "chromeos/lacros/lacros_dbus_helper.h"
 #endif
 
 base::LazyInstance<ChromeContentGpuClient>::DestructorAtExit
@@ -538,6 +541,9 @@
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // Initialize D-Bus for Lacros.
+  chromeos::LacrosInitializeDBus();
+
   // LacrosChromeServiceImpl instance needs the sequence of the main thread,
   // and needs to be created earlier than incoming Mojo invitation handling.
   // This also needs ThreadPool sequences to post some tasks internally.
@@ -550,8 +556,12 @@
         lacros_chrome_service_->init_params();
     // default_paths may null on browser_tests.
     if (init_params->default_paths) {
+      base::FilePath drivefs;
+      if (init_params->default_paths->drivefs.has_value())
+        drivefs = init_params->default_paths->drivefs.value();
       chrome::SetLacrosDefaultPaths(init_params->default_paths->documents,
-                                    init_params->default_paths->downloads);
+                                    init_params->default_paths->downloads,
+                                    drivefs);
     }
   }
 #endif
@@ -778,6 +788,8 @@
   chrome::RegisterPathProvider();
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::RegisterPathProvider();
+#endif
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   chromeos::dbus_paths::RegisterPathProvider();
 #endif
 #if BUILDFLAG(ENABLE_NACL) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 777d27bd..8d41d06 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9038,6 +9038,9 @@
             =1 {Show}
             other {Show all}}
         </message>
+        <message name="IDS_NOTIFICATION_MUTED_ACTION_SNOOZE" desc="Action button text to snooze future notifications during the current screen capture session." translateable="false">
+          Snooze
+        </message>
       </if>
       <if expr="use_titlecase">
         <message name="IDS_NOTIFICATION_MUTED_TITLE" desc="In Title Case: Title of a notification showing how many new notifications are currently hidden. The number is always greater than zero.">
@@ -9050,6 +9053,9 @@
             =1 {Show}
             other {Show All}}
         </message>
+        <message name="IDS_NOTIFICATION_MUTED_ACTION_SNOOZE" desc="In Title Case: Action button text to snooze future notifications during the current screen capture session." translateable="false">
+          Snooze
+        </message>
       </if>
       <if expr="is_android">
         <message name="IDS_NOTIFICATION_BUTTON_MANAGE" desc="Text of a button shown on notification permission requests, that opens the Chrome notifications settings page. This allows users to edit notification settings when a site asks them to allow notifications.">
@@ -10135,29 +10141,6 @@
         Share
       </message>
 
-      <!-- Local Device Discovery display strings -->
-      <if expr="enable_service_discovery">
-        <message name="IDS_LOCAL_DISCOVERY_NOTIFICATION_TITLE_PRINTER" desc="Title of notification for one or more new printer showing up on your network. [ICU Syntax]">
-        {NUM_PRINTER, plural,
-         =1 {New printer on your network}
-         other {New printers on your network}}
-        </message>
-        <message name="IDS_LOCAL_DISCOVERY_NOTIFICATION_CONTENTS_PRINTER" desc="Contents of notification for one or more new printers showing up on your network. [ICU Syntax]">
-        {NUM_PRINTER, plural,
-          =1 {Add the printer to Google Cloud Print so you can print from anywhere.}
-          other {Add # printers to Google Cloud Print so you can print from anywhere.}}
-        </message>
-        <message name="IDS_LOCAL_DISCOVERY_SERVICE_NAME_PRINTER" desc="Display name for notification for a new printer showing up on your network">
-          Google Cloud Print
-        </message>
-        <message name="IDS_LOCAL_DISCOVERY_NOTIFICATION_BUTTON_PRINTER" desc="Message on registration button for printer">
-          Add to Cloud Print
-        </message>
-        <message name="IDS_LOCAL_DISCOVERY_NOTIFICATIONS_DISABLE_BUTTON_LABEL" desc="Label for button disabling local device notifications">
-          Don't show this again
-        </message>
-      </if>
-
       <!--Printer registration message for local discovery and Print Preview-->
       <message name="IDS_CLOUD_PRINT_REGISTER_PRINTER_INFORMATION" desc="Information about registering printers with Google Cloud Print shown to the user before they confirm registration.">
         Documents are <ph name="BEGIN_LINK_HELP">&lt;a is="action-link" href="https://support.google.com/cloudprint/answer/2541843" target="_blank"&gt;</ph>sent to Google<ph name="END_LINK_HELP">&lt;/a&gt;</ph> to prepare them for printing. View, edit and manage your printers and printer history on the <ph name="BEGIN_LINK_DASHBOARD">&lt;a is="action-link" href="https://www.google.com/cloudprint#jobs" target="_blank"&gt;</ph>Google Cloud Print dashboard<ph name="END_LINK_DASHBOARD">&lt;/a&gt;</ph>.
diff --git a/chrome/app/generated_resources_grd/IDS_NOTIFICATION_MUTED_ACTION_SNOOZE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NOTIFICATION_MUTED_ACTION_SNOOZE.png.sha1
new file mode 100644
index 0000000..b8a2703c
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NOTIFICATION_MUTED_ACTION_SNOOZE.png.sha1
@@ -0,0 +1 @@
+758e32c99761fc7ec02431a100bdb43024b1db3f
\ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_ta.xtb b/chrome/app/resources/chromium_strings_ta.xtb
index 846527c..00862db 100644
--- a/chrome/app/resources/chromium_strings_ta.xtb
+++ b/chrome/app/resources/chromium_strings_ta.xtb
@@ -35,7 +35,7 @@
 <translation id="2483889755041906834">Chromium இல்</translation>
 <translation id="2485422356828889247">நிறுவல் நீக்கு</translation>
 <translation id="2535480412977113886">உங்கள் கணக்கின் உள்நுழைவு விவரங்கள் காலாவதியாகிவிட்டதால், உங்கள் தரவை Chromium OS ஆல் ஒத்திசைக்க முடியவில்லை.</translation>
-<translation id="2560420686485554789">கோப்புகளைப் பதிவிறக்க, Chromiumக்குச் சேமிப்பிட அணுகல் தேவை</translation>
+<translation id="2560420686485554789">ஃபைல்களைப் பதிவிறக்க, Chromiumக்குச் சேமிப்பிட அணுகல் தேவை</translation>
 <translation id="2572494885440352020">Chromium உதவி</translation>
 <translation id="2577788541081224677">உங்கள் அனைத்துச் சாதனங்களிலும் Chromium தொடர்பான அனைத்தையும் அணுக, உள்நுழைந்து ஒத்திசைவை இயக்கவும்.</translation>
 <translation id="2580426763510374355">Chromium OSஸை நிறுவு</translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb
index cc540a4..226482c7 100644
--- a/chrome/app/resources/generated_resources_af.xtb
+++ b/chrome/app/resources/generated_resources_af.xtb
@@ -4396,6 +4396,7 @@
 <translation id="5794700615121138172">Linux- gedeelde lêers</translation>
 <translation id="5794786537412027208">Beëindig alle Chrome-programme</translation>
 <translation id="5797070761912323120">Google kan jou geskiedenis gebruik om Search, advertensies en ander Google-dienste te personaliseer</translation>
+<translation id="5797521893972859201">Vee geskiedenis uit, ook in die soekkassie</translation>
 <translation id="5798079537501238810">Werwe kan betalinghanteerders installeer</translation>
 <translation id="579907812742603813">beskermde inhoud</translation>
 <translation id="579915268381781820">Jou sekuriteitsleutel is verwyder.</translation>
@@ -4479,6 +4480,7 @@
 <translation id="5900302528761731119">Google-profielfoto</translation>
 <translation id="590036993063074298">Besonderhede van weerspieëlinggehalte</translation>
 <translation id="5901069264981746702">Jou vingerafdrukdata word veilig geberg en verlaat nooit jou <ph name="DEVICE_TYPE" /> nie. <ph name="LINK_BEGIN" />Kom meer te wete<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Skakel oor na oortjie wat tans vasvang</translation>
 <translation id="5901494423252125310">Drukkerdeur is oop</translation>
 <translation id="5901630391730855834">Geel</translation>
 <translation id="5904614460720589786">Kon nie <ph name="APP_NAME" /> opstel nie weens 'n opstellingprobleem. Kontak jou administrateur. Foutkode: <ph name="ERROR_CODE" />.</translation>
@@ -4751,6 +4753,7 @@
 <translation id="6196854373336333322">Die uitbreiding "<ph name="EXTENSION_NAME" />" het beheer oor jou instaanbedienerinstellings oorgeneem, wat beteken dat dit enigiets wat jy aanlyn doen, kan verander of breek of daarop kan inluister. As jy nie seker is hoekom hierdie verandering plaasgevind het nie, wil jy dit waarskynlik nie hê nie.</translation>
 <translation id="6198102561359457428">Meld af en meld dan weer aan …</translation>
 <translation id="6198252989419008588">Verander PIN</translation>
+<translation id="6200047250927636406">Gooi lêer weg</translation>
 <translation id="6202304368170870640">Jy kan jou PIN gebruik om aan te meld of jou toestel te ontsluit.</translation>
 <translation id="6206311232642889873">Kopieer prent</translation>
 <translation id="6207200176136643843">Stel terug na verstek-zoemvlak</translation>
@@ -5319,6 +5322,7 @@
 <translation id="6831043979455480757">Vertaal</translation>
 <translation id="6833479554815567477">Oortjie is verwyder uit groep <ph name="GROUP_NAME" /> – <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Wissel na 'n slim en veilige blaaier</translation>
+<translation id="6834652994408928492">Donkermodus sal outomaties met sonsondergang aanskakel</translation>
 <translation id="683540480453879381">Maak <ph name="FILE_EXTENSIONS" />-lêers oop</translation>
 <translation id="6835762382653651563">Koppel aan die internet om jou <ph name="DEVICE_TYPE" /> op te dateer.</translation>
 <translation id="6838034009068684089">Vra wanneer 'n werf vensters op jou skerms wil oopmaak en plaas (aanbeveel)</translation>
@@ -6031,6 +6035,7 @@
 <translation id="7622114377921274169">Laai tans.</translation>
 <translation id="7622768823216805500">Werwe installeer gewoonlik betalinghanteerders vir inkopiekenmerke soos makliker betaalpunte</translation>
 <translation id="7622903810087708234">Wagwoordbesonderhede</translation>
+<translation id="7622966771025050155">Skakel oor na oortjie wat vasgevang is</translation>
 <translation id="7624337243375417909">caps lock is af</translation>
 <translation id="7625568159987162309">Bekyk toestemmings en data wat oor werwe heen geberg is</translation>
 <translation id="7628201176665550262">Herlaaitempo</translation>
@@ -6197,6 +6202,7 @@
 <translation id="7784067724422331729">Sekuriteitsinstellings op jou rekenaar het hierdie lêer geblokkeer.</translation>
 <translation id="7784796923038949829">Kan nie werf se data lees of verander nie</translation>
 <translation id="778480864305029524">Om kitsverbinding te gebruik, skakel kennisgewings vir Google Play Dienste aan.</translation>
+<translation id="7785471469930192436">Sien jou soekenjin se instruksies om jou soekgeskiedenis uit te vee, indien toepaslik</translation>
 <translation id="7786889348652477777">Herlaai program</translation>
 <translation id="7787308148023287649">Wys op 'n ander skerm</translation>
 <translation id="7788298548579301890">'n Ander program op jou rekenaar het 'n program bygevoeg wat dalk die manier sal verander waarop Chrome werk.
@@ -6808,6 +6814,7 @@
 <translation id="8438566539970814960">Maak soektogte en blaai-ervaring beter</translation>
 <translation id="8439506636278576865">Bied aan om bladsye in hierdie taal te vertaal</translation>
 <translation id="8440630305826533614">Linux-programme</translation>
+<translation id="8446225304314102060">Wissel na oortjie <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Kom meer te wete</translation>
 <translation id="8447409163267621480">Sluit óf Ctrl óf Alt in</translation>
 <translation id="8448729345478502352">Maak items op jou skerm kleiner of groter</translation>
@@ -7469,6 +7476,7 @@
 <translation id="9148058034647219655">Gaan uit</translation>
 <translation id="9148126808321036104">Meld weer aan …</translation>
 <translation id="9148963623915467028">Hierdie werf het toegang tot jou ligging.</translation>
+<translation id="9149529198050266366">Donkermodus sal outomaties met sonsopkoms afskakel</translation>
 <translation id="9149866541089851383">Wysig …</translation>
 <translation id="9150045010208374699">Gebruik jou kamera</translation>
 <translation id="9150079578948279438">Profiel kon nie verwyder word nie. Probeer weer of kontak jou diensverskaffer vir tegniese steundiens.</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index f824aad..9e57adfa 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -467,6 +467,7 @@
 <translation id="1507246803636407672">إل&amp;غاء</translation>
 <translation id="1508491105858779599">ضع إصبعك على جهاز جهاز استشعار بصمات الإصبع لإلغاء قفل الجهاز.</translation>
 <translation id="1508575541972276599">‏الإصدار الحالي هو Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">استعادة المجموعة</translation>
 <translation id="1509281256533087115">‏الوصول إلى أي <ph name="DEVICE_NAME_AND_VENDOR" /> عبر USB</translation>
 <translation id="1509960214886564027">قد تتوقف الميزات عن العمل في العديد من المواقع الإلكترونية.</translation>
 <translation id="1510238584712386396">مشغِّل التطبيقات</translation>
@@ -589,6 +590,7 @@
 <translation id="1627408615528139100">تم التنزيل من قبل</translation>
 <translation id="1628948239858170093">هل تريد فحص الملف قبل فتحه؟</translation>
 <translation id="1629314197035607094">انتهت صلاحية كلمة المرور.</translation>
+<translation id="1629451755632656601">‏هل تسمح لمحرك البحث Google بالبحث عن خصومات مناسبة على السلع والمنتجات التي تضيفها إلى سلات التسوّق الخاصة بك؟</translation>
 <translation id="1630300831289687074">‏ستتمكّن من استخدام جهاز Chromebook قريبًا.</translation>
 <translation id="163072119192489970">المواقع الإلكترونية التي يُسمح لها بإنهاء إرسال البيانات أو استلامها</translation>
 <translation id="1630768113285622200">إعادة التشغيل والمواصلة</translation>
@@ -1294,6 +1296,7 @@
 <translation id="236117173274098341">تحسين</translation>
 <translation id="2361340419970998028">جارٍ إرسال الملاحظات...</translation>
 <translation id="236141728043665931">حظر الدخول إلى الميكروفون دومًا</translation>
+<translation id="2363744066037724557">استعادة النافذة</translation>
 <translation id="2364498172489649528">تم الاجتياز.</translation>
 <translation id="2365507699358342471">يمكن لهذا الموقع الاطلاع على النصوص والصور التي تم نسخها إلى الحافظة.</translation>
 <translation id="2367972762794486313">إظهار التطبيقات</translation>
@@ -2679,6 +2682,7 @@
 <translation id="3857807444929313943">رفع الإصبع، ثم اللمس مرة أخرى</translation>
 <translation id="3861638017150647085">اسم المستخدم "<ph name="USERNAME" />" غير متوفر.</translation>
 <translation id="3861977424605124250">إظهار عند بدء التشغيل</translation>
+<translation id="386239283124269513">استعادة المجموعة</translation>
 <translation id="3862788408946266506">‏يجب تثبيت التطبيق الذي يحمل سمة البيان "kiosk_only" في وضع الكشك على نظام تشغيل Chrome.</translation>
 <translation id="3865414814144988605">درجة الدقة</translation>
 <translation id="3866249974567520381">الوصف</translation>
@@ -5651,6 +5655,7 @@
 <translation id="7225179976675429563">نوع الشبكة مفقود</translation>
 <translation id="7228479291753472782">معالجة الإعدادات التي تحدد ما إذا كان بإمكان المواقع الإلكترونية استخدام ميزات مثل المواقع الجغرافية والميكروفون والكاميرا، وغيرها</translation>
 <translation id="7228523857728654909">قفل الشاشة وتسجيل الدخول</translation>
+<translation id="7230222852462421043">استعادة النافذة</translation>
 <translation id="7230787553283372882">تخصيص حجم النَّص</translation>
 <translation id="7232750842195536390">تعذّرت إعادة التسمية</translation>
 <translation id="7234010996000898150">‏جارٍ إلغاء عملية الاسترداد من Linux</translation>
@@ -6260,12 +6265,14 @@
 <translation id="7853747251428735">المزيد من الأد&amp;وات</translation>
 <translation id="7855678561139483478">نقل علامة التبويب إلى نافذة جديدة</translation>
 <translation id="7857093393627376423">اقتراحات نصية</translation>
+<translation id="7857675386615530425">‏البحث في جزء من الصفحة باستخدام "عدسة Google"</translation>
 <translation id="7857949311770343000">هل هذه هي صفحة علامة التبويب الجديدة التي كنت تتوقع ظهورها؟</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">الخدمة: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">ال&amp;تنزيلات</translation>
 <translation id="7861846108263890455">‏لغة حساب Google</translation>
 <translation id="7864539943188674973">إيقاف البلوتوث</translation>
+<translation id="7866230141401327032">‏البحث في جزء من الصفحة باستخدام "عدسة Google"</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - تم الإقران</translation>
 <translation id="7870730066603611552">مراجعة خيارات المزامنة بعد الإعداد</translation>
 <translation id="7870790288828963061">‏لا توجد إصدارات أحدث لتطبيق Kiosk. لا يوجد شيء لتحديثه. يُرجى إزالة جهاز USB.</translation>
@@ -6842,6 +6849,7 @@
 <translation id="850875081535031620">لم يتم العثور على أي برامج ضارة</translation>
 <translation id="8509177919508253835">إعادة ضبط مفاتيح الأمان وإنشاء أرقام التعريف الشخصية</translation>
 <translation id="8509646642152301857">تعذّر تنزيل قاموس التدقيق الإملائي.</translation>
+<translation id="8509967119010808787">للبحث في علامات التبويب، انقر هنا.</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{لم يتم العثور على أي كلمات مرور ضعيفة.}=1{تم العثور على كلمة مرور واحدة ({COUNT}) ضعيفة.}two{تم العثور على كلمتَي مرور ({COUNT}) ضعيفتَين.}few{تم العثور على {COUNT} كلمات مرور ضعيفة.}many{تم العثور على {COUNT} كلمة مرور ضعيفة.}other{تم العثور على {COUNT} كلمة مرور ضعيفة.}}</translation>
 <translation id="8512476990829870887">إنهاء العملية</translation>
 <translation id="851263357009351303">السماح للموقع <ph name="HOST" /> بعرض الصور دومًا</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb
index f3ecacb..febf34d0 100644
--- a/chrome/app/resources/generated_resources_as.xtb
+++ b/chrome/app/resources/generated_resources_as.xtb
@@ -467,6 +467,7 @@
 <translation id="1507246803636407672">&amp;অগ্ৰাহ্য কৰক</translation>
 <translation id="1508491105858779599">ডিভাইচটো আনলক কৰিবলৈ আপোনাৰ আঙুলিটো ফিংগাৰপ্ৰিণ্ট ছেন্সত ৰাখক।</translation>
 <translation id="1508575541972276599">বৰ্তমানৰ সংস্কৰণটো হৈছে Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">গোট পুনঃস্থাপন কৰক</translation>
 <translation id="1509281256533087115">USBৰ জৰিয়তে যিকোনো <ph name="DEVICE_NAME_AND_VENDOR" /> এক্সেছ কৰক</translation>
 <translation id="1509960214886564027">বহুতো ছাইটৰ সুবিধাসমূহ ব্যাহত হ’ব পাৰে</translation>
 <translation id="1510238584712386396">লঞ্চাৰ</translation>
@@ -586,6 +587,7 @@
 <translation id="1627408615528139100">ইতিমধ্যে ডাউনল’ড কৰা আছে</translation>
 <translation id="1628948239858170093">খোলাৰ আগতে ফাইলটো স্কেন কৰিবনে?</translation>
 <translation id="1629314197035607094">পাছৱৰ্ডৰ ম্যাদ উকলিল</translation>
+<translation id="1629451755632656601">Googleক আপোনাৰ কাৰ্টসমূহত ব্যক্তিগতকৃত ৰেহাই মূল্য সন্ধান কৰিবলৈ দিবনে?</translation>
 <translation id="1630300831289687074">আপুনি সোনকালেই নিজৰ Chromebook ব্যৱহাৰ কৰিব পাৰিব।</translation>
 <translation id="163072119192489970">ডেটা পঠিওৱা অথবা গ্ৰহণ কৰাটো সম্পূৰ্ণ কৰাৰ অনুমতি আছে</translation>
 <translation id="1630768113285622200">ৰিষ্টাৰ্ট কৰক আৰু অব্যাহত ৰাখক</translation>
@@ -1303,6 +1305,7 @@
 <translation id="236117173274098341">Optimize</translation>
 <translation id="2361340419970998028">মতামত পঠিয়াই থকা হৈছে…</translation>
 <translation id="236141728043665931">মাইক্ৰ'ফ'নৰ এক্সেছ সদায়েই অৱৰোধ কৰক</translation>
+<translation id="2363744066037724557">ৱিণ্ড’ পুনঃস্থাপন কৰক</translation>
 <translation id="2364498172489649528">পাছ কৰিছে</translation>
 <translation id="2365507699358342471">এই ছাইটটোৱে ক্লীপব’র্ডলৈ প্ৰতিলিপি কৰা পাঠ আৰু প্ৰতিচ্ছবিসমূহ চাব পাৰে।</translation>
 <translation id="2367972762794486313">এপ্‌সমূহ দেখুৱাওক</translation>
@@ -2685,6 +2688,7 @@
 <translation id="3857807444929313943">ওপৰলৈ উঠাওক, তাৰ পিছত পুনৰ স্পৰ্শ কৰক</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" ব্যৱহাৰকাৰীৰ নামটো উপলব্ধ নহয়</translation>
 <translation id="3861977424605124250">আৰম্ভ হওঁতে দেখুৱাওক</translation>
+<translation id="386239283124269513">গোট পুনঃস্থাপন কৰক</translation>
 <translation id="3862788408946266506">’kiosk_only’ মেনিফেষ্ট বৈশিষ্ট থকা এপক Chrome OS কিঅ’স্ক ম’ডতেই ইনষ্টল কৰিব লাগিব</translation>
 <translation id="3865414814144988605">ৰিজ'লিউশ্বন</translation>
 <translation id="3866249974567520381">বিৱৰণ</translation>
@@ -5651,6 +5655,7 @@
 <translation id="7225179976675429563">নেটৱৰ্কৰ প্ৰকাৰ নাই</translation>
 <translation id="7228479291753472782">ৱেবছাইটে ভৌগলিক অৱস্থান, মাইক্ৰ'ফ'ন. কেমেৰা ইত্যাদি সুবিধাসমূহ ব্যৱহাৰ কৰিব পাৰিব নে নাই সেয়া নির্দিষ্ট কৰা ছেটিংসমূহ সলনি সাল সলনি কৰে।</translation>
 <translation id="7228523857728654909">স্ক্ৰীণ লক আৰু ছাইন-ইন</translation>
+<translation id="7230222852462421043">ৱিণ্ড’ পুনঃস্থাপন কৰক</translation>
 <translation id="7230787553283372882">আপোনাৰ পাঠৰ আকাৰ কাষ্টমাইজ কৰক</translation>
 <translation id="7232750842195536390">নাম সলনি কৰিব পৰা নগ’ল</translation>
 <translation id="7234010996000898150">Linux পুনঃস্থাপন কৰাটো বাতিল কৰি থকা হৈছে</translation>
@@ -6258,12 +6263,14 @@
 <translation id="7853747251428735">অধিক সঁজু&amp;লি</translation>
 <translation id="7855678561139483478">টেবটো নতুন ৱিণ্ড’লৈ স্থানান্তৰ কৰক</translation>
 <translation id="7857093393627376423">পাঠৰ পৰামৰ্শ</translation>
+<translation id="7857675386615530425">Google Lensৰ সহায়ত পৃষ্ঠাখনৰ কোনো অংশত সন্ধান কৰক</translation>
 <translation id="7857949311770343000">আপুনি বিচৰা নতুন পৃষ্ঠা এইটো হয়নে?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">সেৱা: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ডাউনল'ডসমূহ</translation>
 <translation id="7861846108263890455">Google একাউণ্টৰ ভাষা</translation>
 <translation id="7864539943188674973">ব্লুটুথ অক্ষম কৰক</translation>
+<translation id="7866230141401327032">Google Lensৰ সহায়ত পৃষ্ঠাখনৰ কোনো অংশত সন্ধান কৰক</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - যোৰা লগোৱা আছে</translation>
 <translation id="7870730066603611552">ছেটআপৰ পিছত ছিংকৰ বিকল্পসমূহৰ পৰ্যালোচনা কৰক</translation>
 <translation id="7870790288828963061">কিঅ'স্ক এপৰ কোনো নতুন সংস্কৰণ পোৱা নাই। আপডে'ট কৰিবলৈ একো নাই। অনুগ্ৰহ কৰি USB ষ্টিক আঁতৰাওক।</translation>
@@ -6837,6 +6844,7 @@
 <translation id="850875081535031620">কোনো ক্ষতিকাৰক ছফ্টৱেৰ পোৱা নগ'ল</translation>
 <translation id="8509177919508253835">সুৰক্ষা চাবিসমূহ ৰিছেট কৰি পিন সৃষ্টি কৰক</translation>
 <translation id="8509646642152301857">বানান পৰীক্ষা কৰা অভিধান ডাউনল’ড কৰিব পৰা নগ’ল।</translation>
+<translation id="8509967119010808787">আপোনাৰ টেবসমূহ সন্ধান কৰিবলৈ ইয়াত ক্লিক কৰক</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{কোনো দুৰ্বল পাছৱৰ্ড বিচাৰি পোৱা নগ’ল}=1{{COUNT} টা দুৰ্বল পাছৱৰ্ড বিচাৰি পোৱা গৈছে}one{{COUNT} টা দুৰ্বল পাছৱৰ্ড বিচাৰি পোৱা গৈছে}other{{COUNT} টা দুৰ্বল পাছৱৰ্ড বিচাৰি পোৱা গৈছে}}</translation>
 <translation id="8512476990829870887">প্ৰক্ৰিয়া সমাপ্ত কৰক</translation>
 <translation id="851263357009351303"><ph name="HOST" />ক সদায়েই প্ৰতিচ্ছবি দেখুৱাবলৈ অনুমতি দিয়ক</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index 144665982..6b3964a 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -151,7 +151,7 @@
 <translation id="1153356358378277386">Сдвоени устройства</translation>
 <translation id="1153636665119721804">Програма на Google за разширена защита</translation>
 <translation id="1155816283571436363">Установява се връзка с телефона ви</translation>
-<translation id="1161575384898972166">Моля, влезте в/ъв <ph name="TOKEN_NAME" />, за да експортирате сертификата за клиентската програма.</translation>
+<translation id="1161575384898972166">Моля, влезте в(ъв) <ph name="TOKEN_NAME" />, за да експортирате сертификата за клиентската програма.</translation>
 <translation id="116173250649946226">Администраторът ви е задал стандартна тема, която не може да бъде променена.</translation>
 <translation id="1163931534039071049">&amp;Преглед на изходния код на рамката</translation>
 <translation id="1164891049599601209">Въведена в измамнически сайт</translation>
@@ -4517,7 +4517,7 @@
 <translation id="5939719276406088041">Прекият път не бе създаден</translation>
 <translation id="594048410531370124">Неразпознат клавиш. Натиснете произволен клавиш, за да <ph name="RESPONSE" />.</translation>
 <translation id="5941153596444580863">Добавяне на човек...</translation>
-<translation id="5941343993301164315">Моля, влезте в/ъв <ph name="TOKEN_NAME" />.</translation>
+<translation id="5941343993301164315">Моля, влезте в(ъв) <ph name="TOKEN_NAME" />.</translation>
 <translation id="5941711191222866238">Намаляване</translation>
 <translation id="5942779427914696408">Видимост на устройството</translation>
 <translation id="5943127421590245687">Потвърждаването ви бе успешно. За отключване и възстановяване на локалните си данни, моля, въведете старата си парола за <ph name="DEVICE_TYPE" />.</translation>
@@ -5286,7 +5286,7 @@
 <translation id="6802031077390104172"><ph name="USAGE" /> (<ph name="OID" />)</translation>
 <translation id="680488281839478944">Виртуалната машина <ph name="DEFAULT_VM_NAME" /> съществува</translation>
 <translation id="6805038906417219576">OK</translation>
-<translation id="6805647936811177813">Моля, влезте в/ъв <ph name="TOKEN_NAME" />, за да импортирате сертификат за клиентската програма от <ph name="HOST_NAME" />.</translation>
+<translation id="6805647936811177813">Моля, влезте в(ъв) <ph name="TOKEN_NAME" />, за да импортирате сертификат за клиентската програма от <ph name="HOST_NAME" />.</translation>
 <translation id="680572642341004180">Активиране на проследяването на RLZ в <ph name="SHORT_PRODUCT_OS_NAME" />.</translation>
 <translation id="6808039367995747522">За да продължите, поставете и докоснете ключа си за сигурност</translation>
 <translation id="6808193438228982088">Лисица</translation>
@@ -5414,7 +5414,7 @@
 <translation id="6938789263968032501">Хора</translation>
 <translation id="6939815295902433669">Преглед на софтуера на устройството</translation>
 <translation id="694168622559714949">Основният език е зададен от администратора ви и не може да се променя.</translation>
-<translation id="6941937518557314510">Моля, влезте в/ъв <ph name="TOKEN_NAME" />, за да удостоверите самоличността си пред <ph name="HOST_NAME" /> със сертификата си.</translation>
+<translation id="6941937518557314510">Моля, влезте в(ъв) <ph name="TOKEN_NAME" />, за да удостоверите самоличността си пред <ph name="HOST_NAME" /> със сертификата си.</translation>
 <translation id="6943060957016121200">Активиране на функцията за незабавен тетъринг</translation>
 <translation id="6943176775188458830">Анулиране на отпечатването</translation>
 <translation id="6945221475159498467">Избиране</translation>
@@ -5676,7 +5676,7 @@
 <translation id="7238640585329759787">Когато настройката е активирана, сайтовете може да използват описаните тук техники за защита на поверителността, за да предоставят съдържанието и услугите си. Техниките съдържат алтернативи на проследяването в различни сайтове. С течение на времето може да бъдат добавени други изпробвания.</translation>
 <translation id="7239108166256782787">Прехвърлянето бе анулирано от <ph name="DEVICE_NAME" /></translation>
 <translation id="7240339475467890413">Да се установи ли връзка с новата точка за достъп?</translation>
-<translation id="7241389281993241388">Моля, влезте в/ъв <ph name="TOKEN_NAME" />, за да импортирате сертификата за клиентската програма.</translation>
+<translation id="7241389281993241388">Моля, влезте в(ъв) <ph name="TOKEN_NAME" />, за да импортирате сертификата за клиентската програма.</translation>
 <translation id="7243632151880336635">Изчистване и изход</translation>
 <translation id="7243784282103630670">При надстройването на Linux възникна грешка. Ще възстановим контейнера посредством резервното копие.</translation>
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (най-добро)</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index 3414941..0c8f631f1 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -467,6 +467,7 @@
 <translation id="1507246803636407672">এবং পরিত্যাগ</translation>
 <translation id="1508491105858779599">ডিভাইসটি আনলক করতে আঙ্গুলের ছাপ নেওয়ার সেন্সরে আপনার আঙ্গুল রাখুন।</translation>
 <translation id="1508575541972276599">বর্তমান ভার্সন হল Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;গ্রুপ আবার আগের অবস্থায় ফিরিয়ে আনুন</translation>
 <translation id="1509281256533087115">USB এর মাধ্যমে যেকোনো <ph name="DEVICE_NAME_AND_VENDOR" /> অ্যাক্সেস করুন</translation>
 <translation id="1509960214886564027">একাধিক সাইটের ফিচারগুলি কাজ নাও করতে পারে</translation>
 <translation id="1510238584712386396">লঞ্চার</translation>
@@ -589,6 +590,7 @@
 <translation id="1627408615528139100">আগে থেকেই ডাউনলোড করা আছে</translation>
 <translation id="1628948239858170093">খোলার আগে ফাইল স্ক্যান করতে চান?</translation>
 <translation id="1629314197035607094">পাসওয়ার্ডের মেয়াদ শেষ হয়ে গেছে</translation>
+<translation id="1629451755632656601">Google-কে কি আপনি কার্টে যোগ করা আইটেমে কোনও ছাড় পাবেন কিনা তা খুঁজে দেখতে অনুমতি দিতে চান ?</translation>
 <translation id="1630300831289687074">শীঘ্রই আপনার Chromebook ব্যবহার করতে পারবেন।</translation>
 <translation id="163072119192489970">ডেটা পাওয়া বা পাঠানো শেষ করার অনুমতি দেওয়া হয়েছে</translation>
 <translation id="1630768113285622200">রিস্টার্ট করুন ও চালিয়ে যান</translation>
@@ -1306,6 +1308,7 @@
 <translation id="236117173274098341">Optimize</translation>
 <translation id="2361340419970998028">মতামত পাঠানো হচ্ছে…</translation>
 <translation id="236141728043665931">মাইক্রোফোনের অ্যাক্সেস সর্বদা অবরুদ্ধ রাখুন</translation>
+<translation id="2363744066037724557">&amp;উইন্ডো আবার আগের অবস্থায় ফিরিয়ে আনুন</translation>
 <translation id="2364498172489649528">পাস করেছে</translation>
 <translation id="2365507699358342471">এই সাইটটি ক্লিপবোর্ডে কপি করা টেক্সট এবং ছবি দেখতে পায়।</translation>
 <translation id="2367972762794486313">অ্যাপ্লিকেশানগুলি দেখান</translation>
@@ -2688,6 +2691,7 @@
 <translation id="3857807444929313943">আঙ্গুল লিফ্ট করে আবার টাচ করুন</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" ইউজারনেমটি পাওয়া যাচ্ছে না</translation>
 <translation id="3861977424605124250">স্টার্টআপে দেখুন</translation>
+<translation id="386239283124269513">&amp;গ্রুপ আবার আগের অবস্থায় ফিরিয়ে আনুন</translation>
 <translation id="3862788408946266506">'Kiosk_only' ম্যানিফেস্ট অ্যাট্রিবিউটের সাথে অ্যাপকে অবশ্যই Chrome OS কিয়স্ক মোডে ইনস্টল করতে হবে</translation>
 <translation id="3865414814144988605">রেজোলিউশন</translation>
 <translation id="3866249974567520381">বর্ণনা</translation>
@@ -5664,6 +5668,7 @@
 <translation id="7225179976675429563">নেটওয়ার্কের প্রকার হারিয়ে গেছে</translation>
 <translation id="7228479291753472782">ভৌগোলিক লোকেশন, মাইক্রোফোন, ক্যামেরা, ইত্যাদির মতো বৈশিষ্ট্যগুলিকে ওয়েবসাইটগুলি ব্যবহার করতে পারবে কিনা তা নির্দিষ্ট করতে সেটিংস নিয়ন্ত্রণ করে।</translation>
 <translation id="7228523857728654909">স্ক্রিন লক এবং সাইন-ইন করুন</translation>
+<translation id="7230222852462421043">&amp;উইন্ডো আবার আগের অবস্থায় ফিরিয়ে আনুন</translation>
 <translation id="7230787553283372882">আপনার পাঠ্যের আকার কাস্টমাইজ করুন</translation>
 <translation id="7232750842195536390">নাম পরিবর্তন করা যায়নি</translation>
 <translation id="7234010996000898150">Linux ফিরিয়ে আনা বাতিল করা হচ্ছে</translation>
@@ -6272,12 +6277,14 @@
 <translation id="7853747251428735">আরও সর&amp;ঞ্জাম</translation>
 <translation id="7855678561139483478">ট্যাবটি নতুন উইন্ডোতে খুলুন</translation>
 <translation id="7857093393627376423">টেক্সট সংক্রান্ত সাজেশন</translation>
+<translation id="7857675386615530425">Google Lens ব্যবহার করে পৃষ্ঠার অংশ সার্চ করুন</translation>
 <translation id="7857949311770343000">আপনি কি এই পৃষ্ঠাটিকে নতুন ট্যাব পৃষ্ঠা হিসাবে আশা করছিলেন?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">পরিষেবা: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ডাউনলোড করা</translation>
 <translation id="7861846108263890455">Google অ্যাকাউন্টের ভাষা</translation>
 <translation id="7864539943188674973">ব্লুটুথ অক্ষম করুন</translation>
+<translation id="7866230141401327032">Google Lens ব্যবহার করে পৃষ্ঠার অংশ সার্চ করুন</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - যুক্ত করা হয়েছে</translation>
 <translation id="7870730066603611552">সেট-আপের পর সিঙ্কের বিকল্পগুলির রিভিউ</translation>
 <translation id="7870790288828963061">এর থেকে আরও নতুন ভার্সনের কোনও কিয়স্ক অ্যাপ্লিকেশন পাওয়া যায়নি৷ USB স্টিক সরান৷</translation>
@@ -6854,6 +6861,7 @@
 <translation id="850875081535031620">কোনও ক্ষতিকর সফ্টওয়্যার খুঁজে পাওয়া যায়নি</translation>
 <translation id="8509177919508253835">নিরাপত্তা কী ডিভাইস রিসেট করে পিন তৈরি করুন</translation>
 <translation id="8509646642152301857">বানান পরীক্ষক অভিধান ডাউনলোড করা যায়নি৷</translation>
+<translation id="8509967119010808787">আপনার ট্যাব সার্চ করতে, এখানে ক্লিক করুন</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{কোনও দুর্বল পাসওয়ার্ড পাওয়া যায়নি}=1{{COUNT}টি দুর্বল পাসওয়ার্ড পাওয়া গেছে}one{{COUNT}টি দুর্বল পাসওয়ার্ড পাওয়া গেছে}other{{COUNT}টি দুর্বল পাসওয়ার্ড পাওয়া গেছে}}</translation>
 <translation id="8512476990829870887">প্রক্রিয়া সমাপ্ত করুন</translation>
 <translation id="851263357009351303">ছবিগুলি দেখানোর জন্য সর্বদা <ph name="HOST" />-কে অনুমতি দিন </translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb
index a034f303..c832024 100644
--- a/chrome/app/resources/generated_resources_bs.xtb
+++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -4393,6 +4393,7 @@
 <translation id="5794700615121138172">Dijeljeni folderi na Linuxu</translation>
 <translation id="5794786537412027208">Napusti sve Chromeove aplikacije</translation>
 <translation id="5797070761912323120">Google može koristiti vašu historiju za personalizaciju Pretraživanja, oglasa i drugih Googleovih usluga</translation>
+<translation id="5797521893972859201">Briše povijest, uključujući u okviru za pretraživanje</translation>
 <translation id="5798079537501238810">Web lokacije mogu instalirati obrađivače plaćanja</translation>
 <translation id="579907812742603813">zaštićeni sadržaj</translation>
 <translation id="579915268381781820">Vaš sigurnosni ključ je uklonjen.</translation>
@@ -4476,6 +4477,7 @@
 <translation id="5900302528761731119">Fotografija Google profila</translation>
 <translation id="590036993063074298">Detalji o kvalitetu preslikavanja</translation>
 <translation id="5901069264981746702">Vaši podaci otiska prsta su sigurno pohranjeni i nikada ne napuštaju uređaj <ph name="DEVICE_TYPE" />. <ph name="LINK_BEGIN" />Saznajte više<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Prijeđi na snimanje kartice</translation>
 <translation id="5901494423252125310">Otvoren je poklopac štampača</translation>
 <translation id="5901630391730855834">Žuta</translation>
 <translation id="5904614460720589786">Postavljanje aplikacije <ph name="APP_NAME" /> nije uspjelo zbog problema s konfiguracijom. Kontaktirajte administratora. Kȏd greške: <ph name="ERROR_CODE" />.</translation>
@@ -4748,6 +4750,7 @@
 <translation id="6196854373336333322">Ekstenzija "<ph name="EXTENSION_NAME" />" je preuzela kontrolu nad postavkama vašeg proksi servera, što znači da može promijeniti, prekinuti ili prisluškivati sve što radite na mreži. Ako niste sigurni zašto je došlo do ove promjene, vjerovatno je i ne želite.</translation>
 <translation id="6198102561359457428">Odjavite se i ponovo se prijavite…</translation>
 <translation id="6198252989419008588">Promijeni PIN</translation>
+<translation id="6200047250927636406">Odbaci datoteku</translation>
 <translation id="6202304368170870640">Možete koristiti PIN za prijavu ili otključavanje uređaja.</translation>
 <translation id="6206311232642889873">Kop&amp;iraj sliku</translation>
 <translation id="6207200176136643843">Vraćanje na zadani nivo zumiranja</translation>
@@ -5316,6 +5319,7 @@
 <translation id="6831043979455480757">Prevedi</translation>
 <translation id="6833479554815567477">Kartica je uklonjena iz grupe <ph name="GROUP_NAME" /> – <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Prijeđite na pametan i siguran preglednik</translation>
+<translation id="6834652994408928492">Tamni način rada uključit će se automatski kad sunce zađe</translation>
 <translation id="683540480453879381">otvara <ph name="FILE_EXTENSIONS" /> fajlove</translation>
 <translation id="6835762382653651563">Povežite se na internet da ažurirate uređaj <ph name="DEVICE_TYPE" />.</translation>
 <translation id="6838034009068684089">Traži odobrenje kada web lokacija želi otvarati i postavljati prozore na ekranima (preporučeno)</translation>
@@ -6028,6 +6032,7 @@
 <translation id="7622114377921274169">Punjenje.</translation>
 <translation id="7622768823216805500">Web lokacije obično instaliraju obrađivače plaćanja za funkcije kupovine, naprimjer, za lakše plaćanje</translation>
 <translation id="7622903810087708234">Detalji o lozinci</translation>
+<translation id="7622966771025050155">Prijeđi na snimljenu karticu</translation>
 <translation id="7624337243375417909">velika slova su isključena</translation>
 <translation id="7625568159987162309">Pregledajte dopuštenja i podatke pohranjene na web-lokacijama</translation>
 <translation id="7628201176665550262">Brzina osvježavanja</translation>
@@ -6194,6 +6199,7 @@
 <translation id="7784067724422331729">Sigurnosne postavke na vašem računalu blokirale su ovu datoteku.</translation>
 <translation id="7784796923038949829">Nije moguće čitati ili mijenjati podatke web lokacije</translation>
 <translation id="778480864305029524">Za korištenje Trenutnog povezivanja putem mobitela, uključite obavještenja za Google Play usluge.</translation>
+<translation id="7785471469930192436">Potražite upute za svoju tražilicu da biste saznali kako izbrisati svoju povijest pretraživanja, ako je primjenjivo</translation>
 <translation id="7786889348652477777">&amp;Ponovo učitaj stranicu</translation>
 <translation id="7787308148023287649">Prikaz na drugom ekranu</translation>
 <translation id="7788298548579301890">Drugi program na vašem računaru je dodao aplikaciju koja može promijeniti način na koji Chrome radi.
@@ -6806,6 +6812,7 @@
 <translation id="8438566539970814960">Poboljšajte pretraživanje i pregledanje</translation>
 <translation id="8439506636278576865">Ponudi prijevod stranica na ovom jeziku</translation>
 <translation id="8440630305826533614">Linux aplikacije</translation>
+<translation id="8446225304314102060">Prijeđi na karticu <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Saznajte više</translation>
 <translation id="8447409163267621480">Uključite Ctrl ili Alt</translation>
 <translation id="8448729345478502352">Smanjite ili povećajte stavke na ekranu</translation>
@@ -7469,6 +7476,7 @@
 <translation id="9148058034647219655">Izađi</translation>
 <translation id="9148126808321036104">Prijavi se ponovo</translation>
 <translation id="9148963623915467028">Ova web lokacija može pristupiti vašoj lokaciji.</translation>
+<translation id="9149529198050266366">Tamni način rada isključit će se automatski kad sunce izađe</translation>
 <translation id="9149866541089851383">Uredi…</translation>
 <translation id="9150045010208374699">Korištenje kamere</translation>
 <translation id="9150079578948279438">Uklanjanje profila nije uspjelo. Pokušajte ponovo ili kontaktirajte svog mobilnog operatora za tehničku podršku.</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb
index fca4cd2..feb286b 100644
--- a/chrome/app/resources/generated_resources_cs.xtb
+++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -1432,7 +1432,7 @@
 <translation id="2514326558286966059">Rychlejší odemknutí otiskem prstu</translation>
 <translation id="2515586267016047495">Alt</translation>
 <translation id="2515807442171220586">Přidružte ještě jeden přepínač</translation>
-<translation id="2517472476991765520">Vyhledat</translation>
+<translation id="2517472476991765520">Naskenovat</translation>
 <translation id="2518024842978892609">Používat vaše klientské certifikáty</translation>
 <translation id="2519517390894391510">Název profilu certifikátu</translation>
 <translation id="2520644704042891903">Čeká se na dostupný soket...</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb
index aedacd1..5deba6e 100644
--- a/chrome/app/resources/generated_resources_de.xtb
+++ b/chrome/app/resources/generated_resources_de.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;Verwerfen</translation>
 <translation id="1508491105858779599">Legen Sie den Finger auf den Fingerabdrucksensor, um das Gerät zu entsperren.</translation>
 <translation id="1508575541972276599">Aktuell verwenden Sie Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">Gruppe wiederherstellen</translation>
 <translation id="1509281256533087115">Auf <ph name="DEVICE_NAME_AND_VENDOR" /> per USB zugreifen</translation>
 <translation id="1509960214886564027">Funktionen auf vielen Websites funktionieren möglicherweise nicht mehr</translation>
 <translation id="1510238584712386396">Launcher</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">Bereits heruntergeladen</translation>
 <translation id="1628948239858170093">Datei vor dem Öffnen scannen?</translation>
 <translation id="1629314197035607094">Passwort abgelaufen</translation>
+<translation id="1629451755632656601">Google personalisierte Rabatte für Ihre Einkaufswagen finden lassen?</translation>
 <translation id="1630300831289687074">Sie können Ihr Chromebook demnächst verwenden.</translation>
 <translation id="163072119192489970">Dürfen den Datenversand und ‑empfang abschließen</translation>
 <translation id="1630768113285622200">Neu starten und fortfahren</translation>
@@ -1287,6 +1289,7 @@
 <translation id="236117173274098341">Optimieren</translation>
 <translation id="2361340419970998028">Feedback wird gesendet…</translation>
 <translation id="236141728043665931">Zugriff auf das Mikrofon immer blockieren</translation>
+<translation id="2363744066037724557">Fenster wiederherstellen</translation>
 <translation id="2364498172489649528">Bestanden</translation>
 <translation id="2365507699358342471">Diese Website kann Texte und Bilder aus der Zwischenablage abrufen.</translation>
 <translation id="2367972762794486313">Apps anzeigen</translation>
@@ -2670,6 +2673,7 @@
 <translation id="3857807444929313943">Anheben und erneut berühren</translation>
 <translation id="3861638017150647085">Der Nutzername "<ph name="USERNAME" />" ist nicht verfügbar</translation>
 <translation id="3861977424605124250">Beim Start anzeigen</translation>
+<translation id="386239283124269513">Gruppe wiederherstellen</translation>
 <translation id="3862788408946266506">App mit Manifest-Attribut "kiosk_only" muss im Chrome OS-Kioskmodus installiert werden</translation>
 <translation id="3865414814144988605">Auflösung</translation>
 <translation id="3866249974567520381">Beschreibung</translation>
@@ -5640,6 +5644,7 @@
 <translation id="7225179976675429563">Netzwerktyp fehlt.</translation>
 <translation id="7228479291753472782">Einstellungen bearbeiten, die festlegen, ob Websites Funktionen wie die Standortbestimmung, das Mikrofon, die Kamera usw. verwenden dürfen</translation>
 <translation id="7228523857728654909">Bildschirmsperre und Anmeldung</translation>
+<translation id="7230222852462421043">Fenster wiederherstellen</translation>
 <translation id="7230787553283372882">Textgröße anpassen</translation>
 <translation id="7232750842195536390">Fehler beim Umbenennen</translation>
 <translation id="7234010996000898150">Linux-Wiederherstellung wird abgebrochen</translation>
@@ -6249,12 +6254,14 @@
 <translation id="7853747251428735">Weitere Too&amp;ls</translation>
 <translation id="7855678561139483478">Tab in ein neues Fenster verschieben</translation>
 <translation id="7857093393627376423">Textvorschläge</translation>
+<translation id="7857675386615530425">Mit Google Lens auf einem Teil der Seite suchen</translation>
 <translation id="7857949311770343000">Ist das die "Neuer Tab"-Seite, die Sie erwartet hatten?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Dienst: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Downloads</translation>
 <translation id="7861846108263890455">Sprache des Google-Kontos</translation>
 <translation id="7864539943188674973">Bluetooth deaktivieren</translation>
+<translation id="7866230141401327032">Mit Google Lens auf einem Teil der Seite suchen</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> – gekoppelt</translation>
 <translation id="7870730066603611552">Synchronisierungsoptionen nach der Einrichtung überprüfen</translation>
 <translation id="7870790288828963061">Es wurden keine Kiosk-Apps mit neuerer Version gefunden. Es sind keine Updates vorhanden. Bitte entfernen Sie den USB-Stick.</translation>
@@ -6830,6 +6837,7 @@
 <translation id="850875081535031620">Keine schädliche Software gefunden</translation>
 <translation id="8509177919508253835">Sicherheitsschlüssel zurücksetzen und PINs erstellen</translation>
 <translation id="8509646642152301857">Beim Herunterladen des Wörterbuchs für die Rechtschreibprüfung ist ein Fehler aufgetreten.</translation>
+<translation id="8509967119010808787">Zum Suchen auf Ihren Tabs hier klicken</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Keine schwachen Passwörter gefunden}=1{{COUNT} schwaches Passwort gefunden}other{{COUNT} schwache Passwörter gefunden}}</translation>
 <translation id="8512476990829870887">Prozess beenden</translation>
 <translation id="851263357009351303">Anzeige von Bildern für <ph name="HOST" /> immer zulassen</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index a96419c..931aaf0 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -589,7 +589,7 @@
 <translation id="1627408615528139100">Έγινε ήδη λήψη</translation>
 <translation id="1628948239858170093">Σάρωση αρχείου πριν από το άνοιγμα;</translation>
 <translation id="1629314197035607094">Ο κωδικός πρόσβασης έληξε</translation>
-<translation id="1629451755632656601">Να επιτρέπεται στην Google να βρίσκει εξατομικευμένες εκτπώσεις στα καρότσια σας;</translation>
+<translation id="1629451755632656601">Να επιτρέπεται στην Google να βρίσκει εξατομικευμένες εκπτώσεις στα καρότσια σας;</translation>
 <translation id="1630300831289687074">Θα μπορέσετε να χρησιμοποιήσετε σύντομα το Chromebook.</translation>
 <translation id="163072119192489970">Επιτρέπεται να ολοκληρώνουν την αποστολή και τη λήψη δεδομένων</translation>
 <translation id="1630768113285622200">Επαναφορά και συνέχεια</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index 8590225..0bc7821 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -643,6 +643,7 @@
 <translation id="16815041330799488">Do not allow sites to see text and images copied to the clipboard</translation>
 <translation id="1682548588986054654">New Incognito Window</translation>
 <translation id="1682867089915960590">Turn on caret browsing?</translation>
+<translation id="1684279041537802716">Accent colour</translation>
 <translation id="1686550358074589746">Enable glide typing</translation>
 <translation id="168715261339224929">To get your bookmarks on all your devices, turn on sync.</translation>
 <translation id="1688867105868176567">Clear site data?</translation>
@@ -839,6 +840,7 @@
 <translation id="1868193363684582383">"Ok Google"</translation>
 <translation id="1868553836791672080">Password check is not available in Chromium</translation>
 <translation id="1869433484041798909">Bookmark button</translation>
+<translation id="1871098866036088250">Open in Chrome browser</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>
@@ -914,6 +916,7 @@
 <translation id="1954597385941141174">Sites can ask to connect to USB devices</translation>
 <translation id="1954813140452229842">Error mounting share. Please check your credentials and try again.</translation>
 <translation id="1956050014111002555">The file contained multiple certificates, none of which were imported:</translation>
+<translation id="1956167375087861299">Not allowed to use identifiers to play protected content</translation>
 <translation id="1956390763342388273">This will upload all files from '<ph name="FOLDER_PATH" />'. Only do this if you trust the site.</translation>
 <translation id="1962233722219655970">This page uses a Native Client app that doesn't work on your computer.</translation>
 <translation id="1963227389609234879">Remove all</translation>
@@ -1171,6 +1174,7 @@
 <translation id="2229161054156947610">More than 1 hour left</translation>
 <translation id="222931766245975952">File truncated</translation>
 <translation id="2230005943220647148">Celsius</translation>
+<translation id="2231160360698766265">Sites can play protected content</translation>
 <translation id="2231238007119540260">If you delete a server certificate, you restore the usual security checks for that server and require that it uses a valid certificate.</translation>
 <translation id="2232751457155581899">Sites can ask to track your camera position</translation>
 <translation id="2232876851878324699">The file contained one certificate, which was not imported:</translation>
@@ -1360,6 +1364,7 @@
 <translation id="2440604414813129000">View s&amp;ource</translation>
 <translation id="244231003699905658">Invalid address. Please check the address and try again.</translation>
 <translation id="2442916515643169563">Text shadow</translation>
+<translation id="2443487764245141020">Sites may also need to recognise your device using an identifier</translation>
 <translation id="2445081178310039857">Extension root directory is required.</translation>
 <translation id="2445484935443597917">Create a new profile</translation>
 <translation id="244641233057214044">Related to your search</translation>
@@ -1469,6 +1474,7 @@
 <translation id="2542050502251273923">Sets the debugging level of the network connection manager and other services using ff_debug.</translation>
 <translation id="2544352060595557290">This Tab</translation>
 <translation id="2546283357679194313">Cookies and site data</translation>
+<translation id="2546302722632337735">Don't allow sites to use identifiers to play protected content</translation>
 <translation id="2548347166720081527">Allowed <ph name="PERMISSION" /></translation>
 <translation id="2548545707296594436">Reset eSIM profile cache</translation>
 <translation id="2549985041256363841">Start recording</translation>
@@ -2223,6 +2229,7 @@
 <translation id="3391482648489541560">file editing</translation>
 <translation id="3391512812407811893">Privacy Sandbox trials</translation>
 <translation id="339178315942519818">View notifications from your chat apps on your <ph name="DEVICE_TYPE" /></translation>
+<translation id="3394850431319394743">Allowed to use identifiers to play protected content</translation>
 <translation id="3396800784455899911">By clicking the 'Accept and continue' button, you agree to the processing described above for these Google services.</translation>
 <translation id="339722927132407568">Freezes</translation>
 <translation id="3399432415385675819">Notifications will be disabled</translation>
@@ -2757,6 +2764,7 @@
 <translation id="3928659086758780856">Low on ink</translation>
 <translation id="3929426037718431833">These extensions can see and change information on this site.</translation>
 <translation id="3930155420525972941">Move Group to New Window</translation>
+<translation id="3930602610362250897">To play content protected by copyright, sites may need to use a content protection service</translation>
 <translation id="3930737994424905957">Looking for devices</translation>
 <translation id="3930968231047618417">Background colour</translation>
 <translation id="3933283459331715412">Restore deleted password for <ph name="USERNAME" /></translation>
@@ -2879,6 +2887,7 @@
 <translation id="4061374428807229313">To share, right-click on a folder in the Files app, then select 'Share with Parallels Desktop'.</translation>
 <translation id="406213378265872299">Customised behaviours</translation>
 <translation id="4062561150282203854">Sync your <ph name="DEVICE_TYPE" /> apps, settings and more</translation>
+<translation id="4064575710864784237">1x</translation>
 <translation id="4065876735068446555">The network you are using (<ph name="NETWORK_ID" />) may require you to visit its login page.</translation>
 <translation id="4066207411788646768">Please check your connection to see available printers in your network</translation>
 <translation id="4068776064906523561">Saved fingerprints</translation>
@@ -3275,6 +3284,7 @@
 <translation id="4535127706710932914">Default Profile</translation>
 <translation id="4535767533210902251">The fingerprint sensor is the top-right key on your keyboard. Touch it lightly with any finger.</translation>
 <translation id="4536140153723794651">Sites that can always use cookies</translation>
+<translation id="4538163005498287211">Based on your wallpaper</translation>
 <translation id="4538417792467843292">Delete word</translation>
 <translation id="4538792345715658285">Installed by enterprise policy.</translation>
 <translation id="4541123282641193691">Couldn't verify your account. Please try again or restart your Chromebook.</translation>
@@ -4557,6 +4567,7 @@
 <translation id="5984222099446776634">Recently Visited</translation>
 <translation id="5985458664595100876">Invalid URL format. Supported formats are \\server\share and smb://server/share.</translation>
 <translation id="598810097218913399">Remove assignment</translation>
+<translation id="5989136665954016134">Opening supported links</translation>
 <translation id="5990266201903445068">Wi-Fi only</translation>
 <translation id="5990386583461751448">Translated</translation>
 <translation id="599131315899248751">{NUM_APPLICATIONS,plural, =1{To ensure that you can keep browsing the web, ask your administrator to remove this application.}other{To ensure that you can keep browsing the web, ask your administrator to remove these applications.}}</translation>
@@ -5260,6 +5271,7 @@
 <translation id="6787839852456839824">Keyboard shortcuts</translation>
 <translation id="6788210894632713004">Unpacked extension</translation>
 <translation id="6789592661892473991">Split horizontal</translation>
+<translation id="678982761784843853">Protected content IDs</translation>
 <translation id="6790428901817661496">Play</translation>
 <translation id="6790497603648687708"><ph name="EXTENSION_NAME" /> was added remotely</translation>
 <translation id="6790820461102226165">Add Person...</translation>
@@ -5740,6 +5752,7 @@
 <translation id="7328867076235380839">Invalid combination</translation>
 <translation id="7329154610228416156">Sign-in failed because it was configured to use a non-secure URL (<ph name="BLOCKED_URL" />). Please contact your administrator.</translation>
 <translation id="7332053360324989309">Dedicated worker: <ph name="SCRIPT_URL" /></translation>
+<translation id="7334014994694414993">Choose the colour theme for Launcher, shelf, Quick Settings and more</translation>
 <translation id="7334274148831027933">Enable docked magnifier</translation>
 <translation id="7335974957018254119">Use spell check for</translation>
 <translation id="7336799713063880535">Notifications blocked.</translation>
@@ -6631,6 +6644,7 @@
 <translation id="8241868517363889229">Read and change your bookmarks</translation>
 <translation id="8242370300221559051">Enable Play Store</translation>
 <translation id="8242426110754782860">Proceed</translation>
+<translation id="8243948765190375130">Media quality may be reduced</translation>
 <translation id="8244514732452879619">Lights out soon</translation>
 <translation id="8246776524656196770">Protect your security key with a PIN (Personal Identification Number)</translation>
 <translation id="8248050856337841185">&amp;Paste</translation>
@@ -7441,6 +7455,7 @@
 <translation id="9128870381267983090">Connect to network</translation>
 <translation id="9130015405878219958">Invalid mode entered.</translation>
 <translation id="9131487537093447019">Send messages to and receive messages from Bluetooth devices.</translation>
+<translation id="9134066738478820307">Sites can use identifiers to play protected content</translation>
 <translation id="913411432238655354">Restore apps on start-up</translation>
 <translation id="9137013805542155359">Show original</translation>
 <translation id="9137157311132182254">Preferred search engine</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index f55b7ee..ed1b40c8 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;Descartar</translation>
 <translation id="1508491105858779599">Coloca tu dedo en el sensor de huella dactilar para desbloquear el dispositivo.</translation>
 <translation id="1508575541972276599">La versión actual es Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;Restablecer grupo</translation>
 <translation id="1509281256533087115">Accede a cualquier <ph name="DEVICE_NAME_AND_VENDOR" /> a través de USB</translation>
 <translation id="1509960214886564027">Es posible que las características de muchos sitios no funcionen de forma correcta</translation>
 <translation id="1510238584712386396">Selector</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">Ya se descargó</translation>
 <translation id="1628948239858170093">¿Quieres analizar el archivo antes de abrirlo?</translation>
 <translation id="1629314197035607094">Caducó la contraseña</translation>
+<translation id="1629451755632656601">¿Deseas que Google busque descuentos personalizados en tus carritos?</translation>
 <translation id="1630300831289687074">Pronto podrás usar tu Chromebook.</translation>
 <translation id="163072119192489970">Puede completar el envío y la recepción de datos</translation>
 <translation id="1630768113285622200">Restablecer y continuar</translation>
@@ -1287,6 +1289,7 @@
 <translation id="236117173274098341">Optimizar</translation>
 <translation id="2361340419970998028">Enviando comentarios…</translation>
 <translation id="236141728043665931">Bloquear siempre el acceso al micrófono</translation>
+<translation id="2363744066037724557">&amp;Restablecer ventana</translation>
 <translation id="2364498172489649528">Aprobado</translation>
 <translation id="2365507699358342471">Este sitio puede ver el texto y las imágenes que se copiaron en el portapapeles.</translation>
 <translation id="2367972762794486313">Mostrar aplicaciones</translation>
@@ -2670,6 +2673,7 @@
 <translation id="3857807444929313943">Levanta el dedo y vuelve a tocar</translation>
 <translation id="3861638017150647085">El nombre de usuario "<ph name="USERNAME" />" no está disponible</translation>
 <translation id="3861977424605124250">Mostrar al inicio</translation>
+<translation id="386239283124269513">&amp;Restablecer grupo</translation>
 <translation id="3862788408946266506">Se debe instalar la app con el atributo del manifiesto "kiosk_only" en el modo kiosco del Sistema operativo Chrome</translation>
 <translation id="3865414814144988605">Resolución</translation>
 <translation id="3866249974567520381">Descripción</translation>
@@ -5645,6 +5649,7 @@
 <translation id="7225179976675429563">Falta el tipo de red.</translation>
 <translation id="7228479291753472782">Se manipularán las opciones de configuración que especifican si los sitios web pueden usar funciones, como la ubicación geográfica, el micrófono, la cámara, etc.</translation>
 <translation id="7228523857728654909">Bloqueo de pantalla y acceso</translation>
+<translation id="7230222852462421043">&amp;Restablecer ventana</translation>
 <translation id="7230787553283372882">Personaliza el tamaño del texto</translation>
 <translation id="7232750842195536390">No se pudo cambiar el nombre</translation>
 <translation id="7234010996000898150">Cancelando el restablecimiento de Linux</translation>
@@ -6254,12 +6259,14 @@
 <translation id="7853747251428735">&amp;Más herramientas</translation>
 <translation id="7855678561139483478">Mueve la pestaña a una ventana nueva</translation>
 <translation id="7857093393627376423">Sugerencias de texto</translation>
+<translation id="7857675386615530425">Busca parte de la página con Google Lens</translation>
 <translation id="7857949311770343000">¿Esta es la página Nueva pestaña que esperabas ver?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Servicio: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Descargas</translation>
 <translation id="7861846108263890455">Idioma de la Cuenta de Google</translation>
 <translation id="7864539943188674973">Desactivar Bluetooth</translation>
+<translation id="7866230141401327032">Busca parte de la página con Google Lens</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> sincronizado</translation>
 <translation id="7870730066603611552">Revisar las opciones de sincronización después de la configuración</translation>
 <translation id="7870790288828963061">No se encontraron aplicaciones de kiosco con una versión más reciente. No hay nada para actualizar. Desconecta el dispositivo USB.</translation>
@@ -6836,6 +6843,7 @@
 <translation id="850875081535031620">No se encontró software dañino</translation>
 <translation id="8509177919508253835">Restablece las llaves de seguridad y crea PIN</translation>
 <translation id="8509646642152301857">Ocurrió un error en la descarga del diccionario del corrector ortográfico.</translation>
+<translation id="8509967119010808787">Para buscar tus pestañas, haz clic aquí.</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{No se encontraron contraseñas poco seguras.}=1{Se encontró {COUNT} contraseña poco segura.}other{Se encontraron {COUNT} contraseñas poco seguras.}}</translation>
 <translation id="8512476990829870887">Finalizar proceso</translation>
 <translation id="851263357009351303">Siempre permitir que <ph name="HOST" /> muestre imágenes</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb
index f18a1364..70b48579 100644
--- a/chrome/app/resources/generated_resources_et.xtb
+++ b/chrome/app/resources/generated_resources_et.xtb
@@ -4385,6 +4385,7 @@
 <translation id="5794700615121138172">Linuxi jagatud kaustad</translation>
 <translation id="5794786537412027208">Sule kõik Chrome'i rakendused</translation>
 <translation id="5797070761912323120">Google võib kasutada teie ajalugu otsingu, reklaamide ja muude Google'i teenuste isikupärastamiseks</translation>
+<translation id="5797521893972859201">Tühjendab ajaloo, sh otsingukasti ajaloo</translation>
 <translation id="5798079537501238810">Saidid saavad installida maksete töötlejaid</translation>
 <translation id="579907812742603813">kaitstud sisu</translation>
 <translation id="579915268381781820">Teie turvavõti eemaldati.</translation>
@@ -4468,6 +4469,7 @@
 <translation id="5900302528761731119">Google'i profiilifoto</translation>
 <translation id="590036993063074298">Peegeldamise kvaliteedi üksikasjad</translation>
 <translation id="5901069264981746702">Teie sõrmejäljeandmed talletatakse turvaliselt ja neid ei edastata seadmest <ph name="DEVICE_TYPE" /> väljapoole. <ph name="LINK_BEGIN" />Lisateave<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Lülitu jäädvustavale vahelehele</translation>
 <translation id="5901494423252125310">Printeri luuk on avatud</translation>
 <translation id="5901630391730855834">Kollane</translation>
 <translation id="5904614460720589786">Rakendust <ph name="APP_NAME" /> ei saanud konfiguratsiooniprobleemi tõttu seadistada. Võtke ühendust administraatoriga. Veakood: <ph name="ERROR_CODE" />.</translation>
@@ -4740,6 +4742,7 @@
 <translation id="6196854373336333322">Laiendus „<ph name="EXTENSION_NAME" />” on hõivanud puhverserveri seaded, mis tähendab, et see saab muuta, lõhkuda või kuulata pealt kogu teie veebitegevust. Kui te pole kindel, miks see muudatus toimus, siis te tõenäoliselt ei taha seda.</translation>
 <translation id="6198102561359457428">Logige välja ja uuesti sisse ...</translation>
 <translation id="6198252989419008588">Muuda PIN-koodi</translation>
+<translation id="6200047250927636406">Loobu failist</translation>
 <translation id="6202304368170870640">PIN-kood võimaldab seadmesse sisse logida või selle avada.</translation>
 <translation id="6206311232642889873">Kop&amp;eeri pilt</translation>
 <translation id="6207200176136643843">Lähtesta suumi vaiketasemele</translation>
@@ -5308,6 +5311,7 @@
 <translation id="6831043979455480757">Tõlgi</translation>
 <translation id="6833479554815567477">Vaheleht eemaldati grupist <ph name="GROUP_NAME" /> – <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Minge üle nutikale ja turvalisele brauserile</translation>
+<translation id="6834652994408928492">Tume režiim lülitub päikeseloojangul automaatselt sisse</translation>
 <translation id="683540480453879381">Avada failid <ph name="FILE_EXTENSIONS" /></translation>
 <translation id="6835762382653651563">Seadme <ph name="DEVICE_TYPE" /> värskendamiseks looge ühendus Internetiga.</translation>
 <translation id="6838034009068684089">Küsi, kui sait soovib ekraanikuvadel aknaid avada ja neid sinna paigutada (soovitatav)</translation>
@@ -6020,6 +6024,7 @@
 <translation id="7622114377921274169">Laadimine.</translation>
 <translation id="7622768823216805500">Saidid installivad maksetöötlejaid tavaliselt ostufunktsioonide jaoks, näiteks hõlpsamaks maksmiseks</translation>
 <translation id="7622903810087708234">Parooli üksikasjad</translation>
+<translation id="7622966771025050155">Lülitu jäädvustatud vahelehele</translation>
 <translation id="7624337243375417909">suurtähelukk on välja lülitatud</translation>
 <translation id="7625568159987162309">Kuva load ja mitmel saidil talletatud andmed</translation>
 <translation id="7628201176665550262">Värskendussagedus</translation>
@@ -6186,6 +6191,7 @@
 <translation id="7784067724422331729">Teie arvuti turvaseaded blokeerisid selle faili.</translation>
 <translation id="7784796923038949829">Saidi andmeid ei saa lugeda ega muuta</translation>
 <translation id="778480864305029524">Automaatse jagamise kasutamiseks lülitage Google Play teenuste märguanded sisse.</translation>
+<translation id="7785471469930192436">Vaadake oma otsingumootori juhiseid otsinguajaloo kustutamise kohta, kui see on asjakohane</translation>
 <translation id="7786889348652477777">&amp;Laadi rakendus uuesti</translation>
 <translation id="7787308148023287649">Kuvage teisel ekraanil</translation>
 <translation id="7788298548579301890">Muu arvutis olev programm lisas rakenduse, mis võib muuta Chrome'i tööd.
@@ -6798,6 +6804,7 @@
 <translation id="8438566539970814960">Otsingute ja sirvimise paremaks muutmine</translation>
 <translation id="8439506636278576865">Paku selles keeles olevate lehtede tõlkimist</translation>
 <translation id="8440630305826533614">Linuxi rakendused</translation>
+<translation id="8446225304314102060">Lülitu vahelehele <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Lisateave</translation>
 <translation id="8447409163267621480">Kaasake Ctrl või Alt</translation>
 <translation id="8448729345478502352">Muutke ekraanil kuvatud üksused väiksemaks või suuremaks</translation>
@@ -7459,6 +7466,7 @@
 <translation id="9148058034647219655">Välju</translation>
 <translation id="9148126808321036104">Logige uuesti sisse</translation>
 <translation id="9148963623915467028">Sellel saidil on juurdepääs teie asukohale.</translation>
+<translation id="9149529198050266366">Tume režiim lülitub päikesetõusul automaatselt välja</translation>
 <translation id="9149866541089851383">Muuda...</translation>
 <translation id="9150045010208374699">Kaamera kasutamine</translation>
 <translation id="9150079578948279438">Profiili ei saanud eemaldada. Proovige uuesti või võtke tehnilise toe saamiseks ühendust operaatoriga.</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb
index 685c4e9..ce216bd 100644
--- a/chrome/app/resources/generated_resources_eu.xtb
+++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;Baztertu</translation>
 <translation id="1508491105858779599">Gailua desblokeatzeko, jarri hatza hatz-marken sentsorean.</translation>
 <translation id="1508575541972276599">Oraingo bertsioa Debian 9 (Stretch) da</translation>
+<translation id="1509163368529404530">Leheneratu taldea</translation>
 <translation id="1509281256533087115">Atzitu edozer <ph name="DEVICE_NAME_AND_VENDOR" /> USB bidez</translation>
 <translation id="1509960214886564027">Baliteke webgune askotako eginbideek ez funtzionatzea</translation>
 <translation id="1510238584712386396">Abiarazlea</translation>
@@ -585,6 +586,7 @@
 <translation id="1627408615528139100">Deskargatu da jada</translation>
 <translation id="1628948239858170093">Ireki aurretik aztertu egin nahi al duzu fitxategia?</translation>
 <translation id="1629314197035607094">Pasahitza iraungi egin da</translation>
+<translation id="1629451755632656601">Saskietan deskontu pertsonalizatuak bilatzeko baimena eman nahi diozu Google-ri?</translation>
 <translation id="1630300831289687074">Laster erabili ahalko duzu Chromebook-a.</translation>
 <translation id="163072119192489970">Datuak bidaltzen eta jasotzen amai dezakete</translation>
 <translation id="1630768113285622200">Berrabiarazi eta egin aurrera</translation>
@@ -1290,6 +1292,7 @@
 <translation id="236117173274098341">Optimizatu</translation>
 <translation id="2361340419970998028">Oharrak bidaltzen…</translation>
 <translation id="236141728043665931">Blokeatu beti mikrofonorako sarbidea</translation>
+<translation id="2363744066037724557">Leheneratu leihoa</translation>
 <translation id="2364498172489649528">Gaindituta</translation>
 <translation id="2365507699358342471">Webgune honek arbelean kopiatzen dituzun testuak eta irudiak ikus ditzake.</translation>
 <translation id="2367972762794486313">Erakutsi aplikazioak</translation>
@@ -2672,6 +2675,7 @@
 <translation id="3857807444929313943">Jaso hatza eta ukitu berriro</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" erabiltzaile-izena ez dago erabilgarri</translation>
 <translation id="3861977424605124250">Erakutsi abioan</translation>
+<translation id="386239283124269513">Leheneratu taldea</translation>
 <translation id="3862788408946266506">"kiosk_only" manifestu-atributua duen aplikazio bat instalatu behar da Chrome OS-en modu espezializatuan</translation>
 <translation id="3865414814144988605">Bereizmena</translation>
 <translation id="3866249974567520381">Azalpena</translation>
@@ -5647,6 +5651,7 @@
 <translation id="7225179976675429563">Sare mota falta da</translation>
 <translation id="7228479291753472782">Doitu webguneek eginbide jakin batzuk (esaterako, kokapena, mikrofonoa, kamera, etab.) erabil ditzaketen zehazten duten ezarpenak.</translation>
 <translation id="7228523857728654909">Saio-hasiera eta pantailaren blokeoa</translation>
+<translation id="7230222852462421043">Leheneratu leihoa</translation>
 <translation id="7230787553283372882">Pertsonalizatu testuaren tamaina</translation>
 <translation id="7232750842195536390">Ezin izan da aldatu izena</translation>
 <translation id="7234010996000898150">Linux-eko leheneratzea bertan behera uzten</translation>
@@ -6256,12 +6261,14 @@
 <translation id="7853747251428735">&amp;Tresna gehiago</translation>
 <translation id="7855678561139483478">Eraman fitxa leiho berri batera</translation>
 <translation id="7857093393627376423">Testuzko iradokizunak</translation>
+<translation id="7857675386615530425">Bilatu orriaren zati bat Google Lens-ekin</translation>
 <translation id="7857949311770343000">Espero zenuen fitxa berrien orria al da hau?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Zerbitzua: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Deskargak</translation>
 <translation id="7861846108263890455">Google-ko kontuaren hizkuntza</translation>
 <translation id="7864539943188674973">Desgaitu Bluetooth-a</translation>
+<translation id="7866230141401327032">Bilatu orriaren zati bat Google Lens-ekin</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - Parekatu da</translation>
 <translation id="7870730066603611552">Berrikusi sinkronizazio-aukerak konfigurazioaren ondoren</translation>
 <translation id="7870790288828963061">Ez da aurkitu aplikazio espezializatu berriagorik. Ez dago ezer eguneratzeko. Kendu USB memoria.</translation>
@@ -6836,6 +6843,7 @@
 <translation id="850875081535031620">Ez da aurkitu software kaltegarririk</translation>
 <translation id="8509177919508253835">Berrezarri segurtasun-giltzak eta sortu PIN kodeak</translation>
 <translation id="8509646642152301857">Ezin izan da deskargatu ortografia-zuzenketarako hiztegia.</translation>
+<translation id="8509967119010808787">Fitxak bilatzeko, sakatu hau</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Ez da aurkitu segurua ez den pasahitzik}=1{Segurua ez den {COUNT} pasahitz aurkitu da}other{Seguruak ez diren {COUNT} pasahitz aurkitu dira}}</translation>
 <translation id="8512476990829870887">Amaitu prozesua</translation>
 <translation id="851263357009351303">Eman beti irudiak erakusteko baimena <ph name="HOST" /> webguneari</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index 841e4ce6..9bf8a468 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -464,6 +464,7 @@
 <translation id="1507246803636407672">&amp;Supprimer</translation>
 <translation id="1508491105858779599">Placez votre doigt sur le lecteur d'empreinte digitale pour déverrouiller l'appareil.</translation>
 <translation id="1508575541972276599">Version actuelle : Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;Restaurer le groupe</translation>
 <translation id="1509281256533087115">Accéder à n'importe quel appareil <ph name="DEVICE_NAME_AND_VENDOR" /> via USB</translation>
 <translation id="1509960214886564027">Des fonctionnalités sur de nombreux sites risquent de ne pas fonctionner</translation>
 <translation id="1510238584712386396">Lanceur d'applications</translation>
@@ -586,6 +587,7 @@
 <translation id="1627408615528139100">Déjà téléchargé</translation>
 <translation id="1628948239858170093">Analyser le fichier avant de l'ouvrir ?</translation>
 <translation id="1629314197035607094">Le mot de passe est arrivé à expiration</translation>
+<translation id="1629451755632656601">Autoriser Google à vous proposer des remises personnalisées sur vos paniers ?</translation>
 <translation id="1630300831289687074">Vous allez pouvoir utiliser votre Chromebook sous peu.</translation>
 <translation id="163072119192489970">Autorisé à terminer l'envoi et la réception de données</translation>
 <translation id="1630768113285622200">Redémarrer et continuer</translation>
@@ -1291,6 +1293,7 @@
 <translation id="236117173274098341">Optimiser</translation>
 <translation id="2361340419970998028">Envoi des commentaires…</translation>
 <translation id="236141728043665931">Toujours bloquer l'accès au micro</translation>
+<translation id="2363744066037724557">&amp;Restaurer la fenêtre</translation>
 <translation id="2364498172489649528">Réussi</translation>
 <translation id="2365507699358342471">Ce site peut voir le texte et les images copiés dans le presse-papiers.</translation>
 <translation id="2367972762794486313">Afficher les applications</translation>
@@ -2674,6 +2677,7 @@
 <translation id="3857807444929313943">Levez le doigt, puis reposez-le</translation>
 <translation id="3861638017150647085">Nom d'utilisateur "<ph name="USERNAME" />" non disponible</translation>
 <translation id="3861977424605124250">Afficher au démarrage</translation>
+<translation id="386239283124269513">&amp;Restaurer le groupe</translation>
 <translation id="3862788408946266506">L'application dont le fichier manifeste comporte un attribut "kiosk_only" doit être installée en mode Kiosque pour Chrome OS</translation>
 <translation id="3865414814144988605">Résolution</translation>
 <translation id="3866249974567520381">Description</translation>
@@ -5650,6 +5654,7 @@
 <translation id="7225179976675429563">Type de réseau manquant.</translation>
 <translation id="7228479291753472782">Manipule des paramètres qui déterminent si les sites Web peuvent utiliser des fonctionnalités telles que la géolocalisation, le microphone, l'appareil photo, etc.</translation>
 <translation id="7228523857728654909">Verrouillage de l'écran et connexion</translation>
+<translation id="7230222852462421043">&amp;Restaurer la fenêtre</translation>
 <translation id="7230787553283372882">Personnaliser la taille du texte</translation>
 <translation id="7232750842195536390">Échec du changement de nom</translation>
 <translation id="7234010996000898150">Annulation de la restauration de Linux…</translation>
@@ -6259,12 +6264,14 @@
 <translation id="7853747251428735">Plus d'outi&amp;ls</translation>
 <translation id="7855678561139483478">Déplacer l'onglet vers une nouvelle fenêtre</translation>
 <translation id="7857093393627376423">Suggestions écrites</translation>
+<translation id="7857675386615530425">Rechercher sur une partie de la page avec Google Lens</translation>
 <translation id="7857949311770343000">Est-ce la page Nouvel onglet que vous attendiez ?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Service : <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Téléchargements</translation>
 <translation id="7861846108263890455">Langue du compte Google</translation>
 <translation id="7864539943188674973">Désactiver le Bluetooth</translation>
+<translation id="7866230141401327032">Rechercher sur une partie de la page avec Google Lens</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> associé</translation>
 <translation id="7870730066603611552">Vérifier les options de synchronisation après la configuration</translation>
 <translation id="7870790288828963061">Aucune nouvelle version d'une application kiosque n'a été trouvée. Aucune mise à jour n'est disponible. Veuillez débrancher la clé USB.</translation>
@@ -6841,6 +6848,7 @@
 <translation id="850875081535031620">Aucun logiciel malveillant détecté</translation>
 <translation id="8509177919508253835">Réinitialiser les clés de sécurité et créer des codes</translation>
 <translation id="8509646642152301857">Échec du téléchargement du dictionnaire du correcteur orthographique.</translation>
+<translation id="8509967119010808787">Cliquez ici pour rechercher dans vos onglets</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Aucun mot de passe peu sécurisé trouvé}=1{{COUNT} mot de passe peu sécurisé trouvé}one{{COUNT} mot de passe peu sécurisé trouvé}other{{COUNT} mots de passe peu sécurisés trouvés}}</translation>
 <translation id="8512476990829870887">Arrêter le processus</translation>
 <translation id="851263357009351303">Toujours autoriser <ph name="HOST" /> à afficher les images</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb
index 7e79937..33c5c50 100644
--- a/chrome/app/resources/generated_resources_gl.xtb
+++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;Descartar</translation>
 <translation id="1508491105858779599">Coloca o dedo no sensor de impresión dixital para desbloquear o dispositivo.</translation>
 <translation id="1508575541972276599">A versión actual é Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;Restaurar grupo</translation>
 <translation id="1509281256533087115">Acceda a calquera <ph name="DEVICE_NAME_AND_VENDOR" /> por USB</translation>
 <translation id="1509960214886564027">As funcións de moitos sitios poden deixar de funcionar</translation>
 <translation id="1510238584712386396">Menú de aplicacións</translation>
@@ -584,6 +585,7 @@
 <translation id="1627408615528139100">O ficheiro xa se descargou.</translation>
 <translation id="1628948239858170093">Queres analizar o ficheiro antes de abrilo?</translation>
 <translation id="1629314197035607094">Caducou o contrasinal</translation>
+<translation id="1629451755632656601">Queres permitir que Google busque descontos personalizados para os artigos dos teus carros?</translation>
 <translation id="1630300831289687074">Poderás usar o teu Chromebook en breve.</translation>
 <translation id="163072119192489970">Sitios que poden rematar de enviar ou recibir datos</translation>
 <translation id="1630768113285622200">Reiniciar e continuar</translation>
@@ -1289,6 +1291,7 @@
 <translation id="236117173274098341">Optimizar</translation>
 <translation id="2361340419970998028">Enviando comentario…</translation>
 <translation id="236141728043665931">Bloquear sempre o acceso do micrófono</translation>
+<translation id="2363744066037724557">&amp;Restaurar ventá</translation>
 <translation id="2364498172489649528">Aprobou</translation>
 <translation id="2365507699358342471">Este sitio pode ver o texto e as imaxes que se copian no portapapeis.</translation>
 <translation id="2367972762794486313">Mostrar aplicacións</translation>
@@ -2671,6 +2674,7 @@
 <translation id="3857807444929313943">Levanta o dedo e volve tocar o sensor</translation>
 <translation id="3861638017150647085">O nome de usuario "<ph name="USERNAME" />" non está dispoñible</translation>
 <translation id="3861977424605124250">Mostrar ao inicio</translation>
+<translation id="386239283124269513">&amp;Restaurar grupo</translation>
 <translation id="3862788408946266506">É necesario instalar a aplicación co atributo de manifesto "kiosk_only" no modo de quiosco de Chrome OS</translation>
 <translation id="3865414814144988605">Resolución</translation>
 <translation id="3866249974567520381">Descrición</translation>
@@ -5646,6 +5650,7 @@
 <translation id="7225179976675429563">Non se atopa o tipo de rede</translation>
 <translation id="7228479291753472782">Manipula a configuración que determina se os sitios web poden utilizar funcións como a xeolocalización, o micrófono, a cámara etc.</translation>
 <translation id="7228523857728654909">Bloqueo de pantalla e inicio de sesión</translation>
+<translation id="7230222852462421043">&amp;Restaurar ventá</translation>
 <translation id="7230787553283372882">Personaliza o tamaño do texto</translation>
 <translation id="7232750842195536390">Produciuse un erro ao cambiar o nome</translation>
 <translation id="7234010996000898150">Cancelando a restauración de Linux</translation>
@@ -6255,12 +6260,14 @@
 <translation id="7853747251428735">Máis ferrament&amp;as</translation>
 <translation id="7855678561139483478">Mover pestana a ventá nova</translation>
 <translation id="7857093393627376423">Suxestións de texto</translation>
+<translation id="7857675386615530425">Buscar parte da páxina con Google Lens</translation>
 <translation id="7857949311770343000">Esta é a páxina da pestana nova que esperabas?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Servizo: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Descargas</translation>
 <translation id="7861846108263890455">Idioma da Conta de Google</translation>
 <translation id="7864539943188674973">Desactivar o Bluetooth</translation>
+<translation id="7866230141401327032">Buscar parte da páxina con Google Lens</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" />: sincronizado</translation>
 <translation id="7870730066603611552">Revisar opcións de sincronización despois da configuración</translation>
 <translation id="7870790288828963061">Non se atopou ningunha aplicación de quiosco cunha versión máis recente. Non hai nada para actualizar. Retira a memoria USB.</translation>
@@ -6835,6 +6842,7 @@
 <translation id="850875081535031620">Non se atopou software daniño</translation>
 <translation id="8509177919508253835">Restablece as chaves de seguranza e crea os PIN</translation>
 <translation id="8509646642152301857">Non se puido descargar o dicionario da verificación ortográfica.</translation>
+<translation id="8509967119010808787">Para buscar unha pestana, fai clic aquí</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Non se atopou ningún contrasinal pouco seguro}=1{Atopouse {COUNT} contrasinal pouco seguro}other{Atopáronse {COUNT} contrasinais pouco seguros}}</translation>
 <translation id="8512476990829870887">Finalizar proceso</translation>
 <translation id="851263357009351303">Permitir sempre a <ph name="HOST" /> mostrar imaxes</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index b10cc16..965ffa6 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -464,6 +464,7 @@
 <translation id="1507246803636407672">&amp;છોડી દો</translation>
 <translation id="1508491105858779599">ઉપકરણને અનલૉક કરવા માટે તમારી આંગળીને ફિંગરપ્રિન્ટ સેન્સર પર મૂકો.</translation>
 <translation id="1508575541972276599">હાલનું વર્ઝન Debian 9 (Stretch) છે</translation>
+<translation id="1509163368529404530">&amp;ગ્રૂપ રિસ્ટોર કરો</translation>
 <translation id="1509281256533087115">USB મારફત કોઇપણ <ph name="DEVICE_NAME_AND_VENDOR" /> ઍક્સેસ કરો</translation>
 <translation id="1509960214886564027">ઘણી સાઇટ પરની સુવિધાઓને કદાચ બંધ કરવામાં આવી શકે</translation>
 <translation id="1510238584712386396">લૉન્ચર</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">પહેલેથી જ ડાઉનલોડ કરેલ છે</translation>
 <translation id="1628948239858170093">ખોલતા પહેલાં ફાઇલને સ્કૅન કરીએ?</translation>
 <translation id="1629314197035607094">પાસવર્ડની સમયસીમા સમાપ્ત થઈ</translation>
+<translation id="1629451755632656601">Googleને તમારા કાર્ટમાં ઉમેરેલી આઇટમ પર મનગમતા બનાવેલા ડિસ્કાઉન્ટ શોધવાની મંજૂરી આપીએ?</translation>
 <translation id="1630300831289687074">તમે ટૂંક સમયમાં તમારી Chromebookનો ઉપયોગ કરી શકશો.</translation>
 <translation id="163072119192489970">ડેટા મોકલવાનું અને પ્રાપ્ત કરવાનું સમાપ્ત કરવાની મંજૂરી છે</translation>
 <translation id="1630768113285622200">ફરી શરૂ કરો અને ચાલુ રાખો</translation>
@@ -1288,6 +1290,7 @@
 <translation id="236117173274098341">Optimize</translation>
 <translation id="2361340419970998028">પ્રતિસાદ મોકલી રહ્યું છીએ...</translation>
 <translation id="236141728043665931">માઇક્રોફોનની ઍક્સેસને હંમેશા અવરોધિત કરો</translation>
+<translation id="2363744066037724557">&amp;વિન્ડો રિસ્ટોર કરો</translation>
 <translation id="2364498172489649528">તપાસ પાર કરી</translation>
 <translation id="2365507699358342471">આ સાઇટ ક્લિપબોર્ડ પર કૉપિ કરેલ ટેક્સ્ટ અને છબીઓ જોઈ શકે છે.</translation>
 <translation id="2367972762794486313">ઍપ્લિકેશનો બતાવો</translation>
@@ -2671,6 +2674,7 @@
 <translation id="3857807444929313943">ઉપાડો, પછી ફરી સ્પર્શ કરો</translation>
 <translation id="3861638017150647085">વપરાશકર્તાનું "<ph name="USERNAME" />" નામ ઉપલબ્ધ નથી</translation>
 <translation id="3861977424605124250">સ્ટાર્ટઅપ કરતી વખતે બતાવો</translation>
+<translation id="386239283124269513">&amp;ગ્રૂપ રિસ્ટોર કરો</translation>
 <translation id="3862788408946266506">'Kiosk_only' મેનિફેસ્ટ વિશેષતાવાળી ઍપ Chrome OS કિઓસ્ક મોડમાં ઇન્સ્ટૉલ કરેલી હોવી જરૂરી છે</translation>
 <translation id="3865414814144988605">રિઝોલ્યુશન</translation>
 <translation id="3866249974567520381">વર્ણન</translation>
@@ -5648,6 +5652,7 @@
 <translation id="7225179976675429563">નેટવર્ક પ્રકાર ખૂટે છે</translation>
 <translation id="7228479291753472782">વેબસાઇટ્સ ભૌગોલિક સ્થાન, માઇક્રોફોન, કૅમેરા, વગેરે જેવી સુવિધાઓને ઉપયોગમાં લઈ શકે છે કે કેમ તેનો ઉલ્લેખ કરતી સેટિંગ્સમાં ફેરફારો કરો.</translation>
 <translation id="7228523857728654909">સ્ક્રીન લૉક અને સાઇન ઇન</translation>
+<translation id="7230222852462421043">&amp;વિન્ડો રિસ્ટોર કરો</translation>
 <translation id="7230787553283372882">તમારી ટેક્સ્ટના કદને કસ્ટમાઇઝ કરો</translation>
 <translation id="7232750842195536390">નામ બદલવામાં નિષ્ફળ થયાં</translation>
 <translation id="7234010996000898150">Linux પાછું મેળવવાનું રદ કરી રહ્યાં છીએ</translation>
@@ -6256,12 +6261,14 @@
 <translation id="7853747251428735">વધુ સા&amp;ધનો</translation>
 <translation id="7855678561139483478">ટૅબને નવી વિંડોમાં ખસેડો</translation>
 <translation id="7857093393627376423">ટેક્સ્ટ સૂચનો</translation>
+<translation id="7857675386615530425">Google Lens વડે પેજનો ભાગ શોધો</translation>
 <translation id="7857949311770343000">શું આ તમારી અપેક્ષા મુજબનું નવું ટેબ પૃષ્ઠ છે?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">સેવા: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ડાઉનલોડ્સ</translation>
 <translation id="7861846108263890455">Google એકાઉન્ટની ભાષા</translation>
 <translation id="7864539943188674973">Bluetooth અક્ષમ કરો</translation>
+<translation id="7866230141401327032">Google Lens વડે પેજનો ભાગ શોધો</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - જોડી કરેલ</translation>
 <translation id="7870730066603611552">સેટઅપ કર્યા પછી સિંક વિકલ્પો રિવ્યૂ કરો</translation>
 <translation id="7870790288828963061">નવા વર્ઝન સાથેની કોઈ કિઓસ્ક ઍપ્લિકેશન મળી નથી. અપડેટ કરવા માટે કંઈ નથી. કૃપા કરીને USB સ્ટીક દૂર કરો.</translation>
@@ -6833,6 +6840,7 @@
 <translation id="850875081535031620">કોઈ નુકસાનકારક સૉફ્ટવેર મળ્યું નથી</translation>
 <translation id="8509177919508253835">સુરક્ષા કોડ રીસેટ કરો અને પિન બનાવો</translation>
 <translation id="8509646642152301857">જોડણીની તપાસ ડાઉનલોડ કરવામાં નિષ્ફળ.</translation>
+<translation id="8509967119010808787">તમારી ટૅબ શોધવા માટે, અહીં ક્લિક કરો</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{કોઈ નબળો પાસવર્ડ મળ્યો નથી}=1{{COUNT} નબળો પાસવર્ડ મળ્યો}one{{COUNT} નબળો પાસવર્ડ મળ્યો}other{{COUNT} નબળા પાસવર્ડ મળ્યા}}</translation>
 <translation id="8512476990829870887">પ્રક્રિયાનો અંત કરો</translation>
 <translation id="851263357009351303"><ph name="HOST" /> ને હંમેશા છબી બતાવવાની મંજૂરી આપો</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index e19b609..a1d9be41 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -590,7 +590,7 @@
 <translation id="1627408615528139100">पहले से डाउनलोड की हुई है</translation>
 <translation id="1628948239858170093">क्या आप फ़ाइल को खोलने से पहले स्कैन करना चाहते हैं?</translation>
 <translation id="1629314197035607094">पासवर्ड की समय सीमा खत्म हो गई है</translation>
-<translation id="1629451755632656601">क्या Google को आपके कार्ट पर आपके हिसाब से छूट खोजने की अनुमति है?</translation>
+<translation id="1629451755632656601">Google को आपके कार्ट पर आपके हिसाब से छूट खोजने की अनुमति दें?</translation>
 <translation id="1630300831289687074">जल्द ही, आप अपना Chromebook इस्तेमाल कर पाएंगे.</translation>
 <translation id="163072119192489970">डेटा भेजने और पाने की अनुमति है</translation>
 <translation id="1630768113285622200">रीस्टार्ट करें और जारी रखें</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index e73d7c786..79b9d8fb 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -4381,6 +4381,7 @@
 <translation id="5794700615121138172">Linuxove dijeljene mape</translation>
 <translation id="5794786537412027208">Zatvori sve Chromeove aplikacije</translation>
 <translation id="5797070761912323120">Google može upotrebljavati vašu povijest za prilagodbu Pretraživanja, oglasa i drugih Googleovih usluga</translation>
+<translation id="5797521893972859201">Briše povijest, uključujući u okviru za pretraživanje</translation>
 <translation id="5798079537501238810">Web-lokacije mogu instalirati rukovatelje plaćanjem</translation>
 <translation id="579907812742603813">zaštićeni sadržaj</translation>
 <translation id="579915268381781820">Vaš je sigurnosni ključ uklonjen.</translation>
@@ -4464,6 +4465,7 @@
 <translation id="5900302528761731119">Fotografija Google profila</translation>
 <translation id="590036993063074298">Pojedinosti o kvaliteti zrcaljenja</translation>
 <translation id="5901069264981746702">Podaci o otisku prsta sigurno se pohranjuju i nikamo se ne šalju s uređaja <ph name="DEVICE_TYPE" />. <ph name="LINK_BEGIN" />Saznajte više<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Prijeđi na snimanje kartice</translation>
 <translation id="5901494423252125310">Otvorena su vratašca pisača</translation>
 <translation id="5901630391730855834">Žuta</translation>
 <translation id="5904614460720589786">Postavljanje aplikacije <ph name="APP_NAME" /> nije uspjelo zbog problema s konfiguracijom. Obratite se administratoru. Kôd pogreške: <ph name="ERROR_CODE" />.</translation>
@@ -4736,6 +4738,7 @@
 <translation id="6196854373336333322">Proširenje "<ph name="EXTENSION_NAME" />" preuzelo je kontrolu nad vašim postavkama proxyja, a to znači da može promijeniti, prekinuti ili prisluškivati sve što radite na mreži. Ako niste sigurni kako je došlo do te promjene, vjerojatno je ne želite.</translation>
 <translation id="6198102561359457428">Odjavite se, a zatim ponovo prijavite...</translation>
 <translation id="6198252989419008588">Promijeni PIN</translation>
+<translation id="6200047250927636406">Odbaci datoteku</translation>
 <translation id="6202304368170870640">PIN možete upotrebljavati za prijavu na uređaj ili otključavanje uređaja.</translation>
 <translation id="6206311232642889873">Kop&amp;iraj sliku</translation>
 <translation id="6207200176136643843">Vraćanje na zadanu razinu zumiranja</translation>
@@ -5304,6 +5307,7 @@
 <translation id="6831043979455480757">Prevedi</translation>
 <translation id="6833479554815567477">Kartica je uklonjena iz grupe <ph name="GROUP_NAME" /> – <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Prijeđite na pametan i siguran preglednik</translation>
+<translation id="6834652994408928492">Tamni način rada uključit će se automatski kad sunce zađe</translation>
 <translation id="683540480453879381">otvoriti <ph name="FILE_EXTENSIONS" /> datoteke</translation>
 <translation id="6835762382653651563">Povežite se s internetom da biste ažurirali svoj uređaj <ph name="DEVICE_TYPE" />.</translation>
 <translation id="6838034009068684089">Prikaži upit kad web-lokacija želi otvarati i postavljati prozore na zaslonima (preporučeno)</translation>
@@ -6016,6 +6020,7 @@
 <translation id="7622114377921274169">Punjenje.</translation>
 <translation id="7622768823216805500">Web-lokacije obično instaliraju rukovatelje plaćanjem radi značajki kupnje poput jednostavnije naplate</translation>
 <translation id="7622903810087708234">Pojedinosti o zaporci</translation>
+<translation id="7622966771025050155">Prijeđi na snimljenu karticu</translation>
 <translation id="7624337243375417909">Caps Lock isključen</translation>
 <translation id="7625568159987162309">Pregledajte dopuštenja i podatke pohranjene na web-lokacijama</translation>
 <translation id="7628201176665550262">Učestalost osvježavanja</translation>
@@ -6182,6 +6187,7 @@
 <translation id="7784067724422331729">Sigurnosne postavke na vašem računalu blokirale su ovu datoteku.</translation>
 <translation id="7784796923038949829">Podaci web-lokacije ne mogu se čitati niti promijeniti</translation>
 <translation id="778480864305029524">Za upotrebu Automatskog modemskog povezivanja uključite obavijesti za Google Play usluge.</translation>
+<translation id="7785471469930192436">Potražite upute za svoju tražilicu da biste saznali kako izbrisati svoju povijest pretraživanja, ako je primjenjivo</translation>
 <translation id="7786889348652477777">&amp;Ponovo učitaj aplikaciju</translation>
 <translation id="7787308148023287649">Prikaz na drugom zaslonu</translation>
 <translation id="7788298548579301890">Neki drugi program na vašem računalu dodao je aplikaciju koja može promijeniti Chromeov način rada.
@@ -6793,6 +6799,7 @@
 <translation id="8438566539970814960">Poboljšajte pretraživanje i pregledavanje</translation>
 <translation id="8439506636278576865">Ponudi prevođenje stranica na tom jeziku</translation>
 <translation id="8440630305826533614">Linux aplikacije</translation>
+<translation id="8446225304314102060">Prijeđi na karticu <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Saznajte više</translation>
 <translation id="8447409163267621480">Mora sadržavati Ctrl ili Alt</translation>
 <translation id="8448729345478502352">Povećajte ili smanjite stavke na zaslonu</translation>
@@ -7455,6 +7462,7 @@
 <translation id="9148058034647219655">Izlaz</translation>
 <translation id="9148126808321036104">Prijavite se ponovno</translation>
 <translation id="9148963623915467028">Ova web-lokacija može pristupiti vašoj lokaciji.</translation>
+<translation id="9149529198050266366">Tamni način rada isključit će se automatski kad sunce izađe</translation>
 <translation id="9149866541089851383">Uredi...</translation>
 <translation id="9150045010208374699">upotrijebiti vašu kameru</translation>
 <translation id="9150079578948279438">Uklanjanje profila nije uspjelo. Pokušajte ponovo ili se obratite mobilnom operateru za tehničku podršku.</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index aaa5e71..cf229c08 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -7292,7 +7292,7 @@
 <translation id="8977811652087512276">Password errata o file danneggiato</translation>
 <translation id="8978154919215542464">On: sincronizza tutto</translation>
 <translation id="897939795688207351">Su <ph name="ORIGIN" /></translation>
-<translation id="8980345560318123814">Rapporti di feedback</translation>
+<translation id="8980345560318123814">Report di feedback</translation>
 <translation id="8980951173413349704"><ph name="WINDOW_TITLE" /> - Bloccata</translation>
 <translation id="8981825781894055334">Carta in esaurimento</translation>
 <translation id="8983632908660087688"><ph name="ORIGIN" /> può modificare il file <ph name="FILENAME" /></translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb
index cbf2822..8ed68947 100644
--- a/chrome/app/resources/generated_resources_ky.xtb
+++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -205,7 +205,7 @@
 <translation id="121783623783282548">Сырсөздөр дал келген жок.</translation>
 <translation id="1218015446623563536">Linux'ту жок кылуу</translation>
 <translation id="1218839827383191197"><ph name="BEGIN_PARAGRAPH1" />Google'дун жайгашкан жерди аныктоо кызматы бул түзмөктүн жайгашкан жерин аныктоо үчүн Wi‑Fi, мобилдик тармактарды жана сенсорлорду колдонот.<ph name="END_PARAGRAPH1" />
-    <ph name="BEGIN_PARAGRAPH2" />Бул кызматты өчүрүү үчүн бул түзмөктөгү Жайгашкан жерди аныктоо функциясын өчүрүп салыңыз. Сиз ошондой эле Wi Fi, мобилдик тармактарды, жайгашкан жер сенсорлорун жайгаштыруу жөндөөлөрүнөн өчүрсөңүз болот.<ph name="END_PARAGRAPH2" /></translation>
+    <ph name="BEGIN_PARAGRAPH2" />Бул кызматты өчүрүү үчүн бул түзмөктөгү Жайгашкан жерди аныктоо функциясын өчүрүп салыңыз. Ошол эле жерден жайгашкан жерди аныктай турган Wi-Fi жана мобилдик тармактардын сигналдарынын, сенсорлордун колдонулушуна тыюу сала аласыз.<ph name="END_PARAGRAPH2" /></translation>
 <translation id="122082903575839559">Тастыктама кол тамга алгоритми</translation>
 <translation id="1221024147024329929">PKCS #1 MD2 RSA шифрлөөсү менен</translation>
 <translation id="1221825588892235038">Тандоо гана</translation>
@@ -1143,7 +1143,7 @@
 <translation id="2193365732679659387">Ишеним жөндөөлөрү</translation>
 <translation id="2195331105963583686">Андан кийин деле <ph name="DEVICE_TYPE" /> түзмөгүн колдоно бересиз, бирок андагы программа менен коопсуздук жаңыртуулары автоматтык түрдө алынбайт</translation>
 <translation id="2195729137168608510">Электрондук почтаны коргоо</translation>
-<translation id="2198625180564913276">Профиль кошулууда. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="2198625180564913276">Профиль кошулууда. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="2199298570273670671">Ката</translation>
 <translation id="2199719347983604670">Chrome Шайкештирүүнүн дайындары</translation>
 <translation id="2200094388063410062">Электрондук кат жөнөтүү</translation>
@@ -1849,7 +1849,7 @@
 <translation id="2942279350258725020">Android жазышуулары</translation>
 <translation id="2942560570858569904">Күтүп жатат…</translation>
 <translation id="2942581856830209953">Бул баракты ыңгайлаштыруу</translation>
-<translation id="2944060181911631861">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Google'га мүчүлүштүктөрдү аныктоо жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө жөнөтүп, Android'де иштөө тажрыйбаңызды жакшыртууга жардам бериңиз. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK1" />Кеңири маалымат<ph name="END_LINK1" /></translation>
+<translation id="2944060181911631861">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Google'га мүчүлүштүктөрдү аныктоо жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө жөнөтүп, Android'де иштөө тажрыйбаңызды жакшыртууга жардам бериңиз. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK1" />Кеңири маалымат<ph name="END_LINK1" /></translation>
 <translation id="2946119680249604491">Туташуу кошуу</translation>
 <translation id="2946640296642327832">Bluetooth иштетүү</translation>
 <translation id="2947605845283690091">Веб серепчи тез болушу керек. Бир аз убакыт бөлүп, <ph name="BEGIN_LINK" />кеңейтүүлөрдү текшериңиз<ph name="END_LINK" />.</translation>
@@ -2135,7 +2135,7 @@
 <translation id="3277691515294482687">Linux'ту жаңыртуудан мурда колдонмолор менен файлдардын камдык көчүрмөлөрү "Менин файлдарым" папкасына сакталсын.</translation>
 <translation id="3278001907972365362">Google аккаунттарыңызды карап чыгыңыз</translation>
 <translation id="3279092821516760512">Тандалган байланыштар жакын жерде болсо, сиз менен бөлүшө алышат. Маалымат сиздин макулдугуңуз менен гана өткөрүлө баштайт.</translation>
-<translation id="3279230909244266691">Бул бир нече мүнөткө созулушу мүмкүн. Виртуалдык машина иштетилип баштады.</translation>
+<translation id="3279230909244266691">Бир нече мүнөткө созулушу мүмкүн. Виртуалдык машина иштетилип баштады.</translation>
 <translation id="3280237271814976245">&amp;Төмөнкүдөй сактоо…</translation>
 <translation id="3280243678470289153">Chrome серепчисинде калуу</translation>
 <translation id="3281892622610078515">Карантиндеги файлдар жана программалар:</translation>
@@ -2320,7 +2320,7 @@
 <translation id="3474218480460386727">Жаңы сөздөр үчүн 99 же андан аз тамгаларды колдонуңуз</translation>
 <translation id="3475843873335999118">Кечиресиз, манжа изиңиз дагы эле тааныла элек. Сырсөзүңүздү киргизиңиз.</translation>
 <translation id="3475986680293081450">Баскычтар дал келген жок. <ph name="RESPONSE" /> үчүн каалаган баскычты басыңыз.</translation>
-<translation id="3476303763173086583">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Балаңыздын Android'ди колдонуу тажрыйбасын жакшыртууга көмөктөшүп, мүчүлүштүктөрдү издөө жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө Google'га жөнөтүүгө уруксат бериңиз. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Түзмөктүн ээси бул түзмөктөн мүчүлүштүктөрдү аныктоо жана колдонуу дайындарын Google'га жөнөтүү мүмкүнчүлүгүн иштетиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="3476303763173086583">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Балаңыздын Android'ди колдонуу тажрыйбасын жакшыртууга көмөктөшүп, мүчүлүштүктөрдү издөө жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө Google'га жөнөтүүгө уруксат бериңиз. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Түзмөктүн ээси бул түзмөктөн мүчүлүштүктөрдү аныктоо жана колдонуу дайындарын Google'га жөнөтүү мүмкүнчүлүгүн иштетиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="347670947055184738">Ой!  Тутум бул түзмөк үчүн саясатты ала албай калды.</translation>
 <translation id="347785443197175480"><ph name="HOST" /> камераңыз менен микрофонуңузду колдоно берсин</translation>
 <translation id="3479552764303398839">Азыр эмес</translation>
@@ -2396,7 +2396,7 @@
 <translation id="3559262020195162408">Түзмөккө саясат орнотулбай койду.</translation>
 <translation id="3559533181353831840">Болжол менен <ph name="TIME_LEFT" /> калды</translation>
 <translation id="3560034655160545939">&amp;Орфографиялык текшерүү</translation>
-<translation id="3562423906127931518">Бул бир нече мүнөткө созулушу мүмкүн. Linux контейнери жөндөлүүдө.</translation>
+<translation id="3562423906127931518">Бир нече мүнөткө созулушу мүмкүн. Linux контейнери жөндөлүүдө.</translation>
 <translation id="3562655211539199254">Chrome'догу акыркы өтмөктөрдү телефонуңуздан көрө аласыз</translation>
 <translation id="3563432852173030730">Киоск колдонмосу жүктөлүп алынган жок.</translation>
 <translation id="3564334271939054422">Колдонулуп жаткан Wi-Fi тармагы (<ph name="NETWORK_ID" />) кирүү барагына өтүүңүздү талап кылышы мүмкүн.</translation>
@@ -3002,7 +3002,7 @@
 <translation id="4209464433672152343">Басып чыгаруу үчүн документтер <ph name="BEGIN_LINK_HELP" />Google'га жөнөтүлөт<ph name="END_LINK_HELP" />. <ph name="BEGIN_LINK_DASHBOARD" />Google'дун виртуалдык принтеринин куралдар тактасынан<ph name="END_LINK_DASHBOARD" /> принтерлерди жана принтерлердин басып чыгаруу таржымалын көрүп, түзөтүп, башкарыңыз.</translation>
 <translation id="4210048056321123003">Виртуалдык машина жүктөлүп алынууда</translation>
 <translation id="421182450098841253">Кыстармалар тилкесин &amp;көрсөтүү</translation>
-<translation id="4211851069413100178">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Google'га мүчүлүштүктөрдү аныктоо жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө жөнөтүп, Android'де иштөө тажрыйбаңызды жакшыртууга жардам бериңиз. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Түзмөктүн ээси бул түзмөктөн мүчүлүштүктөрдү аныктоо жана колдонуу дайындарын Google'га жөнөтүү мүмкүнчүлүгүн иштетиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="4211851069413100178">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Google'га мүчүлүштүктөрдү аныктоо жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө жөнөтүп, Android'де иштөө тажрыйбаңызды жакшыртууга жардам бериңиз. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Түзмөктүн ээси бул түзмөктөн мүчүлүштүктөрдү аныктоо жана колдонуу дайындарын Google'га жөнөтүү мүмкүнчүлүгүн иштетиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="42126664696688958">Экспорттоо</translation>
 <translation id="42137655013211669">Бул булакка кирүүгө сервер тыюу салган.</translation>
 <translation id="4217571870635786043">Үн менен жазуу</translation>
@@ -3061,7 +3061,7 @@
 <translation id="4285498937028063278">Бошотуу</translation>
 <translation id="428565720843367874">Бул файл сканерленип жатканда, антивирус программасы күтүүсүздөн үзгүлтүккө учурады.</translation>
 <translation id="4287099557599763816">Экрандагыны окугуч</translation>
-<translation id="428715201724021596">Профилге туташууда. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="428715201724021596">Профилге туташууда. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="4287157641315808225">Ооба, ChromeVox иштетилсин</translation>
 <translation id="4287502603002637393">{MUTED_NOTIFICATIONS_COUNT,plural, =1{Көрсөтүү}other{Баарын көрсөтүү}}</translation>
 <translation id="4289372044984810120">Аккаунттарыңызды бул жерден башкарыңыз. <ph name="LINK_BEGIN" />Кеңири маалымат<ph name="LINK_END" /></translation>
@@ -3226,7 +3226,7 @@
 <translation id="4478664379124702289">Шил&amp;темени төмөнкүдөй сактоо…</translation>
 <translation id="4479424953165245642">Киоск колдонмолорун башкаруу</translation>
 <translation id="4479639480957787382">Ethernet</translation>
-<translation id="4479877282574735775">Виртуалдык машина конфигурацияланууда. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="4479877282574735775">Виртуалдык машина конфигурацияланууда. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="4480590691557335796">Chrome компьютериңизден зыянкеч программаны таап, аны алып салат</translation>
 <translation id="4481467543947557978">service worker cкрипти</translation>
 <translation id="4481530544597605423">Ажыратылган түзмөктөр</translation>
@@ -3289,7 +3289,7 @@
 <translation id="4538792345715658285">Ишкана саясаты тарабынан орнотулду.</translation>
 <translation id="4541123282641193691">Аккаунтуңуз ырасталбай калды. Кайталап көрүңүз же Chromebook'уңузду өчүрүп күйгүзүңүз.</translation>
 <translation id="4541662893742891060">Бул профилге туташуу мүмкүн эмес. Техникалык колдоо көрүү үчүн байланыш операторуна кайрылыңыз.</translation>
-<translation id="4541706525461326392">Профиль өчүрүлүүдө. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="4541706525461326392">Профиль өчүрүлүүдө. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="4541810033354695636">кошумчаланган чындык</translation>
 <translation id="4542520061254486227">Дайын-даректериңизди <ph name="WEBSITE_1" /> жана <ph name="WEBSITE_2" /> даректеринен окуңуз</translation>
 <translation id="454331522350252598">Жарнамачылар миңдеген колдонуучулардын окшош нерселерге кызыгарын биле алышат – мисалы, концертке келген адамдар — натыйжада, жарнамалар жеке бир киши үчүн эмес, жалпы эл үчүн тандалат.</translation>
@@ -3705,7 +3705,7 @@
 <translation id="5007392906805964215">Карап көрүү</translation>
 <translation id="50080882645628821">Профилди өчүрүү</translation>
 <translation id="5008936837313706385">Иш-аракеттин аталышы</translation>
-<translation id="5009463889040999939">Профилдин аталышы өзгөрүүдө. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="5009463889040999939">Профилдин аталышы өзгөрүүдө. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="5010043101506446253">Тастыктама борбору</translation>
 <translation id="5015344424288992913">Прокси чечилүүдө…</translation>
 <translation id="5017633213534173756">Сырсөздү эстеп калуу</translation>
@@ -4012,7 +4012,7 @@
 <translation id="5355099869024327351">Жардамчыга билдирмелерди көрсөтүүгө уруксат берүү</translation>
 <translation id="5355191726083956201">Өркүндөтүлгөн коргоо күйүк</translation>
 <translation id="5355926466126177564">"<ph name="EXTENSION_NAME" />" кеңейтүүсү, Omnibox'тон кандайдыр бир нерсе изделип жатканда, көрсөтүлө турган бетти өзгөрттү.</translation>
-<translation id="5356155057455921522">Администраторуңуз бул жаңыртууну аткаргандан кийин уюмуңуздун колдонмолору тезирээк ачылып калат. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="5356155057455921522">Администраторуңуз бул жаңыртууну аткаргандан кийин уюмуңуздун колдонмолору тезирээк ачылып калат. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="5359910752122114278">1 нерсе табылды</translation>
 <translation id="5359944933953785675"><ph name="NUM" /> өтмөк</translation>
 <translation id="5360150013186312835">Куралдар тилкесинен көрсөтүү</translation>
@@ -4054,7 +4054,7 @@
 <translation id="5407167491482639988">Түшүнүксүз</translation>
 <translation id="5408750356094797285">Чен-өлчөмүн өзгөртүү: <ph name="PERCENT" /></translation>
 <translation id="5409044712155737325">Google аккаунтуңуздан</translation>
-<translation id="5414198321558177633">Профилдин тизмеси жаңыртылууда. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="5414198321558177633">Профилдин тизмеси жаңыртылууда. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="5414566801737831689">Каралган вебсайттардын сүрөтчөлөрүн окуңуз</translation>
 <translation id="5417312524372586921">Серепчинин темалары</translation>
 <translation id="5419405654816502573">Voice match</translation>
@@ -4605,7 +4605,7 @@
 <translation id="6039651071822577588">Тармак касиетинин сөздүгү бузулуп калды</translation>
 <translation id="6040143037577758943">Жабуу</translation>
 <translation id="6041046205544295907"><ph name="BEGIN_PARAGRAPH1" />Google'дун жайгашкан жерди аныктоо кызматы бул түзмөктүн жайгашкан жерин аныктоо үчүн Wi‑Fi, мобилдик тармактарды жана сенсорлорду колдонот.<ph name="END_PARAGRAPH1" />
-    <ph name="BEGIN_PARAGRAPH2" />Бул кызматты өчүрүү үчүн түзмөгүңүздөгү Жайгашкан жерди аныктоо функциясын өчүрүп салыңыз. Сиз ошондой эле Wi Fi, мобилдик тармактарды, жайгашкан жер сенсорлорун жайгаштыруу жөндөөлөрүнөн өчүрсөңүз болот.<ph name="END_PARAGRAPH2" /></translation>
+    <ph name="BEGIN_PARAGRAPH2" />Бул кызматты өчүрүү үчүн түзмөгүңүздөгү Жайгашкан жерди аныктоо функциясын өчүрүп салыңыз. Ошол эле жерден жайгашкан жерди аныктай турган Wi-Fi жана мобилдик тармактардын сигналдарынын, сенсорлордун колдонулушуна тыюу сала аласыз.<ph name="END_PARAGRAPH2" /></translation>
 <translation id="6041155700700864984">Толук экран режиминен чыгуу</translation>
 <translation id="6042308850641462728">Дагы</translation>
 <translation id="6043317578411397101"><ph name="APP_NAME" /> колдонмосу Chrome өтмөгүн <ph name="TAB_NAME" /> менен бөлүшүп жатат.</translation>
@@ -4838,7 +4838,7 @@
 <translation id="6285120908535925801">{NUM_PRINTER,plural, =1{Тармагыңыздагы жаңы принтер}other{Тармагыңыздагы жаңы принтерлер}}</translation>
 <translation id="6285770818046456882">Жөнөтүүчү файлды өткөрүүнү жокко чыгарды</translation>
 <translation id="6290613030083731160">Жакын жерде маалымат бөлүшүлө турган түзмөк жок. <ph name="LINK_BEGIN" />Кеңири маалымат<ph name="LINK_END" /></translation>
-<translation id="6291086328725007688">Жандандыруу коду текшерилүүдө. Бул бир нече мүнөткө созулушу мүмкүн.</translation>
+<translation id="6291086328725007688">Жандандыруу коду текшерилүүдө. Бир нече мүнөткө созулушу мүмкүн.</translation>
 <translation id="6291741848715722067">Ырастоо коду:</translation>
 <translation id="6291949900244949761">Сайт USB түзмөктөрүн колдонгону жатканда уруксат суралсын (сунушталат)</translation>
 <translation id="6291953229176937411">&amp;Тапкычта көрсөтүү</translation>
@@ -5225,7 +5225,7 @@
 <translation id="6725206449694821596">Internet Printing Protocol (IPP)</translation>
 <translation id="6725970970008349185">Баракчада чагылдырыла турган талапкерлердин саны</translation>
 <translation id="672609503628871915">Эмне жаңылык бар</translation>
-<translation id="67269783048918309">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="67269783048918309">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="6727969043791803658">Туташып турат, батареянын деңгээли – <ph name="BATTERY_PERCENTAGE" />%</translation>
 <translation id="6732087373923685049">камера</translation>
 <translation id="6735304988756581115">Кукилерди жана башка сайт дайындарын көрсөтүү…</translation>
@@ -5866,7 +5866,7 @@
 <translation id="7441736921018636843">Бул жөндөөнү өзгөртүү үчүн <ph name="BEGIN_LINK" />шайкештирүү параметрлерин баштапкы абалга келтирип<ph name="END_LINK" />, купуя сөз айкашын алып салыңыз</translation>
 <translation id="7441830548568730290">Башка колдонуучулар</translation>
 <translation id="744341768939279100">Жаңы профиль түзүү</translation>
-<translation id="744366959743242014">Маалымат жүктөлүүдө. Бул бир нече секундга созулушу мүмкүн.</translation>
+<translation id="744366959743242014">Маалымат жүктөлүүдө. Бир нече секундга созулушу мүмкүн.</translation>
 <translation id="7443806024147773267">Google аккаунтуңузга кирериңиз менен сырсөздөрүңүзгө мүмкүнчүлүк аласыз</translation>
 <translation id="7444983668544353857"><ph name="NETWORKDEVICE" /> өчүрүү</translation>
 <translation id="7448430327655618736">Колдонмолорду автоматтык түрдө орнотуу</translation>
@@ -6924,7 +6924,7 @@
 <translation id="8591783563402255548">1 секунд</translation>
 <translation id="8592141010104017453">Билдирмелер такыр көрүнбөсүн</translation>
 <translation id="859246725979739260">Бул сайттын жайгашкан жериңизди көрүү мүмкүнчүлүгү бөгөттөлгөн</translation>
-<translation id="8593121833493516339">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Балаңыздын Android'ди колдонуу тажрыйбасын жакшыртууга көмөктөшүп, мүчүлүштүктөрдү издөө жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө Google'га жөнөтүүгө уруксат бериңиз. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK1" />Кеңири маалымат<ph name="END_LINK1" /></translation>
+<translation id="8593121833493516339">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Балаңыздын Android'ди колдонуу тажрыйбасын жакшыртууга көмөктөшүп, мүчүлүштүктөрдү издөө жана түзмөк менен колдонмолорду пайдалануу дайындарын автоматтык түрдө Google'га жөнөтүүгө уруксат бериңиз. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK1" />Кеңири маалымат<ph name="END_LINK1" /></translation>
 <translation id="8594908476761052472">Видео жаздыруу</translation>
 <translation id="8596540852772265699">Өзгөчөлөштүрүлгөн файлдар</translation>
 <translation id="8597845839771543242">Менчик форматы:</translation>
@@ -7049,7 +7049,7 @@
 <translation id="8719653885894320876"><ph name="PLUGIN_NAME" /> жүктөлүп алынбай калды</translation>
 <translation id="8720200012906404956">Мобилдик тармак изделүүдө. <ph name="BEGIN_LINK" />Кеңири маалымат<ph name="END_LINK" /></translation>
 <translation id="8720816553731218127">Орнотуу убактысынын аттрибуттары үчүн берилген ишке кошуу убакыты аяктады.</translation>
-<translation id="8722912030556880711">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="8722912030556880711">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="8724405322205516354">Бул сүрөтчө көрүнгөндө, манжаңыздын изи менен өздүгүңүздү же кандайдыр бир нерсени сатып алууну ырастайсыз.</translation>
 <translation id="8724409975248965964">Манжа изи кошулду</translation>
 <translation id="8724859055372736596">Куржунда &amp;көрсөтүү</translation>
@@ -7354,7 +7354,7 @@
 <translation id="9024127637873500333">Жаңы өтмөктө &amp;ачуу</translation>
 <translation id="9024158959543687197">Түзмөктү кошууда ката кетти. Файлды бөлүшүү URL'ин текшерип, кайталап көрүңүз.</translation>
 <translation id="9026731007018893674">жүктөп алуу</translation>
-<translation id="9026852570893462412">Бул бир нече мүнөткө созулушу мүмкүн. Виртуалдык машина жүктөлүп алынууда.</translation>
+<translation id="9026852570893462412">Бир нече мүнөткө созулушу мүмкүн. Виртуалдык машина жүктөлүп алынууда.</translation>
 <translation id="9027459031423301635">Шилтемени Жаңы &amp;өтмөктө ачуу</translation>
 <translation id="9030515284705930323">Ишканаңыздагы аккаунтуңуз аркылуу Google Play Store'ду колдонуу мүмкүнчүлүгү жок. Көбүрөөк маалымат алуу үчүн администраторуңузга кайрылыңыз.</translation>
 <translation id="9030754204056345429">Тезирээк</translation>
@@ -7496,16 +7496,16 @@
 <translation id="917350715406657904">Ата-энең <ph name="APP_NAME" /> колдонмосуна койгон чекке жеттиң. Аны эртең <ph name="TIME_LIMIT" /> колдоно аласың.</translation>
 <translation id="9174401638287877180">Колдонуу жана мүчүлүштүктөрдү аныктоо маалыматын жөнөтүү. Балаңыздын Android'ди колдонуу тажрыйбасын жакшыртууга көмөктөшүп, мүчүлүштүктөрдү издөө жана түзмөк менен колдонмолорду пайдалануу маалыматын автоматтык түрдө Google'га жөнөтүүгө уруксат бериңиз. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым маалыматтар тобу Google колдонмолоруна жана Android'дин иштеп чыгуучулары сыяктуу өнөктөштөрүнө да жардам берет. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул маалымат анын Google аккаунтуна сакталышы мүмкүн.</translation>
 <translation id="917510707618656279">Сайт Bluetooth түзмөктөрүн колдонгону жатканда уруксат сурайт</translation>
-<translation id="9176476835295860688">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="9176476835295860688">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Бул <ph name="BEGIN_LINK1" />жөндөөнү<ph name="END_LINK1" /> түзмөктүн ээси иштетет. Эгер кошумча Колдонмолор жана Интернеттеги аракеттериңиздин таржымалынын жөндөөлөрү күйгүзүлгөн болсо, бул нерселер Google аккаунтуңузга сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="9176611096776448349"><ph name="WINDOW_TITLE" /> – Bluetooth түзмөгү туташты</translation>
 <translation id="9179524979050048593">Кирүү экранындагы колдонуучу аты</translation>
-<translation id="9180281769944411366">Бул бир нече мүнөткө созулушу мүмкүн. Linux контейнери иштетилип баштады.</translation>
+<translation id="9180281769944411366">Бир нече мүнөткө созулушу мүмкүн. Linux контейнери иштетилип баштады.</translation>
 <translation id="9180380851667544951">Сайт экраныңызды бөлүшө алат</translation>
 <translation id="9182556968660520230">Сайттар корголгон мазмунду ойното албасын</translation>
 <translation id="918352324374649435">{COUNT,plural, =1{Колдонмо}other{# колдонмо}}</translation>
 <translation id="9185567408827209876">Ыкмаларды Хангул режиминде көрсөтүү</translation>
 <translation id="9186963452600581158">Баланын Google аккаунту менен кирүү</translation>
-<translation id="9188732951356337132">Колдонуу жана мүчүлүштүктөрдү аныктоо дайындарын жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
+<translation id="9188732951356337132">Түзмөктүн иштеши тууралуу маалыматтарды жөнөтүү. Учурда бул түзмөк мүчүлүштүктөрдү аныктоо маалыматын, түзмөктүн жана колдонмонун иштетилиши жөнүндө дайындарды Google'га автоматтык түрдө жөнөтүп жатат. Бул маалымат балаңыздын өздүгүн аныктоо үчүн колдонулбайт жана тутум менен колдонмонун кыйла туруктуу иштешин камсыз кылууга жана башка нерселерди жакшыртууга көмөктөшөт. Айрым дайын-даректердин Google'дун өнөктөштөрүнө, мисалы, Android'ди иштеп чыгуучуларга да кереги тийиши мүмкүн. Эгер кошумча Колдонмолор жана Интернеттеги аракеттер таржымалы балаңыз үчүн күйгүзүлгөн болсо, бул нерселер анын Google аккаунтуна сакталышы мүмкүн. <ph name="BEGIN_LINK2" />Кеңири маалымат<ph name="END_LINK2" /></translation>
 <translation id="9198090666959937775">Android телефонуңузду коопсуздук ачкычы катары колдонуңуз</translation>
 <translation id="9200339982498053969"><ph name="ORIGIN" /> <ph name="FOLDERNAME" /> папкасындагы файлдарды түзөтө алат</translation>
 <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> аркылуу издөө</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index 60b8c78a..c88f76e7 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -465,6 +465,7 @@
 <translation id="1507246803636407672">&amp;നിരസിക്കുക</translation>
 <translation id="1508491105858779599">ഉപകരണം അൺലോക്ക് ചെയ്യാൻ വിരലടയാള സെൻസറിൽ നിങ്ങളുടെ വിരൽ വയ്‌ക്കുക.</translation>
 <translation id="1508575541972276599">Debian 9 (Stretch) ആണ് നിലവിലെ പതിപ്പ്</translation>
+<translation id="1509163368529404530">&amp;ഗ്രൂപ്പ് പുനഃസ്ഥാപിക്കുക</translation>
 <translation id="1509281256533087115">USB വഴി ഏതൊരു <ph name="DEVICE_NAME_AND_VENDOR" /> ഉപകരണത്തെയും ആക്‌സസ് ചെയ്യുക</translation>
 <translation id="1509960214886564027">നിരവധി സൈറ്റുകളിലെ ഫീച്ചറുകൾക്ക് പ്രവർത്തനം നടത്താനായേക്കില്ല</translation>
 <translation id="1510238584712386396">ലോഞ്ചർ</translation>
@@ -584,6 +585,7 @@
 <translation id="1627408615528139100">നേരത്തേതന്നെ ഡൗൺലോഡുചെയ്‌തിട്ടുണ്ട്</translation>
 <translation id="1628948239858170093">തുറക്കുന്നതിന് മുമ്പ് ഫയൽ സ്കാൻ ചെയ്യണോ?</translation>
 <translation id="1629314197035607094">പാസ്‌വേഡ് കാലഹരണപ്പെട്ടു</translation>
+<translation id="1629451755632656601">നിങ്ങളുടെ കാർട്ടുകളിലുള്ള ഇനങ്ങൾക്കായി വ്യക്തിപരമാക്കിയ ഡിസ്‌കൗണ്ടുകൾ കണ്ടെത്താൻ Google-നെ അനുവദിക്കണോ?</translation>
 <translation id="1630300831289687074">നിങ്ങളുടെ Chromebook ഉടൻ തന്നെ ഉപയോഗിക്കാനാകും.</translation>
 <translation id="163072119192489970">ഡാറ്റ അയയ്ക്കുന്നതും സ്വീകരിക്കുന്നതും പൂർത്തിയാക്കാൻ അനുവദിച്ചിരിക്കുന്നു</translation>
 <translation id="1630768113285622200">റീസ്റ്റാർട്ട് ചെയ്‌ത ശേഷം തുടരുക</translation>
@@ -1289,6 +1291,7 @@
 <translation id="236117173274098341">Optimize</translation>
 <translation id="2361340419970998028">ഫീഡ്‌ബാക്ക് അയയ്‌ക്കുന്നു...</translation>
 <translation id="236141728043665931">എപ്പോഴും മൈക്രോഫോൺ ആക്‌സസ്സ് തടയുക</translation>
+<translation id="2363744066037724557">&amp;വിൻഡോ പുനഃസ്ഥാപിക്കുക</translation>
 <translation id="2364498172489649528">വിജയിച്ചു</translation>
 <translation id="2365507699358342471">ക്ലിപ്പ്‌ബോർഡിലേക്ക് പകർത്തിയിട്ടുള്ള ടെക്‌സ്‌റ്റും ചിത്രങ്ങളും ഈ സൈറ്റിന് കാണാനാകും.</translation>
 <translation id="2367972762794486313">അപ്ലിക്കേഷനുകൾ കാണിക്കുക</translation>
@@ -2671,6 +2674,7 @@
 <translation id="3857807444929313943">വിരൽ ഉയർത്തി, വീണ്ടും സ്‌പർശിക്കുക</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" എന്ന ഉപയോക്തൃനാമം ലഭ്യമല്ല</translation>
 <translation id="3861977424605124250">ആരംഭത്തിൽ കാണിക്കുക</translation>
+<translation id="386239283124269513">&amp;ഗ്രൂപ്പ് പുനഃസ്ഥാപിക്കുക</translation>
 <translation id="3862788408946266506">Chrome OS കിയോസ്‌ക് മോഡിൽ, 'kiosk_only' മാനിഫെസ്റ്റ് ആട്രിബ്യൂട്ട് ഉള്ള ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യണം</translation>
 <translation id="3865414814144988605">റെസല്യൂഷൻ</translation>
 <translation id="3866249974567520381">വിവരണം</translation>
@@ -5645,6 +5649,7 @@
 <translation id="7225179976675429563">നെറ്റ്‌വർക്ക് തരം നഷ്‌ടമായി</translation>
 <translation id="7228479291753472782">വെബ്‌സൈറ്റിന് ജിയോലൊക്കേഷൻ, മൈക്രോഫോൺ, ക്യാമറ എന്നിവ പോലുള്ള ഫീച്ചറുകൾ ഉപയോഗിക്കാൻ കഴിയുമോ എന്ന് വ്യക്തമാക്കുന്ന ക്രമീകരണം കൈകാര്യം ചെയ്യുക.</translation>
 <translation id="7228523857728654909">സ്‌ക്രീൻ ലോക്കും സൈൻ-ഇന്നും</translation>
+<translation id="7230222852462421043">&amp;വിൻഡോ പുനഃസ്ഥാപിക്കുക</translation>
 <translation id="7230787553283372882">നിങ്ങളുടെ ടെക്‌സ്‌‌റ്റ് വലുപ്പം ഇഷ്‌ടാനുസൃതമാക്കുക</translation>
 <translation id="7232750842195536390">പേരുമാറ്റൽ പരാജയപ്പെട്ടു</translation>
 <translation id="7234010996000898150">Linux പുനഃസ്ഥാപിക്കൽ റദ്ദാക്കുന്നു</translation>
@@ -6254,12 +6259,14 @@
 <translation id="7853747251428735">കൂടുതൽ ഉപകരണങ്ങൾ</translation>
 <translation id="7855678561139483478">ടാബ് പുതിയ വിൻഡോയിലേക്ക് നീക്കുക</translation>
 <translation id="7857093393627376423">ടെക്‌സ്‌റ്റ് നിർദ്ദേശങ്ങൾ</translation>
+<translation id="7857675386615530425">Google Lens ഉപയോഗിച്ച് പേജിന്റെ ഭാഗം തിരയുക</translation>
 <translation id="7857949311770343000">നിങ്ങൾ ഉദ്ദേശിച്ച പുതിയ ടാബ് പേജ് ഇതാണോ?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">സേവനം: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ഡൌണ്‍ലോഡുകള്‍</translation>
 <translation id="7861846108263890455">Google അക്കൗണ്ടിന്റെ ഭാഷ</translation>
 <translation id="7864539943188674973">Bluetooth അപ്രാപ്‌തമാക്കുക</translation>
+<translation id="7866230141401327032">Google Lens ഉപയോഗിച്ച് പേജിന്റെ ഭാഗം തിരയുക</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - ജോടിയാക്കി</translation>
 <translation id="7870730066603611552">സജ്ജീകരണത്തിന് ശേഷം സമന്വയ ഓപ്‌ഷനുകൾ അവലോകനം ചെയ്യുക</translation>
 <translation id="7870790288828963061">ഏറ്റവും പുതിയ പതിപ്പിലുള്ള കിയോസ്‌ക് ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല. USB സ്‌റ്റിക്ക് നീക്കംചെയ്യുക.</translation>
@@ -6835,6 +6842,7 @@
 <translation id="850875081535031620">ദോഷകരമായ സോഫ്‌റ്റ്‌വെയറൊന്നും കണ്ടെത്തിയില്ല</translation>
 <translation id="8509177919508253835">സുരക്ഷാ കീകൾ പുനഃക്രമീകരിച്ച്, പിന്നുകൾ സൃഷ്‌ടിക്കുക</translation>
 <translation id="8509646642152301857">സ്പെൽ ചെക്ക് നിഘണ്ടു ഡൗൺലോഡ് ചെയ്യുന്നത് പരാജയപ്പെട്ടു.</translation>
+<translation id="8509967119010808787">നിങ്ങളുടെ ടാബുകൾ തിരയാൻ ഇവിടെ ക്ലിക്ക് ചെയ്യുക</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{ദുർബലമായ പാസ്‌വേഡുകളൊന്നും കണ്ടെത്തിയില്ല}=1{ദുർബലമായ {COUNT} പാസ്‌വേഡ് കണ്ടെത്തി}other{ദുർബലമായ {COUNT} പാസ്‌വേഡുകൾ കണ്ടെത്തി}}</translation>
 <translation id="8512476990829870887">പ്രോസസ്സ് അവസാനിപ്പിക്കുക</translation>
 <translation id="851263357009351303">ചിത്രങ്ങൾ‌ കാണിക്കുന്നതിന്<ph name="HOST" /> നെ എല്ലായ്‌പ്പോഴും അനുവദിക്കുക</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb
index 32a50c6..359dc4d 100644
--- a/chrome/app/resources/generated_resources_mn.xtb
+++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -4391,6 +4391,7 @@
 <translation id="5794700615121138172">Linux-н хуваалцсан фолдерууд</translation>
 <translation id="5794786537412027208">Бүх Chrome Apps-аас гарах</translation>
 <translation id="5797070761912323120">Google таны түүхийг Хайлт, зар болон Google-н бусад үйлчилгээг хувийн болгох зорилгоор ашиглаж болзошгүй</translation>
+<translation id="5797521893972859201">Түүхийг арилгана. Үүнд хайх хэсгийн түүх багтана</translation>
 <translation id="5798079537501238810">Сайтууд төлбөр хариуцагч суулгах боломжтой</translation>
 <translation id="579907812742603813">хамгаалалттай контент</translation>
 <translation id="579915268381781820">Таны аюулгүй байдлын түлхүүрийг устгалаа.</translation>
@@ -4474,6 +4475,7 @@
 <translation id="5900302528761731119">Google-ийн танилцуулга зураг</translation>
 <translation id="590036993063074298">Тусгал үүсгэх чанарын дэлгэрэнгүй</translation>
 <translation id="5901069264981746702">Таны хурууны хээний өгөгдлийг аюулгүй хадгалдаг бөгөөд таны <ph name="DEVICE_TYPE" />-с хэзээ ч гардаггүй. <ph name="LINK_BEGIN" />Нэмэлт мэдээлэл авах<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Авч буй таб руу сэлгэх</translation>
 <translation id="5901494423252125310">Хэвлэгчийн таг нээлттэй байна</translation>
 <translation id="5901630391730855834">Шар</translation>
 <translation id="5904614460720589786">Тохируулгын асуудлын улмаас <ph name="APP_NAME" />-г тохируулж чадсангүй. Админтайгаа холбогдоно уу. Алдааны код: <ph name="ERROR_CODE" />.</translation>
@@ -4745,6 +4747,7 @@
 <translation id="6196854373336333322">"<ph name="EXTENSION_NAME" />" өргөтгөл нь таны прокси тохиргоог удирдаж байгаа бөгөөд энэ нь таны онлайнаар хийсэн зүйлийг өөрчилж, гэмтээж, хуулбарлах боломжтой гэсэн үг юм. Энэ өөрчлөлт яагаад гарсныг та мэдэхгүй байгаа бол энэ таны хүссэн зүйл биш байна.</translation>
 <translation id="6198102561359457428">Үйлдлийн системээс гараад, дахин нэвтрэнэ үү...</translation>
 <translation id="6198252989419008588">ПИН кодыг өөрчлөх</translation>
+<translation id="6200047250927636406">Файлыг болих</translation>
 <translation id="6202304368170870640">Ta төхөөрөмждөө нэвтрэх эсвэл түгжээг нь тайлахын тулд ПИН кодоо ашиглаж болно.</translation>
 <translation id="6206311232642889873">Зургийг хуулах</translation>
 <translation id="6207200176136643843">Томруулах өгөгдмөл түвшинд тохируулах</translation>
@@ -5313,6 +5316,7 @@
 <translation id="6831043979455480757">Хөрвүүлэх</translation>
 <translation id="6833479554815567477">Табыг <ph name="GROUP_NAME" /> бүлгээс хассан - <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Ухаалаг, аюулгүй хөтөч рүү сэлгэх</translation>
+<translation id="6834652994408928492">Нар жаргах үед бараан горим автоматаар асна</translation>
 <translation id="683540480453879381"><ph name="FILE_EXTENSIONS" /> файлыг нээх</translation>
 <translation id="6835762382653651563"><ph name="DEVICE_TYPE" />-ээ шинэчлэхийн тулд интернэтэд холбогдоно уу.</translation>
 <translation id="6838034009068684089">Сайтыг таны дэлгэц дээр цонх нээх болон байрлуулахыг хүсэх үед асуух (санал болгосон)</translation>
@@ -6025,6 +6029,7 @@
 <translation id="7622114377921274169">Цэнэглэж байна.</translation>
 <translation id="7622768823216805500">Сайтууд ихэвчлэн илүү хялбар тооцоо хийх зэрэг худалдан авалтын онцлогуудад зориулж төлбөр хариуцагчийг суулгадаг</translation>
 <translation id="7622903810087708234">Нууц үгийн дэлгэрэнгүй</translation>
+<translation id="7622966771025050155">Авсан таб руу сэлгэх</translation>
 <translation id="7624337243375417909">томоор бичих горим унтраалттай</translation>
 <translation id="7625568159987162309">Сайтын зөвшөөрөл болон хадгалсан өгөгдлийг харах</translation>
 <translation id="7628201176665550262">Сэргээх хурд</translation>
@@ -6191,6 +6196,7 @@
 <translation id="7784067724422331729">Таны компьютерийн хамгаалалтын тохиргоо энэ файлыг блоклосон байна.</translation>
 <translation id="7784796923038949829">Сайтын өгөгдлийг унших эсвэл өөрчлөх боломжгүй байна</translation>
 <translation id="778480864305029524">Шуурхай модем болголтыг ашиглахын тулд Google Play Үйлчилгээний мэдэгдлийг асаана уу.</translation>
+<translation id="7785471469930192436">Хэрэв боломжтой бол хайлтын түүхээ устгахын тулд хайлтын системийн зааварчилгаагаа харна уу</translation>
 <translation id="7786889348652477777">Аппыг дахин ачаалла</translation>
 <translation id="7787308148023287649">Өөр дэлгэцэд харуулах</translation>
 <translation id="7788298548579301890">Таны компьютерийн өөр нэг программ Chrome-н ажиллах зарчмыг өөрчилж болох апп нэмсэн байна.
@@ -6800,6 +6806,7 @@
 <translation id="8438566539970814960">Хайлт болон хөтлөх явцыг сайжруулаарай</translation>
 <translation id="8439506636278576865">Хуудаснуудыг энэ хэл рүү орчуулахыг санал болгох</translation>
 <translation id="8440630305826533614">Linux аппууд</translation>
+<translation id="8446225304314102060"><ph name="TAB_ORIGIN" /> таб руу сэлгэх</translation>
 <translation id="8446884382197647889">Дэлгэрэнгүй мэдээлэл</translation>
 <translation id="8447409163267621480">Ctrl эсвэл Alt-н аль нэгийг агуулдаг</translation>
 <translation id="8448729345478502352">Дэлгэц дээрх зүйлсийг жижигрүүлэх эсвэл томруулах</translation>
@@ -7459,6 +7466,7 @@
 <translation id="9148058034647219655">гарах</translation>
 <translation id="9148126808321036104">Дансандаа дахин нэвтрэх</translation>
 <translation id="9148963623915467028">Энэ сайт таны байршилд хандах боломжтой.</translation>
+<translation id="9149529198050266366">Нар мандах үед бараан горим автоматаар унтарна</translation>
 <translation id="9149866541089851383">Засварлах...</translation>
 <translation id="9150045010208374699">Та камераа ашиглана уу</translation>
 <translation id="9150079578948279438">Профайлыг хасах боломжгүй. Дахин оролдож эсвэл техникийн тусламж авахаар оператор компанитайгаа холбогдоно уу.</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index cb255f31..e1e0f151 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -462,6 +462,7 @@
 <translation id="1507246803636407672">&amp;नकार्नुहोस्</translation>
 <translation id="1508491105858779599">यन्त्रलाई अनलक गर्नका लागि फिंगरप्रिन्ट सेन्सरमा आफ्नो औंला राख्नुहोस्।</translation>
 <translation id="1508575541972276599">हालको संस्करण Debian 9 (Stretch) हो</translation>
+<translation id="1509163368529404530">&amp;समूह रिस्टोर गर्नुहोस्</translation>
 <translation id="1509281256533087115">USB मार्फत कुनै पनि <ph name="DEVICE_NAME_AND_VENDOR" /> पहुँच गर्नुहोस्</translation>
 <translation id="1509960214886564027">कयौँ साइटका सुविधाहरूले काम नगर्न सक्छन्</translation>
 <translation id="1510238584712386396">लन्चर</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">पहिल्यै डाउनलोड गरिएको छ</translation>
 <translation id="1628948239858170093">फाइल खोल्नुअघि उक्त फाइल स्क्यान गर्ने हो?</translation>
 <translation id="1629314197035607094">पासवर्डको म्याद सकिएको छ</translation>
+<translation id="1629451755632656601">Google लाई तपाईंका कार्टमा तपाईंले चाहेअनुसारको छुट खोज्ने अनुमति दिने हो?</translation>
 <translation id="1630300831289687074">तपाईं चाँडै नै आफ्नो Chromebook चलाउन सक्नु हुने छ।</translation>
 <translation id="163072119192489970">डेटा पठाउने तथा प्राप्त गर्ने कार्य पूरा गर्न अनुमति दिइएका साइटहरू</translation>
 <translation id="1630768113285622200">पुनः सुरु गरेर जारी राख्नुहोस्</translation>
@@ -1287,6 +1289,7 @@
 <translation id="236117173274098341">अप्टिमाइज गर्नुहोस्</translation>
 <translation id="2361340419970998028">प्रतिक्रिया पठाइँदै छ...</translation>
 <translation id="236141728043665931">माइक्रोफोन पहुँचलाई सँधै ब्लक गर्नुहोस्</translation>
+<translation id="2363744066037724557">&amp;विन्डो रिस्टोर गर्नुहोस्</translation>
 <translation id="2364498172489649528">सुरक्षा जाँचमा पास भयो</translation>
 <translation id="2365507699358342471">यो साइटले क्लिपबोर्डमा प्रतिलिपि गरिएका पाठ र फोटो हेर्न सक्छ।</translation>
 <translation id="2367972762794486313">एप्स देखाउनुहोस्</translation>
@@ -2671,6 +2674,7 @@
 <translation id="3857807444929313943">औँला उठाई फेरि छुनुहोस्</translation>
 <translation id="3861638017150647085">युजरनेम "<ph name="USERNAME" />" उपलब्ध छैन</translation>
 <translation id="3861977424605124250">ब्राउजर खोल्दा देखाइयोस्</translation>
+<translation id="386239283124269513">&amp;समूह रिस्टोर गर्नुहोस्</translation>
 <translation id="3862788408946266506">'Kiosk_only" नामक म्यानिफेस्ट विशेषता भएको एप अनिवार्य रूपमा ChromeOS को किओस्क मोडमा स्थापना गर्नु पर्छ</translation>
 <translation id="3865414814144988605">रिजोलुसन</translation>
 <translation id="3866249974567520381">विवरण</translation>
@@ -5644,6 +5648,7 @@
 <translation id="7225179976675429563">नेटवर्क प्रकार छैन</translation>
 <translation id="7228479291753472782">वेबसाइटहरूले भूस्थान, माइक्रोफोन, क्यामेरा जस्ता सुविधाहरूको प्रयोग गर्न सक्छन् वा सक्दैनन् भन्ने कुरा निर्दिष्ट गर्ने सेटिङहरूलाई फेरबदल गर्नुहोस्।</translation>
 <translation id="7228523857728654909">स्क्रिन लक तथा साइन इन</translation>
+<translation id="7230222852462421043">&amp;विन्डो रिस्टोर गर्नुहोस्</translation>
 <translation id="7230787553283372882">आफ्नो पाठको आकार आफू अनुकूल पार्नुहोस्</translation>
 <translation id="7232750842195536390">पुनः नामकरण गर्न सकिएन</translation>
 <translation id="7234010996000898150">Linux को पुनर्स्थापना रद्द गरिँदै</translation>
@@ -6253,12 +6258,14 @@
 <translation id="7853747251428735">थप उपकरणहरू</translation>
 <translation id="7855678561139483478">ट्याब नयाँ विन्डोमा सार्नुहोस्</translation>
 <translation id="7857093393627376423">पाठसम्बन्धी सुझावहरू</translation>
+<translation id="7857675386615530425">Google Lens प्रयोग गरी पेजको कुनै भाग खोज्नुहोस्</translation>
 <translation id="7857949311770343000">के यो नै तपाईंले अपेक्षा गर्नुभएको नयाँ ट्याब पृष्ठ हो?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">सेवा: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;डाउनलोडहरू</translation>
 <translation id="7861846108263890455">Google खाताको भाषा</translation>
 <translation id="7864539943188674973">ब्लुटुथ अक्षम बनाउनुहोस्</translation>
+<translation id="7866230141401327032">Google Lens प्रयोग गरी पेजको कुनै भाग खोज्नुहोस्</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - जोडा बनाइयो</translation>
 <translation id="7870730066603611552">सेटअप गरेपश्चात् सिंकसम्बन्धी विकल्पहरूको समीक्षा गर्नुहोस्</translation>
 <translation id="7870790288828963061">नयाँ संस्करणका कुनै पनि Kiosk एपहरू भेटिएन। अद्यावधिक गर्न कुनै चिज वाँकि छैन। कृपया USB स्टिक हटाउनुहोस्।</translation>
@@ -6834,6 +6841,7 @@
 <translation id="850875081535031620">कुनै पनि हानिकारक सफ्टवेयर भेटिएन</translation>
 <translation id="8509177919508253835">सुरक्षा साँचाहरू रिसेट गर्नुहोस् र PIN हरू सिर्जना गर्नुहोस्</translation>
 <translation id="8509646642152301857">हिज्जे जाँच शब्दकोशको डाउनलोड असफल भयो।</translation>
+<translation id="8509967119010808787">आफूले चाहेको ट्याब खोज्न यहाँ क्लिक गर्नुहोस्</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{कुनै कमजोर पासवर्ड भेट्टिएन}=1{{COUNT} वटा कमजोर पासवर्ड भेट्टियो}other{{COUNT} वटा कमजोर पासवर्ड भेट्टियो}}</translation>
 <translation id="8512476990829870887">प्रक्रिया समाप्त गर्नुहोस्</translation>
 <translation id="851263357009351303">फोटो देखाउन <ph name="HOST" /> लाई सधैँ अनुमति दिनुहोस्</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index a98cb35b..80302b2 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -4376,6 +4376,7 @@
 <translation id="5794700615121138172">Gedeelde mappen voor Linux</translation>
 <translation id="5794786537412027208">Alle Chrome-apps sluiten</translation>
 <translation id="5797070761912323120">Google kan je geschiedenis gebruiken om Google Zoeken, advertenties en andere Google-services te personaliseren</translation>
+<translation id="5797521893972859201">Hiermee wis je de geschiedenis, waaronder die in het zoekvak</translation>
 <translation id="5798079537501238810">Sites kunnen betalingshandlers installeren</translation>
 <translation id="579907812742603813">beschermde content</translation>
 <translation id="579915268381781820">Je beveiligingssleutel is verwijderd.</translation>
@@ -4459,6 +4460,7 @@
 <translation id="5900302528761731119">Google-profielfoto</translation>
 <translation id="590036993063074298">Informatie over kwaliteit van mirroring</translation>
 <translation id="5901069264981746702">Je vingerafdrukgegevens worden beveiligd opgeslagen en blijven uitsluitend op je <ph name="DEVICE_TYPE" /> staan. <ph name="LINK_BEGIN" />Meer informatie<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Overschakelen naar tabblad vastleggen</translation>
 <translation id="5901494423252125310">Printerklep is open</translation>
 <translation id="5901630391730855834">Geel</translation>
 <translation id="5904614460720589786">Kan <ph name="APP_NAME" /> niet instellen vanwege een configuratieprobleem. Neem contact op met je beheerder. Foutcode: <ph name="ERROR_CODE" />.</translation>
@@ -4731,6 +4733,7 @@
 <translation id="6196854373336333322">De extensie '<ph name="EXTENSION_NAME" />' heeft het beheer van je proxyinstellingen overgenomen. Dit betekent dat de extensie alles wat je online doet, kan wijzigen, beschadigen of bekijken. Als je niet zeker weet waarom deze wijziging heeft plaatsgevonden, is het waarschijnlijk een ongewenste wijziging.</translation>
 <translation id="6198102561359457428">Log uit en log daarna weer in...</translation>
 <translation id="6198252989419008588">Pincode wijzigen</translation>
+<translation id="6200047250927636406">Bestand weggooien</translation>
 <translation id="6202304368170870640">Je kunt je pincode gebruiken om in te loggen of je apparaat te ontgrendelen.</translation>
 <translation id="6206311232642889873">A&amp;fbeelding kopiëren</translation>
 <translation id="6207200176136643843">Standaardzoomniveau resetten</translation>
@@ -5299,6 +5302,7 @@
 <translation id="6831043979455480757">Vertalen</translation>
 <translation id="6833479554815567477">Tabblad verwijderd uit groep <ph name="GROUP_NAME" /> - <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Overschakelen naar een slimme, beveiligde browser</translation>
+<translation id="6834652994408928492">De donkere modus wordt automatisch aangezet bij zonsondergang</translation>
 <translation id="683540480453879381"><ph name="FILE_EXTENSIONS" />-bestanden openen</translation>
 <translation id="6835762382653651563">Maak verbinding met internet om je <ph name="DEVICE_TYPE" /> te updaten.</translation>
 <translation id="6838034009068684089">Vragen als een site vensters op je schermen wil openen en plaatsen (aanbevolen)</translation>
@@ -6011,6 +6015,7 @@
 <translation id="7622114377921274169">Opladen.</translation>
 <translation id="7622768823216805500">Sites installeren betalingshandlers meestal voor winkelfuncties zoals gemakkelijk betalen</translation>
 <translation id="7622903810087708234">Wachtwoordgegevens</translation>
+<translation id="7622966771025050155">Overschakelen naar vastgelegd tabblad</translation>
 <translation id="7624337243375417909">Caps Lock uit</translation>
 <translation id="7625568159987162309">Rechten en op sites opgeslagen gegevens bekijken</translation>
 <translation id="7628201176665550262">Vernieuwingssnelheid</translation>
@@ -6177,6 +6182,7 @@
 <translation id="7784067724422331729">Beveiligingsinstellingen op je computer hebben dit bestand geblokkeerd.</translation>
 <translation id="7784796923038949829">Kan sitegegevens niet lezen of wijzigen</translation>
 <translation id="778480864305029524">Zet meldingen voor Google Play-services aan om instant-tethering te gebruiken.</translation>
+<translation id="7785471469930192436">Bekijk de instructies van je zoekmachine voor het verwijderen van je zoekgeschiedenis (indien van toepassing)</translation>
 <translation id="7786889348652477777">App opnieuw &amp;laden</translation>
 <translation id="7787308148023287649">Weergeven op een ander scherm</translation>
 <translation id="7788298548579301890">Een ander programma op je computer heeft een app toegevoegd die de manier kan wijzigen waarop Chrome werkt.
@@ -6787,6 +6793,7 @@
 <translation id="8438566539970814960">Zoekopdrachten en browsefunctionaliteit verbeteren</translation>
 <translation id="8439506636278576865">Aanbieden pagina's te vertalen in deze taal</translation>
 <translation id="8440630305826533614">Linux-apps</translation>
+<translation id="8446225304314102060">Overschakelen naar tabblad <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Meer informatie</translation>
 <translation id="8447409163267621480">Neem Ctrl of Alt op</translation>
 <translation id="8448729345478502352">Items op het scherm kleiner of groter maken</translation>
@@ -7449,6 +7456,7 @@
 <translation id="9148058034647219655">Sluiten</translation>
 <translation id="9148126808321036104">Opnieuw inloggen</translation>
 <translation id="9148963623915467028">Deze site heeft toegang tot je locatie.</translation>
+<translation id="9149529198050266366">De donkere modus wordt automatisch uitgezet bij zonsopgang</translation>
 <translation id="9149866541089851383">Bewerken...</translation>
 <translation id="9150045010208374699">Je camera gebruiken</translation>
 <translation id="9150079578948279438">Kan profiel niet verwijderen. Probeer het opnieuw of neem contact op met je provider voor technische support.</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb
index 40869c02..2233742 100644
--- a/chrome/app/resources/generated_resources_or.xtb
+++ b/chrome/app/resources/generated_resources_or.xtb
@@ -465,6 +465,7 @@
 <translation id="1507246803636407672">&amp;ଖାରଜ କରନ୍ତୁ</translation>
 <translation id="1508491105858779599">ଡିଭାଇସ୍ ଅନ୍‌ଲକ୍ କରିବା ପାଇଁ ଟିପଚିହ୍ନ ସେନ୍ସର୍‌ରେ ଆପଣଙ୍କର ଆଙ୍ଗୁଠି ରଖନ୍ତୁ ।</translation>
 <translation id="1508575541972276599">ବର୍ତ୍ତମାନର ସଂସ୍କରଣ Debian 9 (Stretch) ଅଟେ</translation>
+<translation id="1509163368529404530">&amp;ଗୋଷ୍ଠୀ ରିଷ୍ଟୋର କରନ୍ତୁ</translation>
 <translation id="1509281256533087115">USB ମାଧ୍ୟମରେ ଯେକୌଣସି <ph name="DEVICE_NAME_AND_VENDOR" /> ଆକ୍ସେସ୍‌ କରନ୍ତୁ</translation>
 <translation id="1509960214886564027">କିଛି ସାଇଟରେ ଫିଚରଗୁଡ଼ିକ ଠିକ୍ ଭାବେ କାମ କରିନପାରେ</translation>
 <translation id="1510238584712386396">ଲଞ୍ଚର୍</translation>
@@ -584,6 +585,7 @@
 <translation id="1627408615528139100">ପୂର୍ବରୁ ଡାଉନ୍‌ଲୋଡ୍‌ କରାଯାଇଛି</translation>
 <translation id="1628948239858170093">ଖୋଲିବା ପୂର୍ବରୁ ଫାଇଲ୍ ସ୍କାନ୍ କରିବେ?</translation>
 <translation id="1629314197035607094">ପାସ୍‍ୱାର୍ଡର ମିଆଦ ସମାପ୍ତ ହୋଇଯାଇଛି</translation>
+<translation id="1629451755632656601">Googleକୁ ଆପଣଙ୍କ କାର୍ଟରେ ପର୍ସନାଲାଇଜ୍ କରାଯାଇଥିବା ରିହାତିଗୁଡ଼ିକୁ ଖୋଜିବାକୁ ଦେବେ କି?</translation>
 <translation id="1630300831289687074">ଆପଣ ଖୁବ୍ ଶୀଘ୍ର ଆପଣଙ୍କ Chromebookକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସମର୍ଥ ହେବେ।</translation>
 <translation id="163072119192489970">ଡାଟା ପଠାଇବା କିମ୍ବା ଗ୍ରହଣ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇଛି</translation>
 <translation id="1630768113285622200">ରିଷ୍ଟାର୍ଟ କରି ଜାରି ରଖନ୍ତୁ</translation>
@@ -1288,6 +1290,7 @@
 <translation id="236117173274098341">ଅପ୍ଟିମାଇଜ୍ କରନ୍ତୁ</translation>
 <translation id="2361340419970998028">ମତାମତ ପଠାଯାଉଛି...</translation>
 <translation id="236141728043665931">ସର୍ବଦା ମାଇକ୍ରୋଫୋନ୍ ଆକ୍ସେସ୍‌କୁ ବ୍ଲକ୍ କରନ୍ତୁ</translation>
+<translation id="2363744066037724557">&amp;ୱିଣ୍ଡୋ ରିଷ୍ଟୋର କରନ୍ତୁ</translation>
 <translation id="2364498172489649528">ପାସ୍ କରିଛି</translation>
 <translation id="2365507699358342471">ଏହି ସାଇଟ୍ କ୍ଲିପ୍‌ବୋର୍ଡରେ କପି କରାଯାଇଥିବା ଟେକ୍ସଟ୍ ଓ ଛବିକୁ ଦେଖିପାରିବ।</translation>
 <translation id="2367972762794486313">ଆପ୍ସ ଦେଖାନ୍ତୁ</translation>
@@ -2671,6 +2674,7 @@
 <translation id="3857807444929313943">ଆଙ୍ଗୁଠି ଉଠାଇ ପୁଣି ସ୍ପର୍ଶ କରନ୍ତୁ</translation>
 <translation id="3861638017150647085">ଉପଯୋଗକର୍ତ୍ତାନାମ "<ph name="USERNAME" />" ଉପଲବ୍ଧ ନାହିଁ</translation>
 <translation id="3861977424605124250">ଆରମ୍ଭ ପୃଷ୍ଠାରେ ଦେଖାନ୍ତୁ</translation>
+<translation id="386239283124269513">&amp;ଗୋଷ୍ଠୀ ରିଷ୍ଟୋର କରନ୍ତୁ</translation>
 <translation id="3862788408946266506">Chrome OS କିଓସ୍କୋ ମୋଡ୍‌ରେ 'kiosk_only' ମାନିଫେଷ୍ଟ ବିଶେଷତାକୁ ନିଶ୍ଚିତରୂପେ ଇନ୍‌ଷ୍ଟଲ୍ କରିବା ଉଚିତ୍‍</translation>
 <translation id="3865414814144988605">ରିଜୋଲ୍ୟୁଶନ୍</translation>
 <translation id="3866249974567520381">ବିବରଣୀ</translation>
@@ -5648,6 +5652,7 @@
 <translation id="7225179976675429563">ନେଟ୍‍ୱାର୍କ ପ୍ରକାର ଉପଲବ୍ଧ ନାହିଁ</translation>
 <translation id="7228479291753472782">ୱେବ୍‌ସାଇଟ୍‌ଗୁଡ଼ିକ ଭୌଗଳିକସ୍ଥାନ, ମାଇକ୍ରୋଫୋନ୍, କ୍ୟାମେରା ପ୍ରଭୃତି ବୈଶିଷ୍ଟ୍ୟ ଗୁଡ଼ିକର ବ୍ୟବହାର କରିପାରିବ କି ନାହିଁ ତାହା ନିର୍ଦ୍ଦିଷ୍ଟ କରୁଥିବା ସେଟିଂସ୍‌କୁ ଏପଟ ସେପଟ କରେ।</translation>
 <translation id="7228523857728654909">ସ୍କ୍ରିନ୍ ଲକ୍ ଓ ସାଇନ୍ ଇନ୍</translation>
+<translation id="7230222852462421043">&amp;ୱିଣ୍ଡୋ ରିଷ୍ଟୋର କରନ୍ତୁ</translation>
 <translation id="7230787553283372882">ଆପଣଙ୍କର ଟେକ୍ସଟ୍ ଆକାରକୁ କଷ୍ଟମାଇଜ୍ କରନ୍ତୁ</translation>
 <translation id="7232750842195536390">ରିନେମ୍ ପ୍ରକ୍ରିୟା ବିଫଳ ହୋଇଛି</translation>
 <translation id="7234010996000898150">Linuxର ରିଷ୍ଟୋର୍ ବାତିଲ୍ ହେଉଛି</translation>
@@ -6257,12 +6262,14 @@
 <translation id="7853747251428735">ଅଧିକ ଟୁ&amp;ଲ୍‌ସ୍</translation>
 <translation id="7855678561139483478">ଟାବ୍‍କୁ ନୂଆ ୱିଣ୍ଡୋକୁ ମୁଭ୍ କରନ୍ତୁ</translation>
 <translation id="7857093393627376423">ଟେକ୍ସଟ୍ ପରାମର୍ଶ</translation>
+<translation id="7857675386615530425">Google Lens ମାଧ୍ୟମରେ ପୃଷ୍ଠାର କିଛି ଅଂଶ ସନ୍ଧାନ କରନ୍ତୁ</translation>
 <translation id="7857949311770343000">ଏହା କ'ଣ ଆପଣ ପ୍ରତ୍ୟାଶିତ କରୁଥିବା ନୂଆ ଟାବ୍ ପୃଷ୍ଠା ଅଟେ?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">ସେବା: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ଡାଉନଲୋଡସମୂହ</translation>
 <translation id="7861846108263890455">Google ଆକାଉଣ୍ଟର ଭାଷା</translation>
 <translation id="7864539943188674973">ବ୍ଲୁଟୁଥ୍ ଅକ୍ଷମ କରନ୍ତୁ</translation>
+<translation id="7866230141401327032">Google Lens ମାଧ୍ୟମରେ ପୃଷ୍ଠାର କିଛି ଅଂଶ ସନ୍ଧାନ କରନ୍ତୁ</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - ପେୟାର୍ ହୋଇଛି</translation>
 <translation id="7870730066603611552">ସେଟ୍‍ଅପ୍ ପରେ ସିଙ୍କ ବିକଳ୍ପର ସମୀକ୍ଷା କରନ୍ତୁ</translation>
 <translation id="7870790288828963061">ନୂତନ ସଂସ୍କରଣର କୌଣସି କିଓସ୍କୋ ଆପ୍ସ ମିଳିଲା ନାହିଁ। ଅପ୍‌ଡେଟ୍‍ କରିବାକୁ କିଛି ନାହିଁ। ଦୟାକରି USB ଷ୍ଟିକ୍‍ କାଢ଼ନ୍ତୁ।</translation>
@@ -6836,6 +6843,7 @@
 <translation id="850875081535031620">କୌଣସି ହାନିକାରକ ସଫ୍ଟୱେର୍ ମିଳିଲା ନାହିଁ</translation>
 <translation id="8509177919508253835">ସୁରକ୍ଷା କୀଗୁଡ଼ିକ ରିସେଟ୍ କରନ୍ତୁ ଏବଂ ପିନ୍‌ଗୁଡ଼ିକ ତିଆରି କରନ୍ତୁ</translation>
 <translation id="8509646642152301857">ବନାନ ଯାଞ୍ଚ ଅଭିଧାନ ଡାଉନ୍‌ଲୋଡ୍ ବିଫଳ ହୋଇଛି।</translation>
+<translation id="8509967119010808787">ଆପଣଙ୍କ ଟାବଗୁଡ଼ିକୁ ସନ୍ଧାନ କରିବାକୁ, ଏଠାରେ କ୍ଲିକ୍ କରନ୍ତୁ</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{କୌଣସି ଦୁର୍ବଳ ପାସୱାର୍ଡ ମିଳିଲା ନାହିଁ}=1{{COUNT}ଟି ଦୁର୍ବଳ ପାସୱାର୍ଡ ମିଳିଲା}other{{COUNT}ଟି ଦୁର୍ବଳ ପାସୱାର୍ଡ ମିଳିଲା}}</translation>
 <translation id="8512476990829870887">ପ୍ରକ୍ରିୟା ଶେଷ କରନ୍ତୁ</translation>
 <translation id="851263357009351303">ଛବି ଦେଖାଇବା ପାଇଁ ସର୍ବଦା <ph name="HOST" />କୁ ଅନୁମତି ଦିଅନ୍ତୁ</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb
index 673b2c2..4ab7f76 100644
--- a/chrome/app/resources/generated_resources_pa.xtb
+++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -467,6 +467,7 @@
 <translation id="1507246803636407672">&amp;ਬਰਖ਼ਾਸਤ ਕਰੋ</translation>
 <translation id="1508491105858779599">ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਆਪਣੀ ਉਂਗਲ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ 'ਤੇ ਰੱਖੋ।</translation>
 <translation id="1508575541972276599">ਮੌਜੂਦਾ ਵਰਜਨ Debian 9 (Stretch) ਹੈ</translation>
+<translation id="1509163368529404530">&amp;ਗਰੁੱਪ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ</translation>
 <translation id="1509281256533087115">USB ਰਾਹੀਂ ਕਿਸੇ ਵੀ <ph name="DEVICE_NAME_AND_VENDOR" /> ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ</translation>
 <translation id="1509960214886564027">ਸ਼ਾਇਦ ਕਈ ਸਾਈਟਾਂ 'ਤੇ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਠੀਕ ਤਰੀਕੇ ਨਾਲ ਕੰਮ ਨਾ ਕਰਨ</translation>
 <translation id="1510238584712386396">ਲੌਂਚਰ</translation>
@@ -589,6 +590,7 @@
 <translation id="1627408615528139100">ਪਹਿਲਾਂ ਤੋਂ ਡਾਊਨਲੋਡ ਕੀਤੀ ਗਈ</translation>
 <translation id="1628948239858170093">ਕੀ ਖੋਲ੍ਹਣ ਤੋਂ ਪਹਿਲਾਂ ਫ਼ਾਈਲ ਨੂੰ ਸਕੈਨ ਕਰਨਾ ਹੈ?</translation>
 <translation id="1629314197035607094">ਪਾਸਵਰਡ ਦੀ ਮਿਆਦ ਮੁੱਕ ਗਈ</translation>
+<translation id="1629451755632656601">ਕੀ Google ਨੂੰ ਤੁਹਾਡੇ ਕਾਰਟਾਂ 'ਤੇ ਵਿਅਕਤੀਗਤ ਬਣਾਈਆਂ ਛੋਟਾਂ ਨੂੰ ਲੱਭਣ ਦੇਣਾ ਹੈ?</translation>
 <translation id="1630300831289687074">ਤੁਸੀਂ ਜਲਦ ਹੀ ਆਪਣੀ Chromebook ਵਰਤ ਸਕੋਗੇ।</translation>
 <translation id="163072119192489970">ਡਾਟਾ ਭੇਜਣ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਨੂੰ ਪੂਰਾ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਹੈ</translation>
 <translation id="1630768113285622200">ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ ਅਤੇ ਜਾਰੀ ਰੱਖੋ</translation>
@@ -1306,6 +1308,7 @@
 <translation id="236117173274098341">ਸੁਯੋਗ ਬਣਾਓ</translation>
 <translation id="2361340419970998028">ਵਿਚਾਰ ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ...</translation>
 <translation id="236141728043665931">ਹਮੇਸ਼ਾਂ ਮਾਈਕ੍ਰੋਫੋਨ ਪਹੁੰਚ ਨੂੰ ਬਲੌਕ ਕਰੋ</translation>
+<translation id="2363744066037724557">&amp;ਵਿੰਡੋ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ</translation>
 <translation id="2364498172489649528">ਪਾਸ ਕੀਤਾ</translation>
 <translation id="2365507699358342471">ਇਹ ਸਾਈਟ ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕੀਤੀ ਲਿਖਤ ਅਤੇ ਚਿੱਤਰਾਂ ਨੂੰ ਦੇਖ ਸਕਦੀ ਹੈ।</translation>
 <translation id="2367972762794486313">ਐਪਸ ਦਿਖਾਓ</translation>
@@ -2688,6 +2691,7 @@
 <translation id="3857807444929313943">ਚੁੱਕੋ, ਫਿਰ ਦੁਬਾਰਾ ਸਪਰਸ਼ ਕਰੋ</translation>
 <translation id="3861638017150647085">ਵਰਤੋਂਕਾਰ ਨਾਮ "<ph name="USERNAME" />" ਉਪਲਬਧ ਨਹੀਂ ਹੈ</translation>
 <translation id="3861977424605124250">ਸ਼ੁਰੂਆਤ ਵੇਲੇ ਦਿਖਾਓ</translation>
+<translation id="386239283124269513">&amp;ਗਰੁੱਪ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ</translation>
 <translation id="3862788408946266506">'kiosk_only' ਮੈਨੀਫ਼ੈਸਟ ਵਿਸ਼ੇਸ਼ਤਾ ਵਾਲੀ ਐਪ Chrome OS ਕਿਓਸਕ ਮੋਡ ਵਿੱਚ ਲਾਜ਼ਮੀ ਤੌਰ 'ਤੇ ਸਥਾਪਤ ਕੀਤੀ ਜਾਣੀ ਚਾਹੀਦੀ ਹੈ</translation>
 <translation id="3865414814144988605">ਰੈਜ਼ੋਲਿਊਸ਼ਨ</translation>
 <translation id="3866249974567520381">ਵਰਣਨ</translation>
@@ -5664,6 +5668,7 @@
 <translation id="7225179976675429563">ਨੈੱਟਵਰਕ ਪ੍ਰਕਾਰ ਲੁਪਤ</translation>
 <translation id="7228479291753472782">ਉਹਨਾਂ ਸੈਟਿੰਗਾਂ ਨੂੰ ਸੋਧੋ ਜੋ ਇਹ ਨਿਰਧਾਰਿਤ ਕਰਦੀਆਂ ਹਨ ਕਿ ਕੀ ਵੈੱਬਸਾਈਟਾਂ ਭੂਗੋਲਿਕ ਟਿਕਾਣੇ, ਮਾਈਕ੍ਰੋਫ਼ੋਨ, ਕੈਮਰਾ, ਆਦਿ ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀਆਂ ਹਨ ਜਾਂ ਨਹੀਂ।</translation>
 <translation id="7228523857728654909">ਸਕ੍ਰੀਨ ਲਾਕ ਅਤੇ ਸਾਈਨ-ਇਨ</translation>
+<translation id="7230222852462421043">&amp;ਵਿੰਡੋ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰੋ</translation>
 <translation id="7230787553283372882">ਆਪਣੀ ਲਿਖਤ ਦੇ ਆਕਾਰ ਨੂੰ ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ</translation>
 <translation id="7232750842195536390">ਨਾਮ ਬਦਲਣਾ ਅਸਫਲ ਰਿਹਾ</translation>
 <translation id="7234010996000898150">Linux ਮੁੜ-ਬਹਾਲੀ ਰੱਦ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ</translation>
@@ -6272,12 +6277,14 @@
 <translation id="7853747251428735">ਹੋਰ ਟੂ&amp;ਲਸ</translation>
 <translation id="7855678561139483478">ਟੈਬ ਨੂੰ ਨਵੀਂ ਵਿੰਡੋ ਵਿੱਚ ਲਿਜਾਓ</translation>
 <translation id="7857093393627376423">ਲਿਖਤ ਸੁਝਾਅ</translation>
+<translation id="7857675386615530425">Google Lens ਨਾਲ ਪੰਨੇ ਦਾ ਹਿੱਸਾ ਖੋਜਣਾ</translation>
 <translation id="7857949311770343000">ਕੀ ਇਹ ਉਹੀ ਨਵੀਂ ਟੈਬ ਪੰਨਾ ਹੈ ਜਿਸਦੀ ਤੁਸੀਂ ਆਸ ਕਰ ਰਹੇ ਸੀ?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">ਸੇਵਾ: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ਡਾਊਨਲੋਡਸ</translation>
 <translation id="7861846108263890455">Google ਖਾਤੇ ਦੀ ਭਾਸ਼ਾ</translation>
 <translation id="7864539943188674973">Bluetooth ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ</translation>
+<translation id="7866230141401327032">Google Lens ਨਾਲ ਪੰਨੇ ਦਾ ਹਿੱਸਾ ਖੋਜਣਾ</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - ਜੋੜਾਬੱਧ ਕੀਤੀ ਗਈ</translation>
 <translation id="7870730066603611552">ਸੈੱਟਅੱਪ ਦੇ ਬਾਅਦ ਸਮਕਾਲੀਕਰਨ ਵਿਕਲਪਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ</translation>
 <translation id="7870790288828963061">ਨਵੇਂ ਵਰਜਨ ਵਾਲੀਆਂ ਕੋਈ ਕਿਓਸਕ ਐਪਾਂ ਨਹੀਂ ਮਿਲਿਆਂ। ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ। ਕਿਰਪਾ ਕਰਕੇ USB ਸਟਿੱਕ ਹਟਾਓ।</translation>
@@ -6853,6 +6860,7 @@
 <translation id="850875081535031620">ਕੋਈ ਹਾਨੀਕਾਰਕ ਸਾਫਟਵੇਅਰ ਨਹੀਂ ਮਿਲਿਆ</translation>
 <translation id="8509177919508253835">ਸੁਰੱਖਿਆ ਕੁੰਜੀਆਂ ਨੂੰ ਰੀਸੈੱਟ ਕਰਕੇ ਪਿੰਨ ਬਣਾਓ</translation>
 <translation id="8509646642152301857">ਸ਼ਬਦ-ਜੋੜ ਜਾਂਚ ਸ਼ਬਦਕੋਸ਼ ਡਾਊਨਲੋਡ ਅਸਫਲ ਰਿਹਾ।</translation>
+<translation id="8509967119010808787">ਆਪਣੇ ਟੈਬਾਂ ਦੀ ਖੋਜ ਕਰਨ ਲਈ, ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{ਕੋਈ ਕਮਜ਼ੋਰ ਪਾਸਵਰਡ ਨਹੀਂ ਮਿਲਿਆ}=1{{COUNT} ਕਮਜ਼ੋਰ ਪਾਸਵਰਡ ਮਿਲਿਆ}other{{COUNT} ਕਮਜ਼ੋਰ ਪਾਸਵਰਡ ਮਿਲੇ}}</translation>
 <translation id="8512476990829870887">ਪ੍ਰਕਿਰਿਆ ਖ਼ਤਮ ਕਰੋ</translation>
 <translation id="851263357009351303"><ph name="HOST" /> ਨੂੰ ਹਮੇਸ਼ਾਂ ਚਿੱਤਰ ਦਿਖਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb
index ed72a52..fab72d4 100644
--- a/chrome/app/resources/generated_resources_si.xtb
+++ b/chrome/app/resources/generated_resources_si.xtb
@@ -4384,6 +4384,7 @@
 <translation id="5794700615121138172">ලිනක්ස් බෙදාගත් ෆෝල්ඩර</translation>
 <translation id="5794786537412027208">සියලු Chrome යෙදුම්වලින් ඉවත් වන්න</translation>
 <translation id="5797070761912323120">සෙවීම, දැන්වීම් සහ අනෙකුත් Google සේවා පුද්ගලායන කිරීමට Google ඔබේ ඉතිහාසය භාවිත කළ හැක</translation>
+<translation id="5797521893972859201">සෙවීම් කොටුවේ ඇතුළුව, ඉතිහාසය හිස් කරයි</translation>
 <translation id="5798079537501238810">අඩවිවලට ගෙවීම් හසුරු ස්ථාපනය කළ හැකිය</translation>
 <translation id="579907812742603813">ආරක්ෂිත අන්තර්ගතය</translation>
 <translation id="579915268381781820">ඔබේ ආරක්‍ෂක යතුර ඉවත් කරනු ලැබීය.</translation>
@@ -4467,6 +4468,7 @@
 <translation id="5900302528761731119">Google පැතිකට ඡායාරූපය</translation>
 <translation id="590036993063074298">දර්පණය කිරීමේ ගුණත්ව විස්තර</translation>
 <translation id="5901069264981746702">ඔබගේ ඇඟිලි සලකුණු දත්ත ආරක්ෂිතව සුරකින අතර කිසි විට ඔබගේ <ph name="DEVICE_TYPE" /> හැර නොයයි. <ph name="LINK_BEGIN" />තව දැන ගන්න<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">ග්‍රහණය කිරීමේ ටැබයට මාරු වන්න</translation>
 <translation id="5901494423252125310">මුද්‍රක දොර විවෘතයි</translation>
 <translation id="5901630391730855834">කහ</translation>
 <translation id="5904614460720589786">වින්‍යාස ගැටලුවක් හේතුවෙන් <ph name="APP_NAME" /> සැකසීමට නොහැකි විය. ඔබගේ පරිපාලක සම්බන්ධ කර ගන්න. දෝෂ කේතය: <ph name="ERROR_CODE" />.</translation>
@@ -4739,6 +4741,7 @@
 <translation id="6196854373336333322">"<ph name="EXTENSION_NAME" />" දිගුව ඔබගේ ප්‍රොක්සි සැකසීම්වල පාලනය ගෙන ඇත, ඉන් අදහස් වන්නේ ඔබ සබැඳිව කරන ඕනෑම දෙයක් වෙනස් කිරීමට, බිඳී යාමට, හෝ හොරෙන් අසා සිටීමට හැකි බවයි. මෙම වෙනස් වීම සිදු වූයේ ඇයිදැයි ඔබට ව්ශ්වාස නැතිනම්, ඔබට බොහෝ විට එය අවශ්‍ය නොවිය හැකිය.</translation>
 <translation id="6198102561359457428">පිටවී නැවත පිවිසෙන්න</translation>
 <translation id="6198252989419008588">PIN අංකය වෙනස් කරන්න</translation>
+<translation id="6200047250927636406">ගොනුව ඉවත ලන්න</translation>
 <translation id="6202304368170870640">ඔබට ඔබේ උපාංගයට පුරනය වීමට හෝ අනවහිර කිරීමට ඔබේ PIN භාවිතා කළ හැකිය.</translation>
 <translation id="6206311232642889873">පින්තූරය පිටපත් කරන්න (&amp;y)</translation>
 <translation id="6207200176136643843">පෙරනිමි විශාලන මට්ටමට යළි පිහිටුවන්න</translation>
@@ -5305,6 +5308,7 @@
 <translation id="6831043979455480757">පරිවර්තනය කරන්න</translation>
 <translation id="6833479554815567477">ටැබය <ph name="GROUP_NAME" /> සමූහය වෙතින් ගෙන යන ලදි - <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">බුද්ධිමත් සහ සුරක්ෂිත බ්‍රව්සරයකට මාරු වන්න</translation>
+<translation id="6834652994408928492">හිරු බැසීමේදී අඳුරු ප්‍රකාරය ස්වයංක්‍රියව ක්‍රියාවිරහිත කරනු ඇත</translation>
 <translation id="683540480453879381"><ph name="FILE_EXTENSIONS" /> ගොනු විවෘත කරන්න</translation>
 <translation id="6835762382653651563">ඔබේ <ph name="DEVICE_TYPE" /> යාවත්කාලීන කිරීමට කරුණාකර අන්තර්ජාලය වෙත සබඳින්න.</translation>
 <translation id="6838034009068684089">අඩවියකට ඔබේ තිර මත windows විවෘත කිරීමට සහ තැබීමට අවශ්‍ය වූ විට අසන්න (නිර්දේශිතයි)</translation>
@@ -6017,6 +6021,7 @@
 <translation id="7622114377921274169">ආරෝපණය වෙමින්.</translation>
 <translation id="7622768823216805500">අඩවි සාමාන්‍යයෙන් වඩා පහසු ගෙවීම වැනි සාප්පු සවාරි විශේෂාංග සඳහා ගෙවීම් හසුරුවන ස්ථාපනය කරයි</translation>
 <translation id="7622903810087708234">මුරපද විස්තර</translation>
+<translation id="7622966771025050155">ග්‍රහණය කළ ටැබයට මාරු වන්න</translation>
 <translation id="7624337243375417909">කැප්ස් ලොක් ක්‍රියාවිරහිතයි</translation>
 <translation id="7625568159987162309">අවසර සහ අඩවි හරහා ගබඩා කර ඇති දත්ත බලන්න</translation>
 <translation id="7628201176665550262">නැවුම් කිරීමේ අනුපාතය</translation>
@@ -6183,6 +6188,7 @@
 <translation id="7784067724422331729">ඔබගේ පරිගණකයේ ආරක්ෂක සැකසුම් මෙම ගොනුව අවහිර කර ඇත.</translation>
 <translation id="7784796923038949829">අඩවියේ දත්ත කියවීමට හෝ වෙනස් කිරීමට නොහැක</translation>
 <translation id="778480864305029524">ක්ෂණික ටෙදරින් භාවිත කිරීමට, Google Play සේවා සඳහා දැනුම්දීම් ක්‍රියාත්මක කරන්න.</translation>
+<translation id="7785471469930192436">අදාළ වන්නේ නම්, ඔබගේ සෙවීම් ඉතිහාසය මැකීම සඳහා ඔබගේ සෙවීම් යන්ත්‍රයේ උපදෙස් බලන්න.</translation>
 <translation id="7786889348652477777">නැවත පූරණය කිරීමේ යෙදුම</translation>
 <translation id="7787308148023287649">තවත් තිරයක පෙන්වන්න</translation>
 <translation id="7788298548579301890">ඔබේ පරිගණකයේ ඇති වෙනත් ක්‍රමලේඛයක් යෙදුමක් එක් කර ඇති අතර එයින් Chrome ක්‍රියා කරන ආකරය වෙනස් විය හැකිය.
@@ -6791,6 +6797,7 @@
 <translation id="8438566539970814960">සෙවීම් සහ ගවේෂණය වඩා හොඳ කරන්න</translation>
 <translation id="8439506636278576865">මෙම භාෂාවෙන් පිටු පරිවර්තනය කිරීමට පිරිනමයි</translation>
 <translation id="8440630305826533614">Linux යෙදුම්</translation>
+<translation id="8446225304314102060"><ph name="TAB_ORIGIN" /> ටැබයට මාරු වන්න</translation>
 <translation id="8446884382197647889">තවත් දැනගන්න</translation>
 <translation id="8447409163267621480">Ctrl හෝ Alt ඇතුළත් කරන්න</translation>
 <translation id="8448729345478502352">ඔබගේ තිරය මත ඇති අයිතම කුඩා හෝ විශාල කරන්න</translation>
@@ -7452,6 +7459,7 @@
 <translation id="9148058034647219655">ඉවත් වන්න</translation>
 <translation id="9148126808321036104">නැවත පිවිසෙන්න</translation>
 <translation id="9148963623915467028">මෙම අඩවියට ඔබේ ස්ථානයට ප්‍රවේශ විය හැකිය.</translation>
+<translation id="9149529198050266366">හිරු නැගීමේදී අඳුරු ප්‍රකාරය ස්වයංක්‍රියව ක්‍රියාවිරහිත කරනු ඇත</translation>
 <translation id="9149866541089851383">සකසන්න...</translation>
 <translation id="9150045010208374699">ඔබගේ කැමරාව භාවිතා කරන්න</translation>
 <translation id="9150079578948279438">පැතිකඩ ඉවත් කළ නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න, නැති නම් තාක්ෂණික සහාය සඳහා ඔබගේ වාහක සම්බන්ධ කර ගන්න.</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index 46420c649..b1713040 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -6867,7 +6867,7 @@
 <translation id="850875081535031620">Najdena ni bila nobena škodljiva programska oprema</translation>
 <translation id="8509177919508253835">Ponastavitev varnostnih ključev in ustvarjanje kod PIN</translation>
 <translation id="8509646642152301857">Prenos slovarja za preverjanje črkovanja ni uspel.</translation>
-<translation id="8509967119010808787">Če želite iskati zavihke, kliknite tu</translation>
+<translation id="8509967119010808787">Če želite iskati zavihke, kliknite tu.</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Najdeno ni bilo nobeno šibko geslo.}=1{Najdeno je bilo {COUNT} šibko geslo.}one{Najdeno je bilo {COUNT} šibko geslo.}two{Najdeni sta bili {COUNT} šibki gesli.}few{Najdena so bila {COUNT} šibka gesla.}other{Najdenih je bilo {COUNT} šibkih gesel.}}</translation>
 <translation id="8512476990829870887">Končaj proces</translation>
 <translation id="851263357009351303">Vedno dovoli mestu <ph name="HOST" />, da pokaže slike</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb
index c588f5f4..846d2ea7 100644
--- a/chrome/app/resources/generated_resources_sq.xtb
+++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;Hidhi poshtë</translation>
 <translation id="1508491105858779599">Vendose gishtin mbi sensorin e gjurmës së gishtit për të shkyçur pajisjen.</translation>
 <translation id="1508575541972276599">Versioni aktual është Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;Restauro grupin</translation>
 <translation id="1509281256533087115">Qasu në çdo <ph name="DEVICE_NAME_AND_VENDOR" /> përmes USB</translation>
 <translation id="1509960214886564027">Veçoritë në shumë sajte mund të ndalojnë së funksionuari</translation>
 <translation id="1510238584712386396">Nisësi</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">Është shkarkuar tashmë</translation>
 <translation id="1628948239858170093">Do ta skanosh skedarin përpara se ta hapësh?</translation>
 <translation id="1629314197035607094">Fjalëkalimi ka skaduar</translation>
+<translation id="1629451755632656601">Të lejohet që Google të gjejë ulje çmimi të personalizuara në karrocat e tua?</translation>
 <translation id="1630300831289687074">Do të mund ta përdorësh pajisjen tënde Chromebook së shpejti.</translation>
 <translation id="163072119192489970">Lejohen të përfundojnë dërgimin dhe marrjen e të dhënave</translation>
 <translation id="1630768113285622200">Rinis dhe vazhdo</translation>
@@ -1288,6 +1290,7 @@
 <translation id="236117173274098341">Optimizo</translation>
 <translation id="2361340419970998028">Komentet po dërgohen...</translation>
 <translation id="236141728043665931">Blloko gjithmonë qasjen te mikrofoni</translation>
+<translation id="2363744066037724557">&amp;Restauro dritaren</translation>
 <translation id="2364498172489649528">Kaloi</translation>
 <translation id="2365507699358342471">Ky sajt mund të shikojë tekstin dhe imazhet e kopjuara te kujtesa e fragmenteve.</translation>
 <translation id="2367972762794486313">Shfaq aplikacionet</translation>
@@ -2670,6 +2673,7 @@
 <translation id="3857807444929313943">Ngrije dhe më pas prek përsëri</translation>
 <translation id="3861638017150647085">Emri i përdoruesit "<ph name="USERNAME" />" nuk ofrohet</translation>
 <translation id="3861977424605124250">Shfaq në momentin e nisjes</translation>
+<translation id="386239283124269513">&amp;Restauro grupin</translation>
 <translation id="3862788408946266506">Aplikacioni me cilësinë e shfaqjes "kiosk_only" duhet të instalohet në modalitetin "kioskë" të sistemit operativ Chrome</translation>
 <translation id="3865414814144988605">Rezolucioni</translation>
 <translation id="3866249974567520381">Përshkrimi</translation>
@@ -5645,6 +5649,7 @@
 <translation id="7225179976675429563">Mungon lloji i rrjetit</translation>
 <translation id="7228479291753472782">Manipulo cilësimet që specifikojnë nëse sajtet e uebit mund të përdorin funksione si vendndodhja gjeografike, mikrofoni, kamera etj.</translation>
 <translation id="7228523857728654909">Kyçja e ekranit dhe identifikimi</translation>
+<translation id="7230222852462421043">&amp;Restauro dritaren</translation>
 <translation id="7230787553283372882">Personalizo madhësinë e tekstit</translation>
 <translation id="7232750842195536390">Riemërtimi dështoi</translation>
 <translation id="7234010996000898150">Po anulohet restaurimi i Linux</translation>
@@ -6253,12 +6258,14 @@
 <translation id="7853747251428735">Vegla të tj&amp;era</translation>
 <translation id="7855678561139483478">Lëvize skedën në dritare të re</translation>
 <translation id="7857093393627376423">Sugjerimet e tekstit</translation>
+<translation id="7857675386615530425">Kërko në një pjesë të faqes me "Lenten e Google"</translation>
 <translation id="7857949311770343000">A është kjo faqja e skedës së re që po prisje?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">Shërbimi: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Shkarkimet</translation>
 <translation id="7861846108263890455">Gjuha e "Llogarisë së Google"</translation>
 <translation id="7864539943188674973">Çaktivizo Bluetooth-in</translation>
+<translation id="7866230141401327032">Kërko në një pjesë të faqes me "Lenten e Google"</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - E çiftuar</translation>
 <translation id="7870730066603611552">Rishiko opsionet e sinkronizimit pas konfigurimit</translation>
 <translation id="7870790288828963061">Nuk u gjetën aplikacione kioskë me version më të ri. Nuk ka asgjë për të përditësuar. Hiqe memorien USB.</translation>
@@ -6833,6 +6840,7 @@
 <translation id="850875081535031620">Nuk u gjet asnjë softuer i dëmshëm</translation>
 <translation id="8509177919508253835">Rivendos çelësat e sigurisë dhe krijo kodet PIN</translation>
 <translation id="8509646642152301857">Dështoi shkarkimi i fjalorit të kontrollit të drejtshkrimit.</translation>
+<translation id="8509967119010808787">Për të kërkuar në skedat e tua, kliko këtu</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{Nuk u gjet asnjë fjalëkalim i dobët}=1{U gjet {COUNT} fjalëkalim i dobët}other{U gjetën {COUNT} fjalëkalime të dobëta}}</translation>
 <translation id="8512476990829870887">Përfundo procesin</translation>
 <translation id="851263357009351303">Lejo gjithmonë që <ph name="HOST" /> të shfaqë imazhet</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb
index cc1ca002..2147b5dc 100644
--- a/chrome/app/resources/generated_resources_ta.xtb
+++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -126,7 +126,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> - <ph name="GROUP_NAME" /> குழுவின் ஒரு பகுதி</translation>
 <translation id="1133418583142946603">இந்தப் பக்கத்தைச் சேர்</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_INDEX" />/<ph name="EMOJI_COUNT" />.</translation>
-<translation id="1136712381129578788">தவறான பின் பல முறை உள்ளிடப்பட்டதால் பாதுகாப்பு விசை பூட்டப்பட்டது. திறப்பதற்கு அதை அகற்றி மீண்டும் செருகவும்.</translation>
+<translation id="1136712381129578788">தவறான பின் பல முறை உள்ளிடப்பட்டதால் பாதுகாப்பு விசை பூட்டப்பட்டது. அன்லாக் செய்ய, அதை அகற்றி மீண்டும் செருகவும்.</translation>
 <translation id="1137589305610962734">தற்காலிகத் தரவு</translation>
 <translation id="1137673463384776352"><ph name="APP" /> இல் இணைப்பைத் திற</translation>
 <translation id="1138686548582345331">{MUTED_NOTIFICATIONS_COUNT,plural, =1{புதிய அறிவிப்பு}other{# புதிய அறிவிப்புகள்}}</translation>
@@ -304,7 +304,7 @@
 <translation id="1333965224356556482">எனது இருப்பிட விவரத்தை அறிய தளங்களை அனுமதிக்காதே</translation>
 <translation id="133535873114485416">விருப்பமான உள்ளீட்டு முறை</translation>
 <translation id="1335929031622236846">உங்கள் சாதனத்தைப் பதிவுசெய்யவும்</translation>
-<translation id="1336902454946927954">உங்களின் கைரேகையை அடையாளங்காண முடியவில்லை என்பதால் பாதுகாப்பு விசை பூட்டப்பட்டுள்ளது. பூட்டைத் திறக்க, உங்கள் பின்னை உள்ளிடவும்.</translation>
+<translation id="1336902454946927954">உங்களின் கைரேகையை அடையாளங்காண முடியவில்லை என்பதால் பாதுகாப்பு விசை பூட்டப்பட்டுள்ளது. அன்லாக் செய்ய, உங்கள் பின்னை உள்ளிடவும்.</translation>
 <translation id="1337692097987160377">இந்தத் தாவலைப் பகிர்</translation>
 <translation id="1338802252451106843">இந்த ஆப்ஸை <ph name="ORIGIN" /> திறக்க விரும்புகிறது.</translation>
 <translation id="1338950911836659113">நீக்குகிறது...</translation>
@@ -340,7 +340,7 @@
 <translation id="1378613616312864539">இந்த அமைப்பைக் கட்டுப்படுத்துவது: <ph name="NAME" /></translation>
 <translation id="1378848228640136848">{NUM_COMPROMISED,plural, =0{களவாடப்பட்ட கடவுச்சொற்கள் எதுவுமில்லை}=1{1 களவாடப்பட்ட கடவுச்சொல்}other{{NUM_COMPROMISED} களவாடப்பட்ட கடவுச்சொற்கள்}}</translation>
 <translation id="1380028686461971526">நெட்வொர்க்குடன் தானாக இணை</translation>
-<translation id="1383597849754832576">உடனடி வசனத்தின் கோப்புகளைப் பதிவிறக்க முடியவில்லை. பிறகு முயலவும்.</translation>
+<translation id="1383597849754832576">உடனடி வசனத்தின் ஃபைல்களைப் பதிவிறக்க முடியவில்லை. பிறகு முயலவும்.</translation>
 <translation id="1383861834909034572">முடித்ததும் திறக்கிறது</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384849755549338773">பிற மொழிகளில் உள்ள இணையதளங்களிலும் Google Translateடைக் காட்டு</translation>
@@ -466,6 +466,7 @@
 <translation id="1507246803636407672">நிராகரி</translation>
 <translation id="1508491105858779599">சாதனத்தை அன்லாக் செய்ய, விரலை கைரேகை உணர்வியின் மீது வைக்கவும்.</translation>
 <translation id="1508575541972276599">தற்போதைய பதிப்பு: Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;குழுவை மீட்டெடு</translation>
 <translation id="1509281256533087115">USB வழியாக எந்தவொரு <ph name="DEVICE_NAME_AND_VENDOR" />ஐயும் அணுகலாம்</translation>
 <translation id="1509960214886564027">பெரும்பாலான தளங்களிலுள்ள அம்சங்கள் செயல்படாமல் போகக்கூடும்</translation>
 <translation id="1510238584712386396">துவக்கி</translation>
@@ -588,6 +589,7 @@
 <translation id="1627408615528139100">ஏற்கனவே பதிவிறக்கப்பட்டது</translation>
 <translation id="1628948239858170093">கோப்பினைத் திறப்பதற்கு முன்பு ஸ்கேன் செய்யவா?</translation>
 <translation id="1629314197035607094">கடவுச்சொல் காலாவதியாகிவிட்டது</translation>
+<translation id="1629451755632656601">உங்கள் கார்ட்டுகளில் உள்ள பொருட்களுக்கான பிரத்தியேகத் தள்ளுபடிகளைக் கண்டறிய Googleளை அனுமதிக்கவா?</translation>
 <translation id="1630300831289687074">விரைவில் உங்கள் Chromebookகைப் பயன்படுத்தலாம்.</translation>
 <translation id="163072119192489970">தரவை அனுப்புவதையும் பெறுவதையும் நிறைவுசெய்ய அனுமதிக்கப்பட்டுள்ள தளங்கள்</translation>
 <translation id="1630768113285622200">மீண்டும் தொடங்கி தொடர்க</translation>
@@ -867,7 +869,7 @@
 <translation id="1892341345406963517">வணக்கம் <ph name="PARENT_NAME" /></translation>
 <translation id="189358972401248634">பிற மொழிகள்</translation>
 <translation id="1895658205118569222">நிறுத்தம்</translation>
-<translation id="1900305421498694955">Google Playயிலிருந்து பதிவிறக்கப்படும் ஆப்ஸுக்கு வெளிப்புறச் சேமிப்பக சாதனங்களில் உள்ள கோப்புகளைப் படிப்பதற்கும் திருத்துவதற்கும் ஃபைல் சிஸ்டத்திற்கான முழு அணுகல் தேவைப்படக்கூடும். வெளிப்புற இயக்ககத்தைப் பயன்படுத்தும் அனைவராலும் சாதனத்தில் உருவாக்கப்பட்ட கோப்புகளையும் கோப்புறைகளையும் பார்க்க முடியும். <ph name="LINK_BEGIN" />மேலும் அறிக<ph name="LINK_END" /></translation>
+<translation id="1900305421498694955">Google Playயிலிருந்து பதிவிறக்கப்படும் ஆப்ஸுக்கு வெளிப்புறச் சேமிப்பக சாதனங்களில் உள்ள ஃபைல்களைப் படிப்பதற்கும் திருத்துவதற்கும் ஃபைல் சிஸ்டத்திற்கான முழு அணுகல் தேவைப்படக்கூடும். வெளிப்புற இயக்ககத்தைப் பயன்படுத்தும் அனைவராலும் சாதனத்தில் உருவாக்கப்பட்ட கோப்புகளையும் கோப்புறைகளையும் பார்க்க முடியும். <ph name="LINK_BEGIN" />மேலும் அறிக<ph name="LINK_END" /></translation>
 <translation id="1901303067676059328">அ&amp;னைத்தையும் தேர்ந்தெடு</translation>
 <translation id="1901396183631570154">இந்தக் கடவுச்சொற்களை Chromeமால் உங்கள் Google கணக்கில் சேமிக்க முடியவில்லை. இருப்பினும் அவற்றை இந்தச் சாதனத்தில் சேமிக்கலாம்.</translation>
 <translation id="1903995858055162096">உங்கள் சாதனம் இல்லையா? <ph name="BEGIN_LINK" />கெஸ்ட் பயன்முறையைப்<ph name="END_LINK" /> பயன்படுத்துங்கள்.</translation>
@@ -1167,7 +1169,7 @@
 <translation id="2224551243087462610">கோப்புறை பெயரை மாற்று</translation>
 <translation id="2225864335125757863">உங்கள் கணக்கைப் பாதுகாப்பாக வைத்துக்கொள்ள இந்தக் கடவுச்சொற்களை உடனடியாக மாற்றவும்:</translation>
 <translation id="2226449515541314767">MIDI சாதனங்களை முழுமையாக கட்டுப்படுத்துவதிலிருந்து இந்தத் தளம் தடுக்கப்பட்டுள்ளது.</translation>
-<translation id="2226907662744526012">பின்னை உள்ளிட்டதும் தானாகத் திற</translation>
+<translation id="2226907662744526012">பின்னை உள்ளிட்டதும் தானாக அன்லாக் செய்</translation>
 <translation id="2227179592712503583">பரிந்துரையை அகற்று</translation>
 <translation id="2229161054156947610">1 மணிநேரத்திற்கும் அதிகமாக உள்ளது</translation>
 <translation id="222931766245975952">கோப்பு சிதைந்தது</translation>
@@ -1260,7 +1262,7 @@
 <translation id="2322318151094136999">ஒரு தளம் சீரியல் போர்ட்டுகளை அணுக வேண்டியிருக்கும்போது கேள் (பரிந்துரைக்கப்படுகிறது)</translation>
 <translation id="2323018538045954000">சேமித்த வைஃபை நெட்வொர்க்குகள்</translation>
 <translation id="2325444234681128157">கடவுச்சொல்லைச் சேமி</translation>
-<translation id="2326188115274135041">தானாகத் திறப்பதை இயக்க பின்னை உறுதிசெய்யவும்</translation>
+<translation id="2326188115274135041">தானாக அன்லாக் ஆகும் அம்சத்தை இயக்க பின்னை உறுதிசெய்யவும்</translation>
 <translation id="2326931316514688470">&amp;பயன்பாட்டை மீண்டும் ஏற்று</translation>
 <translation id="2327492829706409234">ஆப்ஸை இயக்கு</translation>
 <translation id="2328561734797404498"><ph name="APP_NAME" /> ஆப்ஸைப் பயன்படுத்த, உங்கள் சாதனத்தை மீண்டும் தொடங்கவும்.</translation>
@@ -1305,6 +1307,7 @@
 <translation id="236117173274098341">Optimize</translation>
 <translation id="2361340419970998028">கருத்தை அனுப்புகிறது...</translation>
 <translation id="236141728043665931">மைக்ரோஃபோன் அணுகலை எப்போதும் தடு</translation>
+<translation id="2363744066037724557">&amp;சாளரத்தை மீட்டெடு</translation>
 <translation id="2364498172489649528">வெற்றி</translation>
 <translation id="2365507699358342471">கிளிப்போர்டுக்கு நகலெடுத்த உரையையும் படங்களையும், இந்தத் தளத்தால் பார்க்க முடியும்.</translation>
 <translation id="2367972762794486313">பயன்பாடுகளைக் காட்டு</translation>
@@ -1352,7 +1355,7 @@
 <translation id="243179355394256322">அங்கீகரிக்கப்பட்ட பயனர்கள் மட்டுமே சாதனத்தைப் பதிவுசெய்ய உங்கள் நிறுவனம் அனுமதிக்கிறது. சாதனங்களைப் பதிவுசெய்ய இந்தப் பயனருக்கு அனுமதி இல்லை. நிர்வாகிக் கன்சோலின் 'பயனர்கள்' பிரிவில் நிர்வாகிகளுக்கான சிறப்புரிமை விருப்பம் "Google Meet வன்பொருளைப் பதிவுசெய்" காட்டப்படுவதை உறுதிசெய்துகொள்ளவும்.</translation>
 <translation id="2433452467737464329">பக்கத்தைத் தானாகவே புதுப்பிக்க URLலில் வினவல் அளவுருவைச் சேர்க்கவும்: chrome://network/?refresh=&lt;sec&gt;</translation>
 <translation id="2433507940547922241">தோற்றம்</translation>
-<translation id="2433836460518180625">சாதனத்தை மட்டும் திற</translation>
+<translation id="2433836460518180625">சாதனத்தை மட்டும் அன்லாக் செய்</translation>
 <translation id="2434449159125086437">பிரிண்டரை அமைக்க இயலவில்லை. உள்ளமைவைச் சரிபார்த்து மீண்டும் முயலவும்.</translation>
 <translation id="2434758125294431199">யாரெல்லாம் உங்களுடன் பகிரலாம் என்பதைத் தேர்ந்தெடுங்கள்</translation>
 <translation id="2435248616906486374">நெட்வொர்க் துண்டிக்கப்பட்டது</translation>
@@ -1410,7 +1413,7 @@
 <translation id="2485422356828889247">நிறுவல் நீக்கு</translation>
 <translation id="2487067538648443797">புதிய புத்தகக்குறியைச் சேர்</translation>
 <translation id="2487268545026948104">உங்கள் தரவை மீட்டெடுக்க இணையத்துடன் இணைக்கவும்</translation>
-<translation id="2489829450872380594">அடுத்த முறை, இந்த <ph name="DEVICE_TYPE" /> சாதனத்தை புதிய ஃபோன் திறக்கும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
+<translation id="2489829450872380594">அடுத்த முறை, இந்த <ph name="DEVICE_TYPE" /> சாதனத்தை புதிய ஃபோன் அன்லாக் ஆகும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
 <translation id="2489918096470125693">&amp;கோப்புறையைச் சேர்...</translation>
 <translation id="2490481887078769936">பட்டியலிலிருந்து '<ph name="FILE_NAME" />' அகற்றப்பட்டது</translation>
 <translation id="249113932447298600">இந்த நேரத்தில் <ph name="DEVICE_LABEL" /> சாதனத்தை ஆதரிக்க முடியவில்லை. மன்னிக்கவும்.</translation>
@@ -1440,7 +1443,7 @@
 <translation id="2509566264613697683">8x</translation>
 <translation id="2510988373360790637">புளூடூத் சாதனத்தை மறந்துவிடுதல்</translation>
 <translation id="2513396635448525189">உள்நுழைவுப் படம்</translation>
-<translation id="2514326558286966059">கைரேகை மூலம் விரைவாகத் திறந்திடுங்கள்</translation>
+<translation id="2514326558286966059">கைரேகை மூலம் விரைவாக அன்லாக் செய்திடுங்கள்</translation>
 <translation id="2515586267016047495">Alt</translation>
 <translation id="2515807442171220586">மேலும் ஒரு ஸ்விட்சை ஒதுக்கு</translation>
 <translation id="2517472476991765520">ஸ்கேன் செய்</translation>
@@ -1493,7 +1496,7 @@
 <translation id="2575441894380764255">குறுக்கிடும்/தவறாக வழிநடத்தும் விளம்பரங்களைக் காட்ட அனுமதி இல்லாத தளங்கள்</translation>
 <translation id="257779572837908839">சந்திப்புகளுக்கான Chromebox சாதனமாக அமை</translation>
 <translation id="2579232805407578790">சேவையகத்துடன் இணைக்க முடியவில்லை. நெட்வொர்க் இணைப்பைச் சரிபார்த்துவிட்டு மீண்டும் முயலவும். சிக்கல் தொடர்ந்தால் Chromebookகை மீண்டும் தொடங்கவும். பிழைக் குறியீடு: <ph name="ERROR_CODE" />.</translation>
-<translation id="2580889980133367162">பல கோப்புகளைப் பதிவிறக்க எப்போதும் <ph name="HOST" /> ஐ அனுமதி</translation>
+<translation id="2580889980133367162">பல ஃபைல்களைப் பதிவிறக்க எப்போதும் <ph name="HOST" /> ஐ அனுமதி</translation>
 <translation id="258095186877893873">நீண்ட</translation>
 <translation id="2582253231918033891"><ph name="PRODUCT_NAME" /> <ph name="PRODUCT_VERSION" /> (இயங்குதளம் <ph name="PLATFORM_VERSION" />) <ph name="DEVICE_SERIAL_NUMBER" /></translation>
 <translation id="2584109212074498965">Kerberos டிக்கெட்டைப் பெற இயலவில்லை. மீண்டும் முயலவும் அல்லது உங்கள் நிறுவனத்தின் சாதன நிர்வாகியைத் தொடர்பு கொள்ளவும். (பிழை குறியீடு <ph name="ERROR_CODE" />).</translation>
@@ -1941,7 +1944,7 @@
 <translation id="3038612606416062604">கைமுறையாகப் பிரிண்டரைச் சேர்</translation>
 <translation id="3039491566278747710">சாதனத்தில் ஆஃப்லைன் கொள்கையை நிறுவ முடியவில்லை.</translation>
 <translation id="3043581297103810752"><ph name="ORIGIN" /> என்ற இணைப்பில் இருந்து</translation>
-<translation id="3045447014237878114">இந்தத் தளம் தானாகவே பல கோப்புகளைப் பதிவிறக்கம் செய்தது</translation>
+<translation id="3045447014237878114">இந்தத் தளம் தானாகவே பல ஃபைல்களைப் பதிவிறக்கம் செய்தது</translation>
 <translation id="3046178388369461825">Linux டிஸ்க் சேமிப்பிடம் மிகவும் குறைவாக உள்ளது</translation>
 <translation id="3046910703532196514">வலைப்பக்கம், முழுமையாக</translation>
 <translation id="304747341537320566">பேச்சு என்ஜின்கள்</translation>
@@ -2324,7 +2327,7 @@
 <translation id="3480612136143976912">உடனடி வசனத்திற்கான அளவையும் நடையையும் பிரத்தியேகமாக்கலாம். சில ஆப்ஸும் தளங்களும் கூட இந்த அமைப்பைப் பயன்படுத்தும்.</translation>
 <translation id="3480827850068960424"><ph name="NUM" /> தாவல்கள் உள்ளன</translation>
 <translation id="3481268647794498892"><ph name="COUNTDOWN_SECONDS" /> விநாடிகளில் <ph name="ALTERNATIVE_BROWSER_NAME" /> உலாவியில் திறக்கும்</translation>
-<translation id="3482719661246593752"><ph name="ORIGIN" /> தளத்தால் பின்வரும் கோப்புகளைப் பார்க்க முடியும்:</translation>
+<translation id="3482719661246593752"><ph name="ORIGIN" /> தளத்தால் பின்வரும் ஃபைல்களைப் பார்க்க முடியும்:</translation>
 <translation id="3484273680291419129">தீங்கிழைக்கும் மென்பொருளை அகற்றுகிறது...</translation>
 <translation id="3484869148456018791">புதிய சான்றிதழைப் பெறு</translation>
 <translation id="3487007233252413104">அநாமதேய செயல்பாடு</translation>
@@ -2334,7 +2337,7 @@
 <translation id="3491678231052507920">வழக்கமாக VR அமர்வுகளில் நீங்கள் உள்நுழைவதற்காக உங்கள் விர்ச்சுவல் ரியாலிட்டி சாதனங்களையும் தரவையும் தளங்கள் பயன்படுத்தும்</translation>
 <translation id="3493486281776271508">இணைய இணைப்பு அவசியம்</translation>
 <translation id="3493881266323043047">செல்லுபடிக்காலம்</translation>
-<translation id="3494769164076977169">முதல் கோப்பு பதிவிறக்கமானதும் தானாகவே கோப்புகளைப் பதிவிறக்கத் தளம் முயற்சிக்கும்போது கேள் (பரிந்துரைக்கப்பட்டது)</translation>
+<translation id="3494769164076977169">முதல் கோப்பு பதிவிறக்கமானதும் தானாகவே ஃபைல்களைப் பதிவிறக்கத் தளம் முயற்சிக்கும்போது கேள் (பரிந்துரைக்கப்பட்டது)</translation>
 <translation id="3495496470825196617">சார்ஜ் செய்யப்படும்போது செயலற்ற நிலை</translation>
 <translation id="3495660573538963482">Google அசிஸ்டண்ட் அமைப்புகள்</translation>
 <translation id="3496213124478423963">சிறிதாக்கு</translation>
@@ -2448,7 +2451,7 @@
 <translation id="3619115746895587757">காப்பச்சினோ</translation>
 <translation id="362266093274784978">{COUNT,plural, =1{ஓர் ஆப்ஸை}other{# ஆப்ஸை}}</translation>
 <translation id="362333465072914957">CAயிடமிருந்து சான்றிதழ் பெறுவதற்காகக் காத்திருக்கிறது</translation>
-<translation id="3624567683873126087">ஃபோனைத் திறந்து, Google கணக்கில் உள்நுழை</translation>
+<translation id="3624567683873126087">ஃபோனை அன்லாக் செய்து, Google கணக்கில் உள்நுழை</translation>
 <translation id="3625481642044239431">தவறான கோப்பைத் தேர்ந்தெடுத்துள்ளீர்கள். மீண்டும் முயலவும்.</translation>
 <translation id="3626296069957678981">இந்த Chromebookகை சார்ஜ் செய்ய இதற்கு இணக்கமான Dell பேட்டரியைப் பயன்படுத்தவும்.</translation>
 <translation id="3627320433825461852">1 நிமிடத்திற்கும் குறைவாக உள்ளது</translation>
@@ -2456,7 +2459,7 @@
 <translation id="3627671146180677314">Netscape சான்றிதழ் புதுப்பிப்பு நேரம்</translation>
 <translation id="3627879631695760395"><ph name="APP" />ஐ நிறுவு...</translation>
 <translation id="3628275722731025472">புளூடூத்தை முடக்குதல்</translation>
-<translation id="3629631988386925734">Smart Lockகை இயக்க, கடவுச்சொல்லை உள்ளிடவும். அடுத்த முறை <ph name="DEVICE_TYPE" />ஐ உங்கள் மொபைல் திறக்கும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
+<translation id="3629631988386925734">Smart Lockகை இயக்க, கடவுச்சொல்லை உள்ளிடவும். அடுத்த முறை <ph name="DEVICE_TYPE" />ஐ உங்கள் மொபைல் அன்லாக் ஆகும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
 <translation id="3630132874740063857">உங்கள் ஃபோன்</translation>
 <translation id="3630995161997703415">இந்தத் தளத்தை எந்த நேரத்திலும் பயன்படுத்த அதனை உங்கள் ஷெல்ஃபில் சேர்க்கவும்</translation>
 <translation id="3634652306074934350">அனுமதி கோரிக்கை காலாவதியாகிவிட்டது</translation>
@@ -2687,6 +2690,7 @@
 <translation id="3857807444929313943">விரலை எடுத்துவிட்டு மீண்டும் தொடவும்</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" என்ற பயனர்பெயரைப் பயன்படுத்த முடியாது</translation>
 <translation id="3861977424605124250">தொடங்கும்போது காட்டு</translation>
+<translation id="386239283124269513">&amp;குழுவை மீட்டெடு</translation>
 <translation id="3862788408946266506">'kiosk_only' மெனிஃபெஸ்ட் பண்புக்கூறைக் கொண்ட ஆப்ஸை Chrome OS கியோஸ்க் பயன்முறையிலேயே நிறுவ வேண்டும்</translation>
 <translation id="3865414814144988605">தெளிவு</translation>
 <translation id="3866249974567520381">விவரம்</translation>
@@ -2748,7 +2752,7 @@
 <translation id="392089482157167418">ChromeVox (பேச்சுவடிவ கருத்து) ஐ இயக்கு</translation>
 <translation id="3920909973552939961">பேமெண்ட் ஹேண்ட்லர்களை நிறுவ அனுமதி இல்லாத தளங்கள்</translation>
 <translation id="3923184630988645767">டேட்டா உபயோகம்</translation>
-<translation id="3923676227229836009">இந்தப் பக்கத்தில் கோப்புகளைப் பார்க்க முடியும்</translation>
+<translation id="3923676227229836009">இந்தப் பக்கத்தில் ஃபைல்களைப் பார்க்க முடியும்</translation>
 <translation id="3923943745177274752"><ph name="DEVICE_TYPE" />க்கு வரவேற்கிறோம்</translation>
 <translation id="3924145049010392604">Meta</translation>
 <translation id="3924487862883651986">URLகளைச் சரிபார்க்க பாதுகாப்பு உலாவலுக்கு அவற்றை அனுப்பும். புதிய அச்சுறுத்தல்களைக் கண்டறிவதற்கு உதவ, பக்கங்கள், பதிவிறக்கங்கள், நீட்டிப்பு செயல்பாடு, சிஸ்டம் தகவல் போன்ற சிலவற்றையும் அனுப்பும். Google ஆப்ஸ் முழுவதிலும் உங்களைப் பாதுகாக்க, உங்கள் Google கணக்கில் உள்நுழைந்திருக்கும்போது தற்காலிகமாக அதனுடன் இந்தத் தரவை இணைக்கும்.</translation>
@@ -2830,7 +2834,7 @@
 <translation id="3987993985790029246">இணைப்பை நகலெடு</translation>
 <translation id="3988996860813292272">நேரமண்டலத்தைத் தேர்ந்தெடுக்கவும்</translation>
 <translation id="399179161741278232">இறக்குமதியானது</translation>
-<translation id="3994374631886003300"><ph name="DEVICE_TYPE" />ஐத் திறக்க, உங்கள் மொபைலை அன்லாக் செய்து, சாதனத்திற்கு அருகில் எடுத்து வரவும்.</translation>
+<translation id="3994374631886003300"><ph name="DEVICE_TYPE" />ஐ அன்லாக் செய்ய, உங்கள் மொபைலை அன்லாக் செய்து, சாதனத்திற்கு அருகில் எடுத்து வரவும்.</translation>
 <translation id="3994878504415702912">&amp;பெரிதாக்கு</translation>
 <translation id="3995138139523574647">USB-C சாதனம் (வலது பக்கம் பின்னே இருக்கும் போர்ட்)</translation>
 <translation id="4002066346123236978">தலைப்பு</translation>
@@ -3209,7 +3213,7 @@
 <translation id="4469477701382819144">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களைக் காட்டும் தளங்களில் தடுக்கப்படும்</translation>
 <translation id="4469762931504673593"><ph name="FOLDERNAME" /> கோப்புறையில் உள்ள கோப்புகளை <ph name="ORIGIN" /> தளத்தால் திருத்த முடியும்</translation>
 <translation id="4470957202018033307">வெளிப்புறச் சேமிப்பக விருப்பங்கள்</translation>
-<translation id="4471354919263203780">பேச்சு அறிதலுக்கான கோப்புகளைப் பதிவிறக்குகிறது... <ph name="PERCENT" />%</translation>
+<translation id="4471354919263203780">பேச்சு அறிதலுக்கான ஃபைல்களைப் பதிவிறக்குகிறது... <ph name="PERCENT" />%</translation>
 <translation id="447252321002412580">Chrome இன் அம்சங்களையும் செயல்திறனையும் மேம்படுத்த உதவுக</translation>
 <translation id="4472575034687746823">தொடங்குக</translation>
 <translation id="4474155171896946103">அனைத்து தாவல்களையும் புக்மார்க்கிடுக...</translation>
@@ -3398,7 +3402,7 @@
 <translation id="4651484272688821107">டெமோ பயன்முறை ஆதாரங்கள் மூலம் ஆன்லைன் காம்பொனெண்ட்டை ஏற்ற முடியவில்லை.</translation>
 <translation id="4652935475563630866">கேமரா அமைப்பில் செய்த மாற்றத்தைச் செயல்படுத்த Parallels Desktopபை மீண்டும் தொடங்க வேண்டும். தொடர Parallels Desktopபை மீண்டும் தொடங்கவும்.</translation>
 <translation id="4653405415038586100">Linuxஸை உள்ளமைக்கும்போது பிழை</translation>
-<translation id="4654236001025007561">உங்களுக்கு அருகிலுள்ள Chromebookகளிலும் Android சாதனங்களிலும் கோப்புகளைப் பகிரலாம்</translation>
+<translation id="4654236001025007561">உங்களுக்கு அருகிலுள்ள Chromebookகளிலும் Android சாதனங்களிலும் ஃபைல்களைப் பகிரலாம்</translation>
 <translation id="4657914796247705218">TrackPoint வேகம்</translation>
 <translation id="465878909996028221">HTTP, HTTPS மற்றும் கோப்பு நெறிமுறைகள் மட்டுமே உலாவி திசைதிருப்புதல் செய்யலாம்.</translation>
 <translation id="4659077111144409915">முதன்மைக் கணக்கு</translation>
@@ -3539,7 +3543,7 @@
 <translation id="4836504898754963407">கைரேகைகளை நிர்வகிக்கவும்</translation>
 <translation id="4837128290434901661">மீண்டும் Google Search என அமைக்கவா?</translation>
 <translation id="4837926214103741331">இந்தச் சாதனத்தைப் பயன்படுத்த, உங்களுக்கு அங்கீகாரம் இல்லை. உள்நுழைவு அனுமதியைப் பெற, சாதன உரிமையாளரைத் தொடர்பு கொள்ளவும்.</translation>
-<translation id="4837952862063191349">உங்கள் அகக் கணினியின் தரவைத் திறந்து, மீட்டெடுக்க, <ph name="DEVICE_TYPE" /> இன் பழைய கடவுச்சொல்லை உள்ளிடவும்.</translation>
+<translation id="4837952862063191349">உங்கள் அகக் கணினியின் தரவை அன்லாக் செய்து, மீட்டெடுக்க, <ph name="DEVICE_TYPE" /> இன் பழைய கடவுச்சொல்லை உள்ளிடவும்.</translation>
 <translation id="4838836835474292213">கிளிப்போர்டைப் படிப்பதற்கான அணுகல் அனுமதிக்கப்பட்டது</translation>
 <translation id="4838907349371614303">கடவுச்சொல் புதுப்பிக்கப்பட்டது</translation>
 <translation id="4839303808932127586">வீடியோவை இவ்வாறு சே&amp;மி...</translation>
@@ -3858,7 +3862,7 @@
 <translation id="5190926251776387065">போர்ட்டைச் செயல்படுத்து</translation>
 <translation id="5191094172448199359">உள்ளிட்ட பின்கள் (PIN) பொருந்தவில்லை</translation>
 <translation id="5191251636205085390">மூன்றாம் தரப்புக் குக்கீகளுக்கு மாற்றாகப் பயன்படுத்த உதவும் புதிய தொழில்நுட்பங்கள் குறித்தும் அவற்றைக் கட்டுப்படுத்துவது குறித்தும் மேலும் அறிக</translation>
-<translation id="51918995459521422"><ph name="ORIGIN" /> பல கோப்புகளைப் பதிவிறக்க விரும்புகிறது</translation>
+<translation id="51918995459521422"><ph name="ORIGIN" /> பல ஃபைல்களைப் பதிவிறக்க விரும்புகிறது</translation>
 <translation id="5192062846343383368">கண்காணிப்பு அமைப்புகளைப் பார்க்க Family Link ஆப்ஸைத் திறக்கவும்</translation>
 <translation id="5193988420012215838">கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது</translation>
 <translation id="5194256020863090856">மறைநிலைச் சாளரங்களில் மட்டுமே தரவு அழிக்கப்படும்</translation>
@@ -4015,7 +4019,7 @@
 <translation id="5363109466694494651">பவர்வாஷ் செய்து மாற்றியமை</translation>
 <translation id="5365881113273618889">நீங்கள் தேர்ந்தெடுத்த கோப்புறையில் முக்கியமான கோப்புகள் உள்ளன. "<ph name="APP_NAME" />" இந்தக் கோப்புறைக்கான நிரந்தர எழுதும் அணுகலை நிச்சயமாக வழங்க விரும்புகிறீர்களா?</translation>
 <translation id="536638840841140142">மார்ஜின்கள் எதுவுமில்லை</translation>
-<translation id="5368720394188453070">ஃபோன் பூட்டப்பட்டது. நுழைய, திறக்கவும்.</translation>
+<translation id="5368720394188453070">ஃபோன் பூட்டப்பட்டது. நுழைய, அன்லாக் செய்யவும்.</translation>
 <translation id="5368779022775404937"><ph name="REALM" /> இல் உள்நுழையவும்</translation>
 <translation id="536882527576164740">{0,plural, =1{மறைநிலைச் சாளரம்}other{மறைநிலைச் சாளரங்கள் (#)}}</translation>
 <translation id="5369491905435686894">மவுஸ் துரிதப்படுத்தலை இயக்கு</translation>
@@ -4285,7 +4289,7 @@
 <translation id="5662513737565158057">Linux ஆப்ஸ் வேலை செய்யும் விதத்தை மாற்றுங்கள்.</translation>
 <translation id="5667546120811588575">Google Playஐ அமைக்கிறது...</translation>
 <translation id="5668351004957198136">சரிபார்க்க முடியவில்லை</translation>
-<translation id="56702779821643359">உங்களுக்கு அருகிலுள்ளவர்களுடன் கோப்புகளைப் பகிருங்கள். <ph name="LINK_BEGIN" />மேலும் அறிக<ph name="LINK_END" /></translation>
+<translation id="56702779821643359">உங்களுக்கு அருகிலுள்ளவர்களுடன் ஃபைல்களைப் பகிருங்கள். <ph name="LINK_BEGIN" />மேலும் அறிக<ph name="LINK_END" /></translation>
 <translation id="5671641761787789573">படங்கள் தடுக்கப்பட்டன</translation>
 <translation id="5671658447180261823"><ph name="SUGGESTION_NAME" /> பரிந்துரையை அகற்றும்</translation>
 <translation id="567587836466137939"><ph name="MONTH_AND_YEAR" /> வரை இந்தச் சாதனத்தின் மென்பொருளும் பாதுகாப்பும் தானாகவே புதுப்பிக்கப்படும். <ph name="LINK_BEGIN" />மேலும் அறிக<ph name="LINK_END" /></translation>
@@ -4323,7 +4327,7 @@
 <translation id="5707185214361380026">இதிலிருந்து நீட்டிப்பை ஏற்றுவதில் தோல்வி:</translation>
 <translation id="5708171344853220004">Microsoft Principal பெயர்</translation>
 <translation id="5709557627224531708">Chromeமை உங்கள் இயல்பு உலாவியாக அமைக்கவும்</translation>
-<translation id="5711983031544731014">திறக்க முடியவில்லை. கடவுச்சொல்லை உள்ளிடவும்.</translation>
+<translation id="5711983031544731014">அன்லாக் செய்ய முடியவில்லை. கடவுச்சொல்லை உள்ளிடவும்.</translation>
 <translation id="5712153969432126546">சிலசமயம் ஆவணங்கள், ஒப்பந்தங்கள், படிவங்கள் போன்ற PDFகளை தளங்கள் வெளியிடும்</translation>
 <translation id="5715711091495208045">செருகுநிரல் புரோக்கர்: <ph name="PLUGIN_NAME" /></translation>
 <translation id="5719603411793408026">இயல்புநிலை தேடல் இன்ஜின்கள்</translation>
@@ -4498,7 +4502,7 @@
     <ph name="LINE_BREAK" />
     இந்தப் படம் Chromebookகின் உள்நுழைவுத் திரையிலும் பூட்டுத் திரையிலும் காண்பிக்கப்படும்.</translation>
 <translation id="5925147183566400388">சான்றிதழ் பயிற்சி அறிக்கை சுட்டி</translation>
-<translation id="592880897588170157">தானாக Chromeமில் திறப்பதற்குப் பதிலாக, PDF கோப்புகளைப் பதிவிறக்கவும்</translation>
+<translation id="592880897588170157">தானாக Chromeமில் திறப்பதற்குப் பதிலாக, PDF ஃபைல்களைப் பதிவிறக்கவும்</translation>
 <translation id="5931146425219109062">நீங்கள் பார்வையிடும் இணையதளங்களில் உள்ள உங்கள் எல்லா தரவையும் படிக்கலாம் மற்றும் திருத்தலாம்</translation>
 <translation id="5932124097031739492">Linux மேம்படுத்தப்பட்டது.</translation>
 <translation id="5932224571077948991">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களை தளம் காண்பிக்கிறது</translation>
@@ -4745,7 +4749,7 @@
 <translation id="6196854373336333322">"<ph name="EXTENSION_NAME" />" நீட்டிப்பு உங்கள் ப்ராக்ஸி அமைப்புகளைக் கட்டுப்படுத்துகிறது, அதாவது நீங்கள் ஆன்லைனில் செய்யும் எல்லாவற்றையும் அதனால் மாற்ற முடியும், தடுக்க முடியும் அல்லது அறிந்து கொள்ள முடியும். இது ஏன் நடந்தது எனத் தெரியவில்லை எனில், உங்களுக்கு இந்த தேவைப்படாதது என்று அர்த்தம்.</translation>
 <translation id="6198102561359457428">வெளியேறி பிறகு மீண்டும் உள்நுழைக...</translation>
 <translation id="6198252989419008588">PIN ஐ மாற்றவும்</translation>
-<translation id="6202304368170870640">உங்கள் சாதனத்தில் உள்நுழைய அல்லது அதைத் திறக்க, உங்கள் பின்னைப் பயன்படுத்தலாம்.</translation>
+<translation id="6202304368170870640">உங்கள் சாதனத்தில் உள்நுழைய அல்லது அதை அன்லாக் செய்ய, உங்கள் பின்னைப் பயன்படுத்தலாம்.</translation>
 <translation id="6206311232642889873">படத்தை நகலெ&amp;டு</translation>
 <translation id="6207200176136643843">இயல்பான அளவிற்கு மீட்டமைக்கும்</translation>
 <translation id="6207937957461833379">நாடு/பிராந்தியம்</translation>
@@ -5378,7 +5382,7 @@
 <translation id="6904655473976120856">வெளியேற, பயன்பாட்டுப் பொத்தானை அழுத்தவும்</translation>
 <translation id="6909422577741440844">இந்தச் சாதனத்திலிருந்து பெறவா?</translation>
 <translation id="6910211073230771657">நீக்கப்பட்டது</translation>
-<translation id="691024665142758461">பல கோப்புகளைப் பதிவிறக்குதல்</translation>
+<translation id="691024665142758461">பல ஃபைல்களைப் பதிவிறக்குதல்</translation>
 <translation id="691106080621596509"><ph name="SITE_GROUP_NAME" />, அதன் கீழுள்ள தளங்கள், அதனால் நிறுவப்பட்ட ஆப்ஸ் ஆகியவற்றால் சேமிக்கப்பட்ட அனைத்துத் தரவையும் குக்கீகளையும் இது அழிக்கும்</translation>
 <translation id="6911324888870229398">நெட்வொர்க் இணைப்பு துண்டிக்கப்பட்டது. இணைப்பைச் சரிபார்க்கவும் அல்லது வேறொரு வைஃபை நெட்வொர்க்குடன் இணைக்கவும்.</translation>
 <translation id="6911734910326569517">நினைவகப் பயன்பாடு</translation>
@@ -5474,7 +5478,7 @@
 <translation id="7002055706763150362">Chromebookக்கான Smart Lockஐ அமைக்க, இது நீங்கள் தான் என்பதை Google உறுதிப்படுத்த வேண்டும்—தொடங்க, கடவுச்சொல்லை உள்ளிடவும்.</translation>
 <translation id="7003339318920871147">வலை தரவுத்தளங்கள்</translation>
 <translation id="7003454175711353260">{COUNT,plural, =1{{COUNT} கோப்பு}other{{COUNT} கோப்புகள்}}</translation>
-<translation id="7003723821785740825">சாதனத்தை விரைவாகத் திறப்பதற்கான வழியை அமைக்கவும்</translation>
+<translation id="7003723821785740825">சாதனத்தை விரைவாக அன்லாக் செய்வதற்கான வழியை அமைக்கவும்</translation>
 <translation id="7003844668372540529"><ph name="VENDOR_NAME" /> அனுப்பிய <ph name="PRODUCT_ID" /> தயாரிப்பை அறிய முடியவில்லை</translation>
 <translation id="7004402701596653846">தளத்தால் MIDIயைப் பயன்படுத்த முடியும்</translation>
 <translation id="7004499039102548441">சமீபத்திய தாவல்கள்</translation>
@@ -5640,7 +5644,7 @@
 <translation id="7200083590239651963">உள்ளமைவைத் தேர்ந்தெடுக்கவும்</translation>
 <translation id="720110658997053098">இந்தச் சாதனத்தை, கியோஸ்க் பயன்முறையில் நிரந்தரமாக வைத்திரு</translation>
 <translation id="7201118060536064622">'<ph name="DELETED_ITEM_NAME" />' நீக்கப்பட்டது</translation>
-<translation id="7201420661433230412">கோப்புகளைப் பார்</translation>
+<translation id="7201420661433230412">ஃபைல்களைப் பார்</translation>
 <translation id="7203150201908454328">விரிவாக்கப்பட்டது</translation>
 <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ஐப் பதிவிறக்குகிறது...</translation>
 <translation id="720715819012336933">{NUM_PAGES,plural, =1{பக்கத்திலிருந்து வெளியேறு}other{பக்கங்களிலிருந்து வெளியேறு}}</translation>
@@ -5662,6 +5666,7 @@
 <translation id="7225179976675429563">நெட்வொர்க் வகை இல்லை</translation>
 <translation id="7228479291753472782">புவி இருப்பிடம், மைக்ரோஃபோன், கேமரா போன்ற அம்சங்களை, இணையதளங்கள் பயன்படுத்தலாமா வேண்டாமா என்பதைக் குறிக்கும் அமைப்புகளை மாற்றலாம்.</translation>
 <translation id="7228523857728654909">திரைப் பூட்டு மற்றும் உள்நுழைவு</translation>
+<translation id="7230222852462421043">&amp;சாளரத்தை மீட்டெடு</translation>
 <translation id="7230787553283372882">உரை அளவைத் தனிப்பயனாக்கலாம்</translation>
 <translation id="7232750842195536390">பெயரை மாற்ற முடியவில்லை</translation>
 <translation id="7234010996000898150">Linux மீட்டமைப்பது ரத்துசெய்யப்படுகிறது</translation>
@@ -5874,7 +5879,7 @@
 <translation id="7458168200501453431">Google தேடலில் பயன்படுத்தப்படும் அதே பிழைத்திருத்தியைப் பயன்படுத்தும். உலாவியில் நீங்கள் உள்ளிடும் உரை Googleளுக்கு அனுப்பப்படும்.</translation>
 <translation id="7460045493116006516">தற்போது நிறுவியுள்ள தீம்</translation>
 <translation id="7461924472993315131">நிலையாக வை</translation>
-<translation id="746216226901520237">அடுத்த முறை, உங்கள் ஃபோன் <ph name="DEVICE_TYPE" /> சாதனத்தைத் திறக்கும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
+<translation id="746216226901520237">அடுத்த முறை, உங்கள் ஃபோன் <ph name="DEVICE_TYPE" /> சாதனத்தை அன்லாக் செய்யும். அமைப்புகளில் Smart Lockகை முடக்கலாம்.</translation>
 <translation id="7465522323587461835">{NUM_OPEN_TABS,plural, =1{# தாவல் பட்டையை நிலைமாற்ற தாவலைத் திறந்து, அழுத்தவும்}other{# தாவல் பட்டையை நிலைமாற்ற தாவல்களைத் திறந்து, அழுத்தவும்}}</translation>
 <translation id="7465635034594602553">ஏதோ தவறாகிவிட்டது. சில நிமிடங்கள் கழித்து <ph name="APP_NAME" /> ஆப்ஸை மீண்டும் இயக்கவும்.</translation>
 <translation id="7465778193084373987">Netscape சான்றிதழ் தளர்த்தல் URL</translation>
@@ -5990,7 +5995,7 @@
 <translation id="7582582252461552277">இந்த நெட்வொர்க்குக்கு முன்னுரிமை வழங்குக</translation>
 <translation id="7582844466922312471">மொபைல் தரவு</translation>
 <translation id="7583948862126372804">எண்ணிக்கை</translation>
-<translation id="7586051298768394542">பேச்சு அறிதல் அம்சத்திற்கான கோப்புகளைப் பதிவிறக்க முடியவில்லை. நீங்கள் கூறுவதை Googleளுக்கு அனுப்புவதன் மூலம், சொல்வதை எழுதும் அம்சம் தொடர்ந்து செயல்படும்.</translation>
+<translation id="7586051298768394542">பேச்சு அறிதல் அம்சத்திற்கான ஃபைல்களைப் பதிவிறக்க முடியவில்லை. நீங்கள் கூறுவதை Googleளுக்கு அனுப்புவதன் மூலம், சொல்வதை எழுதும் அம்சம் தொடர்ந்து செயல்படும்.</translation>
 <translation id="7586498138629385861">Chrome ஆப்ஸ் திறக்கப்பட்டிருக்கும்போதும், Chrome தொடர்ந்து இயங்கும்.</translation>
 <translation id="7589461650300748890">கவனமாக இருக்கவும்.</translation>
 <translation id="7593653750169415785">நீங்கள் சில தடவை அறிவிப்புகளை நிராகரித்து விட்டதால் தானாகவே தடுக்கப்பட்டது</translation>
@@ -6044,7 +6049,7 @@
 <translation id="7641513591566880111">புதிய சுயவிவரப் பெயர்</translation>
 <translation id="7642778300616172920">பாதுகாக்க வேண்டிய உள்ளடக்கத்தை மறை</translation>
 <translation id="7643842463591647490">{0,plural, =1{# சாளரம் திறக்கப்பட்டுள்ளது}other{# சாளரங்கள் திறக்கப்பட்டுள்ளன}}</translation>
-<translation id="7643932971554933646">கோப்புகளைப் பார்க்க வலைத்தளத்தை அனுமதிக்கவா?</translation>
+<translation id="7643932971554933646">ஃபைல்களைப் பார்க்க வலைத்தளத்தை அனுமதிக்கவா?</translation>
 <translation id="7644543211198159466">வண்ணமும் தீமும்</translation>
 <translation id="7645176681409127223"><ph name="USER_NAME" /> (உரிமையாளர்)</translation>
 <translation id="7645681574855902035">Linux காப்புப் பிரதியை ரத்துசெய்கிறது</translation>
@@ -6180,7 +6185,7 @@
 <translation id="7774365994322694683">பறவை</translation>
 <translation id="7774792847912242537">அளவுக்கு அதிகமான கோரிக்கைகள்.</translation>
 <translation id="7775694664330414886">தாவல் பெயரிடப்படாத இந்தக் குழுவிற்கு நகர்த்தப்பட்டது - <ph name="GROUP_CONTENTS" /></translation>
-<translation id="7776156998370251340">இந்தத் தளத்தின் தாவல்கள் அனைத்தையும் மூடும் வரை <ph name="ORIGIN" /> தளத்தால் <ph name="FOLDERNAME" /> இல் உள்ள கோப்புகளைப் பார்க்க முடியும்</translation>
+<translation id="7776156998370251340">இந்தத் தளத்தின் தாவல்கள் அனைத்தையும் மூடும் வரை <ph name="ORIGIN" /> தளத்தால் <ph name="FOLDERNAME" /> இல் உள்ள ஃபைல்களைப் பார்க்க முடியும்</translation>
 <translation id="7776701556330691704">குரல்கள் எதுவும் இல்லை</translation>
 <translation id="7781335840981796660">எல்லா பயனர்களின் கணக்குகளும், அகத் தரவும் அகற்றப்படும்.</translation>
 <translation id="7782102568078991263">Google இலிருந்து மேலும் பரிந்துரைகள் இல்லை</translation>
@@ -6271,12 +6276,14 @@
 <translation id="7853747251428735">மேலும் கருவி&amp;கள்</translation>
 <translation id="7855678561139483478">தாவலை புதிய சாளரத்திற்கு நகர்த்து</translation>
 <translation id="7857093393627376423">சொல் பரிந்துரைகள்</translation>
+<translation id="7857675386615530425">Google Lens மூலம் பக்கத்தின் ஒரு பகுதியைத் தேடு</translation>
 <translation id="7857949311770343000">இந்தப் புதிய தாவல் பக்கத்தைத்தான் எதிர்பார்த்தீர்களா?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">சேவை: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;பதிவிறக்கங்கள்</translation>
 <translation id="7861846108263890455">Google கணக்கின் மொழி</translation>
 <translation id="7864539943188674973">புளூடூத்தை முடக்கு</translation>
+<translation id="7866230141401327032">Google Lens மூலம் பக்கத்தின் ஒரு பகுதியைத் தேடு</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - இணைக்கப்பட்டது</translation>
 <translation id="7870730066603611552">அமைவைத் தொடர்ந்து, ஒத்திசைவு விருப்பங்களை மதிப்பாய்வு செய்யவும்</translation>
 <translation id="7870790288828963061">புதிய பதிப்பு கொண்ட கியாஸ்க் ஆப்ஸ் எதுவும் காணப்படவில்லை. புதுப்பிக்க எதுவுமில்லை. USB சாதனத்தை அகற்றவும்.</translation>
@@ -6380,7 +6387,7 @@
 <translation id="7970882136539140748">கார்டு விவரங்களைத் தற்போது சேமிக்க இயலாது</translation>
 <translation id="7972714317346275248">RSA என்க்ரிப்ஷனுடன் PKCS #1 SHA-384</translation>
 <translation id="7973776233567882054">பின்வருபவற்றில் எது உங்கள் நெட்வொர்க் குறித்துச் சரியாக விவரிக்கிறது?</translation>
-<translation id="797394244396603170">கோப்புகளைப் பகிர விரும்பும் சாதனத்தைத் தேர்ந்தெடுங்கள்</translation>
+<translation id="797394244396603170">ஃபைல்களைப் பகிர விரும்பும் சாதனத்தைத் தேர்ந்தெடுங்கள்</translation>
 <translation id="7974566588408714340"><ph name="EXTENSIONNAME" />ஐப் பயன்படுத்த முயற்சி</translation>
 <translation id="7974713334845253259">இயல்பு வண்ணம்</translation>
 <translation id="7974936243149753750">ஓவர்ஸ்கேன்</translation>
@@ -6828,7 +6835,7 @@
 <translation id="8477241577829954800">இடமாற்றப்பட்டது</translation>
 <translation id="8477384620836102176">&amp;பொது</translation>
 <translation id="8479176401914456949">தவறான குறியீடு. மீண்டும் முயலவும்.</translation>
-<translation id="8480082892550707549">இந்தத் தளத்திலிருந்து ஏற்கனவே கோப்புகளைப் பதிவிறக்கியிருந்தாலும், அது தற்காலிகமாகப் பாதுகாப்பற்றதாக இருக்கக்கூடும் (ஹேக் செய்யப்பட்டிருக்கலாம்). இந்த ஃபைலைப் பின்னர் பதிவிறக்கவும்.</translation>
+<translation id="8480082892550707549">இந்தத் தளத்திலிருந்து ஏற்கனவே ஃபைல்களைப் பதிவிறக்கியிருந்தாலும், அது தற்காலிகமாகப் பாதுகாப்பற்றதாக இருக்கக்கூடும் (ஹேக் செய்யப்பட்டிருக்கலாம்). இந்த ஃபைலைப் பின்னர் பதிவிறக்கவும்.</translation>
 <translation id="8480869669560681089"><ph name="VENDOR_NAME" /> இடமிருந்து தெரியாத சாதனம்</translation>
 <translation id="8481187309597259238">USB அனுமதியை உறுதிப்படுத்தவும்</translation>
 <translation id="8481980314595922412">சோதனையிலுள்ள அம்சங்கள் இயக்கப்பட்டுள்ளன</translation>
@@ -6853,6 +6860,7 @@
 <translation id="850875081535031620">தீங்கிழைக்கும் மென்பொருள் இல்லை</translation>
 <translation id="8509177919508253835">பாதுகாப்பு விசைகளை ரீசெட் செய்து பின்களை உருவாக்கலாம்</translation>
 <translation id="8509646642152301857">எழுத்துப் பிழை சரிபார்ப்பு அகராதியைப் பதிவிறக்குவதில் தோல்வி.</translation>
+<translation id="8509967119010808787">பக்கங்களைத் தேட இங்கே கிளிக் செய்யுங்கள்</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{வலுவற்ற கடவுச்சொற்கள் இல்லை}=1{வலுவற்ற {COUNT} கடவுச்சொல் உள்ளது}other{வலுவற்ற {COUNT} கடவுச்சொற்கள் உள்ளன}}</translation>
 <translation id="8512476990829870887">செயலாக்கத்தை முடி</translation>
 <translation id="851263357009351303"><ph name="HOST" /> ஐ படங்களைக் காண்பிக்க எப்போதும் அனுமதி</translation>
@@ -7065,7 +7073,7 @@
 <translation id="8741944563400125534">சுவிட்ச் அணுகலை அமைப்பதற்கான வழிகாட்டி</translation>
 <translation id="8742998548129056176">உங்கள் சாதனம் மற்றும் இதை நீங்கள் பயன்படுத்தும் விதம் (பேட்டரியின் அளவு, சிஸ்டம் மற்றும் ஆப்ஸ் செயல்பாடு மற்றும் பிழைகள் போன்றவை) குறித்த பொதுவான தகவல் இது. Androidடை மேம்படுத்த இந்தத் தரவு பயன்படுத்தப்படும். மேலும், Google ஆப்ஸுக்கும் Android டெவலப்பர்கள் போன்ற கூட்டாளர்கள் தங்களின் ஆப்ஸ் மற்றும் தயாரிப்புகளைச் சிறப்பாக அமைக்கவும் ஒருங்கிணைக்கப்பட்ட சில தகவல்களும் உதவும்.</translation>
 <translation id="8746654918629346731">ஏற்கனவே "<ph name="EXTENSION_NAME" />" ஐக் கோரியுள்ளீர்கள்</translation>
-<translation id="874689135111202667">{0,plural, =1{இந்தத் தளத்தில் ஒரு கோப்பைப் பதிவேற்றவா?}other{இந்தத் தளத்தில் # கோப்புகளைப் பதிவேற்றவா?}}</translation>
+<translation id="874689135111202667">{0,plural, =1{இந்தத் தளத்தில் ஒரு கோப்பைப் பதிவேற்றவா?}other{இந்தத் தளத்தில் # ஃபைல்களைப் பதிவேற்றவா?}}</translation>
 <translation id="8749805710397399240">உங்கள் திரையை அலைபரப்ப முடியவில்லை. சிஸ்டம் விருப்பத்தேர்வில் ஸ்க்ரீன் ரெக்கார்டிங் அனுமதியைச் சரிபார்க்கவும்.</translation>
 <translation id="8749826920799243530">சாதனம் பதிவுசெய்யப்படவில்லை</translation>
 <translation id="8749863574775030885">அறியப்படாத விற்பனையாளரிடமிருந்து USB சாதனங்களை அணுகு</translation>
@@ -7529,7 +7537,7 @@
 <translation id="934503638756687833">தேவைப்பட்டால், இங்கே பட்டியலிடப்படாத உருப்படிகளும் அகற்றப்படும். Chrome தனியுரிமைத் தகவல் கையேட்டில் &lt;a href="<ph name="URL" />"&gt;தேவையற்ற மென்பொருளிலிருந்து பாதுகாப்பு&lt;/a&gt; பற்றி மேலும் அறிக.</translation>
 <translation id="93480724622239549">சிக்கல் அல்லது பிழை</translation>
 <translation id="935490618240037774">புத்தகக்குறிகள், வரலாறு, கடவுச்சொற்கள் மற்றும் பிற அமைப்புகள் உங்கள் Google கணக்குடன் ஒத்திசைக்கப்படும் என்பதால் அவற்றை எல்லா சாதனங்களிலும் பயன்படுத்தலாம்.</translation>
-<translation id="935854577147268200">Smart Lock மொபைல் மாற்றப்பட்டது. Smart Lockகைப் புதுப்பிக்க, கடவுச்சொல்லை உள்ளிடவும். அடுத்த முறை, உங்கள் மொபைலானது <ph name="DEVICE_TYPE" /> சாதனத்தைத் திறக்கும். அமைப்புகளுக்குச் சென்று, Smart Lockகை முடக்கலாம்</translation>
+<translation id="935854577147268200">Smart Lock மொபைல் மாற்றப்பட்டது. Smart Lockகைப் புதுப்பிக்க, கடவுச்சொல்லை உள்ளிடவும். அடுத்த முறை, உங்கள் மொபைலானது <ph name="DEVICE_TYPE" /> சாதனத்தை அன்லாக் செய்யும். அமைப்புகளுக்குச் சென்று, Smart Lockகை முடக்கலாம்</translation>
 <translation id="93610034168535821">தளங்கள் பயன்படுத்தும் மொத்தச் சேமிப்பகம்:</translation>
 <translation id="936646668635477464">கேமரா &amp; மைக்ரோஃபோன்</translation>
 <translation id="936801553271523408">முறைமை பகுப்பாய்வு தரவு</translation>
@@ -7537,7 +7545,7 @@
 <translation id="939252827960237676">ஸ்கிரீன் ஷாட்டை சேமிப்பதில் தோல்வி</translation>
 <translation id="939598580284253335">கடவுச்சொற்றொடரை உள்ளிடுக</translation>
 <translation id="939736085109172342">புதிய கோப்புறை</translation>
-<translation id="941070664607309480">உங்கள் சாதனத்தை அது கண்டறிந்து கோப்புகளைப் பகிர கிளிக் செய்க</translation>
+<translation id="941070664607309480">உங்கள் சாதனத்தை அது கண்டறிந்து ஃபைல்களைப் பகிர கிளிக் செய்க</translation>
 <translation id="942532530371314860">Chrome தாவலையும் ஆடியோவையும் <ph name="APP_NAME" /> பகிர்கிறது.</translation>
 <translation id="945522503751344254">கருத்தை அனுப்பு</translation>
 <translation id="947329552760389097">&amp;கூறுகளை ஆய்வு செய்</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb
index 39bc21a..2858d4ea 100644
--- a/chrome/app/resources/generated_resources_te.xtb
+++ b/chrome/app/resources/generated_resources_te.xtb
@@ -466,6 +466,7 @@
 <translation id="1507246803636407672">&amp;వదిలివేయి</translation>
 <translation id="1508491105858779599">పరికరాన్ని అన్‌లాక్ చేయడానికి వేలిముద్ర సెన్సార్‌పై మీ వేలిని ఉంచండి.</translation>
 <translation id="1508575541972276599">ప్రస్తుత వెర్షన్ Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">&amp;గ్రూప్‌ను రీస్టోర్ చేయండి</translation>
 <translation id="1509281256533087115">ఏ <ph name="DEVICE_NAME_AND_VENDOR" />ని అయినా USB ద్వారా యాక్సెస్ చేయడానికి అనుమతి</translation>
 <translation id="1509960214886564027">చాలా సైట్‌లలోని ఫీచర్‌లు పని చేయకుండాపోవచ్చు</translation>
 <translation id="1510238584712386396">లాంచర్</translation>
@@ -588,6 +589,7 @@
 <translation id="1627408615528139100">ఇప్పటికే డౌన్‌లోడ్ చేయబడింది</translation>
 <translation id="1628948239858170093">తెరవడానికి ముందు ఫైల్‌ను స్కాన్ చేయాలా?</translation>
 <translation id="1629314197035607094">పాస్‌వర్డ్ గడువు ముగిసింది</translation>
+<translation id="1629451755632656601">మీ కార్ట్‌లలో వ్యక్తిగతీకరించబడిన డిస్కౌంట్‌లను కనుగొనడానికి Googleను అనుమతించాలా?</translation>
 <translation id="1630300831289687074">త్వరలోనే మీరు మీ Chromebookను ఉపయోగించగలుగుతారు.</translation>
 <translation id="163072119192489970">డేటాను పంపడాన్ని, అలాగే అందుకోవడాన్ని పూర్తి చేయడానికి అనుమతించబడింది</translation>
 <translation id="1630768113285622200">రీస్టార్ట్ చేసి, కొనసాగించు</translation>
@@ -1304,6 +1306,7 @@
 <translation id="236117173274098341">ఆప్టిమైజ్ చేయండి</translation>
 <translation id="2361340419970998028">ఫీడ్‌బ్యాక్‌ను పంపుతోంది...</translation>
 <translation id="236141728043665931">ఎల్లప్పుడూ మైక్రోఫోన్ యాక్సెస్‌ను బ్లాక్ చేయి</translation>
+<translation id="2363744066037724557">&amp;విండోను రీస్టోర్ చేయండి</translation>
 <translation id="2364498172489649528">ఆమోదించినవి</translation>
 <translation id="2365507699358342471">క్లిప్‌బోర్డ్‌కు కాపీ చేసిన వచనం మరియు చిత్రాలను ఈ సైట్ చూడగలదు.</translation>
 <translation id="2367972762794486313">అనువర్తనాలను చూపు</translation>
@@ -2687,6 +2690,7 @@
 <translation id="3857807444929313943">పైకి ఎత్తి, మళ్లీ తాకండి</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" యూజర్‌నేమ్ అందుబాటులో లేదు</translation>
 <translation id="3861977424605124250">ప్రారంభంలో చూపించు</translation>
+<translation id="386239283124269513">&amp;గ్రూప్‌ను రీస్టోర్ చేయండి</translation>
 <translation id="3862788408946266506">'kiosk_only' మానిఫెస్ట్ ఫీచర్ ఉన్న యాప్‌ను తప్పనిసరిగా Chrome OS కియోస్క్ మోడ్‌లో ఇన్‌స్టాల్ చేయాలి</translation>
 <translation id="3865414814144988605">రిజల్యూషన్</translation>
 <translation id="3866249974567520381">వివరణ</translation>
@@ -5663,6 +5667,7 @@
 <translation id="7225179976675429563">నెట్‌వర్క్ రకం లేదు</translation>
 <translation id="7228479291753472782">వెబ్‌సైట్‌లు భౌగోళికస్థానం, మైక్రోఫోన్, కెమెరా మొదలైనటువంటి లక్షణాలను ఉపయోగించవచ్చా లేదా అనేది పేర్కొనే సెట్టింగ్‌లను సవరించండి</translation>
 <translation id="7228523857728654909">స్క్రీన్ లాక్ మరియు సైన్ ఇన్</translation>
+<translation id="7230222852462421043">&amp;విండోను రీస్టోర్ చేయండి</translation>
 <translation id="7230787553283372882">మీ వచన పరిమాణాన్ని అనుకూలీకరించండి</translation>
 <translation id="7232750842195536390">పేరు మార్చడం విఫలమైంది</translation>
 <translation id="7234010996000898150">Linux పునరుద్ధరణను రద్దు చేస్తోంది</translation>
@@ -6271,12 +6276,14 @@
 <translation id="7853747251428735">మరిన్ని సాధనా&amp;లు</translation>
 <translation id="7855678561139483478">ట్యాబ్‌ను కొత్త విండోకు తరలించు</translation>
 <translation id="7857093393627376423">టెక్స్ట్ సూచనలు</translation>
+<translation id="7857675386615530425">Google Lens సహాయంతో పేజీలోని భాగాన్ని సెర్చ్ చేయండి</translation>
 <translation id="7857949311770343000">మీరు ఆశిస్తున్న కొత్త ట్యాబ్ పేజీ ఇదేనా?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (విండోలు)</translation>
 <translation id="786073089922909430">సేవ: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;డౌన్‌లోడ్‌లు</translation>
 <translation id="7861846108263890455">Google ఖాతా భాష</translation>
 <translation id="7864539943188674973">Bluetoothని నిలిపివేయి</translation>
+<translation id="7866230141401327032">Google Lens సహాయంతో పేజీలోని భాగాన్ని సెర్చ్ చేయండి</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - జత చేయబడింది</translation>
 <translation id="7870730066603611552">సెటప్ చేసిన తర్వాత సింక్ ఎంపికలను రివ్యూ చేయండి</translation>
 <translation id="7870790288828963061">సరికొత్త వెర్షన్ అందుబాటులో ఉన్న కియోస్క్ యాప్‌లేవీ కనుగొనబడలేదు. అప్‌డేట్ చేయడానికి ఏదీ లేదు. దయచేసి USB స్టిక్‌ను తీసివేయండి.</translation>
@@ -6850,6 +6857,7 @@
 <translation id="850875081535031620">హానికరమైన సాఫ్ట్‌వేర్ కనుగొనబడలేదు</translation>
 <translation id="8509177919508253835">సెక్యూరిటీ కీలు రీసెట్ చేసి, పిన్‌లను సృష్టించండి</translation>
 <translation id="8509646642152301857">స్పెల్ చెక్ తనిఖీ నిఘంటువును డౌన్‌లోడ్ చేయడం విఫలమైంది.</translation>
+<translation id="8509967119010808787">మీ ట్యాబ్‌లను సెర్చ్ చేయడానికి, ఇక్కడ క్లిక్ చేయండి</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{బలహీనమైన పాస్‌వర్డ్‌లు ఏవీ కనుగొనబడలేదు}=1{{COUNT} బలహీనమైన పాస్‌వర్డ్ కనుగొనబడింది}other{{COUNT} బలహీనమైన పాస్‌వర్డ్‌లు కనుగొనబడ్డాయి}}</translation>
 <translation id="8512476990829870887">ప్రాసెస్‌ని ముగించు</translation>
 <translation id="851263357009351303">చిత్రాలను చూపించడానికి ఎల్లప్పుడూ <ph name="HOST" />ను అనుమతించు</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb
index dccce31..e354712 100644
--- a/chrome/app/resources/generated_resources_ur.xtb
+++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">&amp;مسترد کریں</translation>
 <translation id="1508491105858779599">آلہ غیر مقفل کرنے کیلئے اپنی انگلی کو فنگرپرنٹ سینسر پر رکھیں۔</translation>
 <translation id="1508575541972276599">‏موجودہ ورژن Debian 9 ‏(Stretch)‏ ہے‪</translation>
+<translation id="1509163368529404530">&amp;گروپ بحال کریں</translation>
 <translation id="1509281256533087115">‏USB کے ذریعے کسی بھی <ph name="DEVICE_NAME_AND_VENDOR" /> تک رسائی حاصل کریں</translation>
 <translation id="1509960214886564027">بہت سی سائٹس پر خصوصیات میں خلل ہو سکتا ہے</translation>
 <translation id="1510238584712386396">لانچر</translation>
@@ -585,6 +586,7 @@
 <translation id="1627408615528139100">پہلے ہی ڈاؤن لوڈ کردہ ہے</translation>
 <translation id="1628948239858170093">کھولنے سے پہلے فائل کو اسکین کریں؟</translation>
 <translation id="1629314197035607094">پاس ورڈ کی میعاد ختم ہو گئی</translation>
+<translation id="1629451755632656601">‏Google کو آپ کی کارٹس میں ذاتی نوعیت کی رعایتیں تلاش کرنے دیں؟</translation>
 <translation id="1630300831289687074">‏آپ جلد ہی اپنا Chromebook استعمال کر پائیں گے۔</translation>
 <translation id="163072119192489970">ڈیٹا بھیجنے اور موصول کرنے کو مکمل کرنے کی اجازت ہے</translation>
 <translation id="1630768113285622200">ری سٹارٹ کریں اور جاری رکھیں</translation>
@@ -1290,6 +1292,7 @@
 <translation id="236117173274098341">بہتر بنائیں</translation>
 <translation id="2361340419970998028">تاثرات بھیج رہا ہے…</translation>
 <translation id="236141728043665931">مائیکروفون رسائی کو ہمیشہ مسدود کریں</translation>
+<translation id="2363744066037724557">&amp;ونڈو بحال کریں</translation>
 <translation id="2364498172489649528">پاس ہو گیا</translation>
 <translation id="2365507699358342471">یہ سائٹ کلپ بورڈ میں کاپی کردہ متن اور تصاویر دیکھ سکتی ہے۔</translation>
 <translation id="2367972762794486313">ایپس دکھائیں</translation>
@@ -2672,6 +2675,7 @@
 <translation id="3857807444929313943">اٹھائیں، پھر دوبارہ ٹچ کریں</translation>
 <translation id="3861638017150647085">"<ph name="USERNAME" />" صارف نام دستیاب نہیں ہے</translation>
 <translation id="3861977424605124250">اسٹارٹ اپ پر دکھائیں</translation>
+<translation id="386239283124269513">&amp;گروپ بحال کریں</translation>
 <translation id="3862788408946266506">‏'kiosk_only' مینی فیسٹ انتساب والی ایپ کا  Chrome OS کیوسک وضع میں انسٹال ہونا ضروری ہے</translation>
 <translation id="3865414814144988605">ریزولیوشن</translation>
 <translation id="3866249974567520381">تفصیل</translation>
@@ -5647,6 +5651,7 @@
 <translation id="7225179976675429563">نیٹ ورک کی قسم غائب ہے</translation>
 <translation id="7228479291753472782">وہ ترتیبات استعمال کریں جو تعین کرتی ہیں کہ آیا ویب سائٹس جغرافیائی مقام، مائیکروفون، کیمرا وغیرہ جیسی خصوصیات استعمال کر سکتی ہیں۔</translation>
 <translation id="7228523857728654909">اسکرین لاک اور سائن ان</translation>
+<translation id="7230222852462421043">&amp;ونڈو بحال کریں</translation>
 <translation id="7230787553283372882">اپنے متن کے سائز کو حسب ضرورت بنائیں</translation>
 <translation id="7232750842195536390">نام کی تبدییلی ناکام ہو گئی</translation>
 <translation id="7234010996000898150">‏Linux کی بحالی کا عمل منسوخ ہو رہا ہے</translation>
@@ -6257,12 +6262,14 @@
 <translation id="7853747251428735">مزید ٹولز</translation>
 <translation id="7855678561139483478">ٹیب کو نئی ونڈو میں منتقل کریں</translation>
 <translation id="7857093393627376423">متنی تجاویز</translation>
+<translation id="7857675386615530425">‏Google لینز کے ساتھ صفحہ کا حصہ تلاش کریں</translation>
 <translation id="7857949311770343000">کیا یہی وہ نیا ٹیب صفحہ ہے جس کی آپ توقع کر رہے تھے؟</translation>
 <translation id="7858328180167661092">‎<ph name="APP_NAME" /> (Windows)‎</translation>
 <translation id="786073089922909430">سروس: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;ڈاؤن لوڈز</translation>
 <translation id="7861846108263890455">‏Google اکاؤنٹ کی زبان</translation>
 <translation id="7864539943188674973">بلوٹوتھ غیر فعال کریں</translation>
+<translation id="7866230141401327032">‏Google لینز کے ساتھ صفحہ کا حصہ تلاش کریں</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - جوڑا بنایا گیا</translation>
 <translation id="7870730066603611552">سیٹ اپ کے بعد مطابقت پذیری کے اختیارات کا جائزہ لیں</translation>
 <translation id="7870790288828963061">‏نئے ورژن والی کوئی کیوسک ایپس نہیں ملیں۔ اپ ڈیٹ کرنے کیلئے کچھ بھی نہیں ہے۔ براہ کرم USB اسٹک ہٹائیں۔</translation>
@@ -6836,6 +6843,7 @@
 <translation id="850875081535031620">کوئی نقصان دہ سافٹ ویئر نہیں ملا</translation>
 <translation id="8509177919508253835">‏سیکیورٹی کلیدوں کو دوبارہ ترتیب دیں اور PINs تخلیق کریں</translation>
 <translation id="8509646642152301857">املا کی جانچ کی لغت کو ڈاؤن لوڈ کرنا ناکام ہوگیا۔</translation>
+<translation id="8509967119010808787">اپنے ٹیبز کو تلاش کرنے کیلئے یہاں کلک کریں</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{کوئی کمزور پاس ورڈز نہیں ملے}=1{{COUNT} کمزور پاس ورڈ ملا}other{{COUNT} کمزور پاس ورڈز ملے}}</translation>
 <translation id="8512476990829870887">کارروائی ختم کریں</translation>
 <translation id="851263357009351303"><ph name="HOST" /> کو تصاویر دکھانے کی ہمیشہ اجازت دیں</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb
index 8d821ce..e17226c 100644
--- a/chrome/app/resources/generated_resources_uz.xtb
+++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -4382,6 +4382,7 @@
 <translation id="5794700615121138172">Linux umumiy jildlari</translation>
 <translation id="5794786537412027208">Barcha Chrome ilovalarini yopish</translation>
 <translation id="5797070761912323120">Qidiruv, rekama va boshqa xizmatlarni sizga moslashtirish uchun Google tarix maʼlumotlaringizdan foydalanishi mumkin</translation>
+<translation id="5797521893972859201">Qidiruv maydonchasidagi tarixni tozalaydi</translation>
 <translation id="5798079537501238810">Saytlar toʻlov vositalarini oʻrnatishi mumkin</translation>
 <translation id="579907812742603813">himoyalangan kontent</translation>
 <translation id="579915268381781820">Elektron kalitingiz chiqarib olindi.</translation>
@@ -4465,6 +4466,7 @@
 <translation id="5900302528761731119">Google profili rasmi</translation>
 <translation id="590036993063074298">Translatsiya sifati tafsilotlari</translation>
 <translation id="5901069264981746702">Barmoq izlaringiz yaxshi himoya ostida va faqat <ph name="DEVICE_TYPE" /> qurilmangizda saqlanadi. <ph name="LINK_BEGIN" />Batafsil<ph name="LINK_END" /></translation>
+<translation id="5901089233978050985">Yozib olinayotgan varaq</translation>
 <translation id="5901494423252125310">Printer eshikchasi ochiq</translation>
 <translation id="5901630391730855834">Sariq</translation>
 <translation id="5904614460720589786">Sozlashda muammo yuz bergani uchun <ph name="APP_NAME" /> sozlanmadi Administratorga murojaat qiling. Xatolik kodi: <ph name="ERROR_CODE" />.</translation>
@@ -4737,6 +4739,7 @@
 <translation id="6196854373336333322">“<ph name="EXTENSION_NAME" />” kengaytmasi proksi-server sozlamalarini nazorat qiladi. U internetda bajargan ishlaringizni o‘zgartirishi, buzishi yoki bildirmasdan eshitishi mumkin. Agar bu haqda eshitmagan bo‘lsangiz, uni o‘chirib qo‘yganingiz yaxshi.</translation>
 <translation id="6198102561359457428">Chiqish va qaytadan kirish...</translation>
 <translation id="6198252989419008588">PIN-kodni o‘zgartirish</translation>
+<translation id="6200047250927636406">Faylni yopish</translation>
 <translation id="6202304368170870640">Hisobingizga kirish yoki qurilmani ochish uchun PIN koddan foydalanishingiz mumkin.</translation>
 <translation id="6206311232642889873">Tasvirni &amp;nusxalash</translation>
 <translation id="6207200176136643843">Standart masshtab</translation>
@@ -5306,6 +5309,7 @@
 <translation id="6831043979455480757">Tarjima</translation>
 <translation id="6833479554815567477">Varaq <ph name="GROUP_NAME" /> guruhidan olib tashlandi – <ph name="GROUP_CONTENTS" /></translation>
 <translation id="683373380308365518">Qulay va xavfsiz brauzerdan foydalaning</translation>
+<translation id="6834652994408928492">Tungi rejim quyosh botishi bilan avtomatik yoqiladi</translation>
 <translation id="683540480453879381"><ph name="FILE_EXTENSIONS" /> fayllarini ochish</translation>
 <translation id="6835762382653651563"><ph name="DEVICE_TYPE" /> qurilmasini yangilash uchun Internetga ulaning.</translation>
 <translation id="6838034009068684089">Saytlar ekranlarda oynalar ochish va joylashtirishdan oldin ruxsat olsin (tavsiya etiladi)</translation>
@@ -6018,6 +6022,7 @@
 <translation id="7622114377921274169">Quvvat olmoqda.</translation>
 <translation id="7622768823216805500">Saytlar odatda xaridlar vaqtida hisob-kitobni osonlashtirish uchun toʻlov vositalarini oʻrnatadi</translation>
 <translation id="7622903810087708234">Parol tafsilotlari</translation>
+<translation id="7622966771025050155">Yozib olingan varaq</translation>
 <translation id="7624337243375417909">caps lock o‘chiq</translation>
 <translation id="7625568159987162309">Saytlardagi rusatnoma va saytlarning saqlangan ma’lumotlarini ko‘rish</translation>
 <translation id="7628201176665550262">Yangilash chastotasi</translation>
@@ -6184,6 +6189,7 @@
 <translation id="7784067724422331729">Bu fayl kompyuter havfsizlik sozlamasi tomonidan bloklandi.</translation>
 <translation id="7784796923038949829">Sayt axborotini ochish yoki tahrirlash imkonsiz</translation>
 <translation id="778480864305029524">Tezkor modem rejimidan foydalanish uchun Google Play xizmatlari bildirishnomalarini yoqing.</translation>
+<translation id="7785471469930192436">Imkon boʻlsa, qidiruv tarixini qanday tozalash haqidagi qidiruv tizimi koʻrsatmalarini oching</translation>
 <translation id="7786889348652477777">&amp;Ilovani qayta yuklash</translation>
 <translation id="7787308148023287649">Boshqa ekranda ko‘rsatish</translation>
 <translation id="7788298548579301890">Kompyuteringizdagi boshqa dastur brauzeringizga bitta ilova o‘rnatdi. U Chrome brauzerining ishlash usulini o‘zgartirishi mumkin.
@@ -6794,6 +6800,7 @@
 <translation id="8438566539970814960">Sahifalarni kezish va qidiruvni yaxshilash</translation>
 <translation id="8439506636278576865">Bu tildagi sahifalarni tarjima qilish taklif qilinsin</translation>
 <translation id="8440630305826533614">Linux ilovalari</translation>
+<translation id="8446225304314102060">Varaqqa oʻtish: <ph name="TAB_ORIGIN" /></translation>
 <translation id="8446884382197647889">Batafsil</translation>
 <translation id="8447409163267621480">Tugmalar birikmasi Ctrl yoki Alt tugmasi bilan boshlanishi lozim</translation>
 <translation id="8448729345478502352">Ekrandagi elementlarni kichiklashtirish yoki kattalashtirish</translation>
@@ -7455,6 +7462,7 @@
 <translation id="9148058034647219655">To‘liq ekran rejimidan chiqish</translation>
 <translation id="9148126808321036104">Qaytadan kiring</translation>
 <translation id="9148963623915467028">Bu sayt joylashuvingiz axborotidan foydalanishi mumkin.</translation>
+<translation id="9149529198050266366">Tungi rejim quyosh chiqishi bilan avtomatik faolsizlantiriladi</translation>
 <translation id="9149866541089851383">O‘zgartirish...</translation>
 <translation id="9150045010208374699">Kameradan foydalanish</translation>
 <translation id="9150079578948279438">Profil olib tashlanmadi. Qayta urining yoki texnik yordam olish uchun aloqa operatoriga murojaat qiling.</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index f0f5b25..7f50925 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -463,6 +463,7 @@
 <translation id="1507246803636407672">舍弃(&amp;D)</translation>
 <translation id="1508491105858779599">请将手指放在指纹传感器上以解锁设备。</translation>
 <translation id="1508575541972276599">当前所用版本为 Debian 9 (Stretch)</translation>
+<translation id="1509163368529404530">恢复组(&amp;R)</translation>
 <translation id="1509281256533087115">通过 USB 访问任何<ph name="DEVICE_NAME_AND_VENDOR" /></translation>
 <translation id="1509960214886564027">很多网站上的功能可能会无法正常运作</translation>
 <translation id="1510238584712386396">启动器</translation>
@@ -582,6 +583,7 @@
 <translation id="1627408615528139100">已下载</translation>
 <translation id="1628948239858170093">打开前,先扫描文件?</translation>
 <translation id="1629314197035607094">密码已过期</translation>
+<translation id="1629451755632656601">让 Google 查找您购物车中商品的个性化折扣信息?</translation>
 <translation id="1630300831289687074">您很快就能使用 Chromebook 了。</translation>
 <translation id="163072119192489970">允许完成数据收发操作</translation>
 <translation id="1630768113285622200">重启并继续</translation>
@@ -1287,6 +1289,7 @@
 <translation id="236117173274098341">优化</translation>
 <translation id="2361340419970998028">正在发送反馈…</translation>
 <translation id="236141728043665931">始终禁止使用麦克风</translation>
+<translation id="2363744066037724557">恢复窗口(&amp;R)</translation>
 <translation id="2364498172489649528">通过</translation>
 <translation id="2365507699358342471">此页面可以查看复制到剪贴板的文字和图片。</translation>
 <translation id="2367972762794486313">显示应用</translation>
@@ -2669,6 +2672,7 @@
 <translation id="3857807444929313943">移开手指,然后再次触摸传感器</translation>
 <translation id="3861638017150647085">用户名“<ph name="USERNAME" />”不可用</translation>
 <translation id="3861977424605124250">在 Chrome 启动时显示</translation>
+<translation id="386239283124269513">恢复组(&amp;R)</translation>
 <translation id="3862788408946266506">具有“kiosk_only”这项清单属性的应用必须在 Chrome 操作系统自助服务终端模式下进行安装</translation>
 <translation id="3865414814144988605">分辨率</translation>
 <translation id="3866249974567520381">说明</translation>
@@ -5643,6 +5647,7 @@
 <translation id="7225179976675429563">缺少网络类型</translation>
 <translation id="7228479291753472782">管理用于指定网站可否使用地理位置信息、麦克风、摄像头等功能的设置</translation>
 <translation id="7228523857728654909">屏幕锁定和登录</translation>
+<translation id="7230222852462421043">恢复窗口(&amp;R)</translation>
 <translation id="7230787553283372882">自定义文字大小</translation>
 <translation id="7232750842195536390">重命名失败</translation>
 <translation id="7234010996000898150">正在取消 Linux 恢复</translation>
@@ -6252,12 +6257,14 @@
 <translation id="7853747251428735">更多工具(&amp;L)</translation>
 <translation id="7855678561139483478">将标签页移至新窗口</translation>
 <translation id="7857093393627376423">文字建议</translation>
+<translation id="7857675386615530425">使用 Google 智能镜头搜索网页的某个部分</translation>
 <translation id="7857949311770343000">这是您想要的新标签页吗?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">服务:<ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">下载内容(&amp;D)</translation>
 <translation id="7861846108263890455">Google 帐号语言</translation>
 <translation id="7864539943188674973">停用蓝牙</translation>
+<translation id="7866230141401327032">使用 Google 智能镜头搜索网页的某个部分</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - 已配对</translation>
 <translation id="7870730066603611552">完成设置后查看同步选项</translation>
 <translation id="7870790288828963061">找不到自助服务终端应用的更高版本,因此没有要更新的内容。请拔下 U 盘。</translation>
@@ -6833,6 +6840,7 @@
 <translation id="850875081535031620">未发现任何有害软件</translation>
 <translation id="8509177919508253835">重置安全密钥并创建 PIN 码</translation>
 <translation id="8509646642152301857">拼写检查字典下载失败。</translation>
+<translation id="8509967119010808787">如要搜索您的标签页,请点击此处</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{未发现任何安全系数低的密码}=1{发现了 {COUNT} 个安全系数低的密码}other{发现了 {COUNT} 个安全系数低的密码}}</translation>
 <translation id="8512476990829870887">结束进程</translation>
 <translation id="851263357009351303">始终允许 <ph name="HOST" /> 显示图片</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb
index da29ffd..c8b73b3 100644
--- a/chrome/app/resources/generated_resources_zh-HK.xtb
+++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -466,7 +466,7 @@
 <translation id="1507246803636407672">捨棄(&amp;D)</translation>
 <translation id="1508491105858779599">將您的手指放在指紋感應器上即可解鎖裝置。</translation>
 <translation id="1508575541972276599">目前版本為 Debian 9 (Stretch)</translation>
-<translation id="1509163368529404530">還原群組 (&amp;R)</translation>
+<translation id="1509163368529404530">還原群組</translation>
 <translation id="1509281256533087115">使用 USB 存取所有 <ph name="DEVICE_NAME_AND_VENDOR" /></translation>
 <translation id="1509960214886564027">很多網站的功能可能會無法正常運作</translation>
 <translation id="1510238584712386396">啟動器</translation>
@@ -589,7 +589,7 @@
 <translation id="1627408615528139100">已下載</translation>
 <translation id="1628948239858170093">要先掃瞄檔案再開啟嗎?</translation>
 <translation id="1629314197035607094">密碼已過期</translation>
-<translation id="1629451755632656601">要讓 Google 根據購物車中的商品尋找個人專屬折扣嗎?</translation>
+<translation id="1629451755632656601">要讓 Google 為購物車中的項目尋找個人化折扣嗎?</translation>
 <translation id="1630300831289687074">您很快就能使用 Chromebook 了。</translation>
 <translation id="163072119192489970">已允許完成傳送和接收資料</translation>
 <translation id="1630768113285622200">重新啟動及繼續</translation>
@@ -1306,7 +1306,7 @@
 <translation id="236117173274098341">優化</translation>
 <translation id="2361340419970998028">正在傳送意見…</translation>
 <translation id="236141728043665931">永遠封鎖存取麥克風</translation>
-<translation id="2363744066037724557">還原視窗 (&amp;R)</translation>
+<translation id="2363744066037724557">還原視窗</translation>
 <translation id="2364498172489649528">已通過</translation>
 <translation id="2365507699358342471">此網站可以查看複製到剪貼簿的文字和圖片。</translation>
 <translation id="2367972762794486313">顯示應用程式</translation>
@@ -2690,7 +2690,7 @@
 <translation id="3857807444929313943">提起手指,然後再次輕觸</translation>
 <translation id="3861638017150647085">使用者名稱「<ph name="USERNAME" />」無法使用</translation>
 <translation id="3861977424605124250">啟動時顯示</translation>
-<translation id="386239283124269513">還原群組 (&amp;R)</translation>
+<translation id="386239283124269513">還原群組</translation>
 <translation id="3862788408946266506">含有 "kiosk_only" 資訊清單屬性的應用程式只能在 ChromeOS Kiosk 模式中安裝</translation>
 <translation id="3865414814144988605">解像度</translation>
 <translation id="3866249974567520381">描述</translation>
@@ -5667,7 +5667,7 @@
 <translation id="7225179976675429563">找不到網絡類型</translation>
 <translation id="7228479291753472782">控制各種設定,包括指定網站能否使用地理位置、麥克風和相機等功能。</translation>
 <translation id="7228523857728654909">螢幕鎖定和登入</translation>
-<translation id="7230222852462421043">還原視窗 (&amp;R)</translation>
+<translation id="7230222852462421043">還原視窗</translation>
 <translation id="7230787553283372882">自訂文字大小</translation>
 <translation id="7232750842195536390">無法重新命名</translation>
 <translation id="7234010996000898150">正在取消 Linux 還原</translation>
@@ -6277,14 +6277,14 @@
 <translation id="7853747251428735">更多工具(&amp;L)</translation>
 <translation id="7855678561139483478">把分頁移至新視窗</translation>
 <translation id="7857093393627376423">文字建議</translation>
-<translation id="7857675386615530425">使用 Google 智慧鏡頭搜尋頁面上的部分內容</translation>
+<translation id="7857675386615530425">透過「Google 智能鏡頭」搜尋頁面的一部分</translation>
 <translation id="7857949311770343000">這是您想要的新分頁嗎?</translation>
 <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation>
 <translation id="786073089922909430">服務:<ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">下載(&amp;D)</translation>
 <translation id="7861846108263890455">Google 帳戶語言</translation>
 <translation id="7864539943188674973">停用藍牙</translation>
-<translation id="7866230141401327032">使用 Google 智慧鏡頭搜尋頁面上的部分內容</translation>
+<translation id="7866230141401327032">透過「Google 智能鏡頭」搜尋頁面的一部分</translation>
 <translation id="786957569166715433"><ph name="DEVICE_NAME" /> - 已配對</translation>
 <translation id="7870730066603611552">設定後查看同步選項</translation>
 <translation id="7870790288828963061">找不到較新版本的 Kiosk 應用程式,無需更新。請移除 USB 記憶體。</translation>
@@ -6861,7 +6861,7 @@
 <translation id="850875081535031620">未發現任何有害軟件</translation>
 <translation id="8509177919508253835">重設安全密鑰並建立 PIN</translation>
 <translation id="8509646642152301857">拼字檢查字典下載失敗。</translation>
-<translation id="8509967119010808787">如要搜尋分頁,請按這裡</translation>
+<translation id="8509967119010808787">如要搜尋分頁,請按一下這裡</translation>
 <translation id="8512396579636492893">{COUNT,plural, =0{找不到安全性弱的密碼}=1{找到 {COUNT} 個安全性弱的密碼}other{找到 {COUNT} 個安全性弱的密碼}}</translation>
 <translation id="8512476990829870887">結束處理程序</translation>
 <translation id="851263357009351303">永遠允許 <ph name="HOST" /> 顯示圖片</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ta.xtb b/chrome/app/resources/google_chrome_strings_ta.xtb
index 34d26bcc..34a6874 100644
--- a/chrome/app/resources/google_chrome_strings_ta.xtb
+++ b/chrome/app/resources/google_chrome_strings_ta.xtb
@@ -243,7 +243,7 @@
 <translation id="7295052994004373688">Google Chrome UIயைக் காட்ட இந்த மொழி பயன்படுத்தப்படும்</translation>
 <translation id="7296210096911315575">பயன்பாடு மற்றும் பாதுகாப்பு குறித்த முக்கியத் தகவல்</translation>
 <translation id="7303916856901595720">புதிய Chrome சுயவிவரத்திற்குக் கணக்கை நகர்த்தவா?</translation>
-<translation id="7308322188646931570">கோப்புகளைப் பதிவிறக்க Chromeக்குச் சேமிப்பிட அணுகல் தேவை</translation>
+<translation id="7308322188646931570">ஃபைல்களைப் பதிவிறக்க Chromeக்குச் சேமிப்பிட அணுகல் தேவை</translation>
 <translation id="7339898014177206373">புதிய சாளரம்</translation>
 <translation id="7398801000654795464">Chromeல் <ph name="USER_EMAIL_ADDRESS" /> ஆக உள்நுழைந்திருந்தீர்கள். மீண்டும் உள்நுழைய அதே கணக்கைப் பயன்படுத்தவும்.</translation>
 <translation id="7408085963519505752">Chrome OS விதிமுறைகள்</translation>
diff --git a/chrome/app/theme/default_100_percent/common/cloudprint.png b/chrome/app/theme/default_100_percent/common/cloudprint.png
deleted file mode 100644
index 2efbd34a..0000000
--- a/chrome/app/theme/default_100_percent/common/cloudprint.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/cloudprint.png b/chrome/app/theme/default_200_percent/common/cloudprint.png
deleted file mode 100644
index e90bd600..0000000
--- a/chrome/app/theme/default_200_percent/common/cloudprint.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 758f278..ff356b5 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -143,9 +143,6 @@
 
       <structure type="chrome_scaled_image" name="IDR_INPUT_ALERT" file="common/input_alert.png" />
       <structure type="chrome_scaled_image" name="IDR_INPUT_ALERT_MENU" file="common/input_alert_menu.png" />
-      <if expr="enable_service_discovery">
-        <structure type="chrome_scaled_image" name="IDR_LOCAL_DISCOVERY_CLOUDPRINT_ICON" file="common/cloudprint.png" />
-      </if>
       <if expr="not is_android">
         <structure type="chrome_scaled_image" name="IDR_MANAGEMENT_FAVICON" file="common/favicon_management.png" />
         <structure type="chrome_scaled_image" name="IDR_MAXIMIZE_BUTTON_MASK" file="common/maximize_button_mask.png" />
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index f81a1d1..8440204d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1379,8 +1379,6 @@
     "profiles/profile_downloader_delegate.h",
     "profiles/profile_impl.cc",
     "profiles/profile_impl.h",
-    "profiles/profile_info_cache.cc",
-    "profiles/profile_info_cache.h",
     "profiles/profile_info_cache_observer.h",
     "profiles/profile_io_data.cc",
     "profiles/profile_io_data.h",
@@ -1954,7 +1952,6 @@
     "//chrome/browser/ui/webui/downloads:mojo_bindings",
     "//chrome/browser/ui/webui/history_clusters:mojo_bindings",
     "//chrome/browser/ui/webui/internals/user_education:mojo_bindings",
-    "//chrome/browser/ui/webui/internals/web_app:mojo_bindings",
     "//chrome/browser/ui/webui/new_tab_page:mojo_bindings",
     "//chrome/browser/ui/webui/new_tab_page_third_party:mojo_bindings",
     "//chrome/browser/ui/webui/omnibox:mojo_bindings",
@@ -3482,6 +3479,8 @@
       "cart/cart_discount_fetcher.h",
       "cart/cart_discount_link_fetcher.cc",
       "cart/cart_discount_link_fetcher.h",
+      "cart/cart_discount_metric_collector.cc",
+      "cart/cart_discount_metric_collector.h",
       "cart/cart_handler.cc",
       "cart/cart_handler.h",
       "cart/cart_metrics_tracker.cc",
@@ -4276,12 +4275,6 @@
       "//extensions/buildflags",
     ]
 
-    if (is_win || is_mac || is_linux) {
-      sources += []
-
-      deps += []
-    }
-
     if (!is_chromeos_ash) {
       sources += [
         "accessibility/soda_installer_impl.cc",
@@ -6354,10 +6347,6 @@
       "printing/cloud_print/privet_http_impl.h",
       "printing/cloud_print/privet_local_printer_lister.cc",
       "printing/cloud_print/privet_local_printer_lister.h",
-      "printing/cloud_print/privet_notifications.cc",
-      "printing/cloud_print/privet_notifications.h",
-      "printing/cloud_print/privet_notifications_factory.cc",
-      "printing/cloud_print/privet_notifications_factory.h",
       "printing/cloud_print/privet_url_loader.cc",
       "printing/cloud_print/privet_url_loader.h",
     ]
@@ -6850,9 +6839,7 @@
     "//chrome/browser/media:mojo_bindings_js",
     "//chrome/browser/resources/internals/user_education:components",
     "//chrome/browser/resources/local_state:build",
-    "//chrome/browser/resources/web_app_internals:components",
     "//chrome/browser/ui/webui/internals/user_education:mojo_bindings_js",
-    "//chrome/browser/ui/webui/internals/web_app:mojo_bindings_js",
     "//components/site_engagement/core/mojom:mojo_bindings_webui_js",
   ]
   if (is_android) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index eceac25..d400e9a4 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2574,17 +2574,6 @@
          kPlatformProvidedTrustTokenIssuance,
          base::size(kPlatformProvidedTrustTokenIssuance), nullptr}};
 
-const FeatureEntry::FeatureParam kPasswordsAccountStorage_ProfileStore[] = {
-    {password_manager::features::kSaveToProfileStoreByDefault, "true"},
-    {password_manager::features::kSaveToAccountStoreOnOptIn, "true"},
-};
-
-const FeatureEntry::FeatureVariation kPasswordsAccountStorageVariations[] = {
-    {"(save to profile store by default)",
-     kPasswordsAccountStorage_ProfileStore,
-     base::size(kPasswordsAccountStorage_ProfileStore), nullptr},
-};
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr char kWallpaperWebUIInternalName[] = "wallpaper-webui";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -4073,6 +4062,11 @@
      flag_descriptions::kArcImageCopyPasteCompatName,
      flag_descriptions::kArcImageCopyPasteCompatDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(arc::kImageCopyPasteCompatFeature)},
+    {"arc-keyboard-shortcut-helper-integration",
+     flag_descriptions::kArcKeyboardShortcutHelperIntegrationName,
+     flag_descriptions::kArcKeyboardShortcutHelperIntegrationDescription,
+     kOsCrOS,
+     FEATURE_VALUE_TYPE(arc::kKeyboardShortcutHelperIntegrationFeature)},
     {"arc-native-bridge-toggle", flag_descriptions::kArcNativeBridgeToggleName,
      flag_descriptions::kArcNativeBridgeToggleDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(arc::kNativeBridgeToggleFeature)},
@@ -5962,26 +5956,6 @@
      FEATURE_VALUE_TYPE(app_list_features::kEnableSuggestedFiles)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-    {"passwords-account-storage",
-     flag_descriptions::kEnablePasswordsAccountStorageName,
-     flag_descriptions::kEnablePasswordsAccountStorageDescription,
-     kOsWin | kOsMac | kOsLinux,
-     FEATURE_WITH_PARAMS_VALUE_TYPE(
-         password_manager::features::kEnablePasswordsAccountStorage,
-         kPasswordsAccountStorageVariations,
-         "ButterForPasswords")},
-
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS)
-    {"passwords-account-storage-iph",
-     flag_descriptions::kEnablePasswordsAccountStorageIPHName,
-     flag_descriptions::kEnablePasswordsAccountStorageIPHDescription,
-     kOsWin | kOsMac | kOsLinux,
-     FEATURE_VALUE_TYPE(
-         feature_engagement::kIPHPasswordsAccountStorageFeature)},
-#endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
-        // defined(OS_CHROMEOS)
-
     {"autofill-always-return-cloud-tokenized-card",
      flag_descriptions::kAutofillAlwaysReturnCloudTokenizedCardName,
      flag_descriptions::kAutofillAlwaysReturnCloudTokenizedCardDescription,
@@ -6047,6 +6021,13 @@
      FEATURE_VALUE_TYPE(features::kMacCoreLocationImplementation)},
 #endif
 
+#if !defined(OS_ANDROID)
+    {"mute-notification-snooze-action",
+     flag_descriptions::kMuteNotificationSnoozeActionName,
+     flag_descriptions::kMuteNotificationSnoozeActionDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kMuteNotificationSnoozeAction)},
+#endif  // !defined(OS_ANDROID)
+
 #if defined(OS_MAC)
     {"enable-new-mac-notification-api",
      flag_descriptions::kNewMacNotificationAPIName,
@@ -6451,6 +6432,9 @@
      kOsDesktop,
      FEATURE_VALUE_TYPE(
          permissions::features::kPermissionChipRequestTypeSensitive)},
+    {"permission-quiet-chip", flag_descriptions::kPermissionQuietChipName,
+     flag_descriptions::kPermissionQuietChipDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(permissions::features::kPermissionQuietChip)},
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
     {"dice-web-signin-interception",
@@ -6907,12 +6891,6 @@
      FEATURE_VALUE_TYPE(features::kSwipeToMoveCursor)},
 #endif  // defined(OS_ANDROID)
 
-    {"change-password-affiliation",
-     flag_descriptions::kChangePasswordAffiliationInfoName,
-     flag_descriptions::kChangePasswordAffiliationInfoDescription, kOsAll,
-     FEATURE_VALUE_TYPE(
-         password_manager::features::kChangePasswordAffiliationInfo)},
-
     {"use-of-hash-affiliation-fetcher",
      flag_descriptions::kUseOfHashAffiliationFetcherName,
      flag_descriptions::kUseOfHashAffiliationFetcherDescription, kOsAll,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
index a937ca7..eca2a2dd5 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -78,6 +78,7 @@
     flattened.emplace_back(rect.top);
     flattened.emplace_back(rect.right);
     flattened.emplace_back(rect.bottom);
+    flattened.emplace_back(rect.full_width ? 1 : 0);
   }
   return flattened;
 }
diff --git a/chrome/browser/android/browserservices/constants/BUILD.gn b/chrome/browser/android/browserservices/constants/BUILD.gn
new file mode 100644
index 0000000..c193789
--- /dev/null
+++ b/chrome/browser/android/browserservices/constants/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+android_library("java") {
+  deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
+
+  srcjar_deps = [
+    "//chrome/browser/installable:browser_services_enums_srcjar",
+    "//components/webapps/browser/android/webapk:enums_srcjar",
+  ]
+}
diff --git a/chrome/browser/android/browserservices/intents/BUILD.gn b/chrome/browser/android/browserservices/intents/BUILD.gn
index ed4e063a..6b6026a03 100644
--- a/chrome/browser/android/browserservices/intents/BUILD.gn
+++ b/chrome/browser/android/browserservices/intents/BUILD.gn
@@ -22,6 +22,7 @@
   deps = [
     "//base:base_java",
     "//chrome/android/webapk/libs/common:common_java",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/flags:java",
     "//components/webapps/browser/android:java",
     "//content/public/android:content_main_dex_java",
@@ -29,7 +30,6 @@
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_browser_browser_java",
   ]
-  srcjar_deps = [ "//components/webapps/browser/android/webapk:enums_srcjar" ]
 }
 
 android_library("junit") {
@@ -48,6 +48,7 @@
     "//chrome/android/webapk/libs/common:common_java",
     "//chrome/android/webapk/libs/common:splash_java",
     "//chrome/android/webapk/test:junit_test_support",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/test/android:chrome_java_test_support",
     "//components/webapk/android/libs/common:java",
     "//components/webapps/browser/android:java",
diff --git a/chrome/browser/android/explore_sites/import_catalog_task.cc b/chrome/browser/android/explore_sites/import_catalog_task.cc
index cf251db..05b7d1a0 100644
--- a/chrome/browser/android/explore_sites/import_catalog_task.cc
+++ b/chrome/browser/android/explore_sites/import_catalog_task.cc
@@ -99,7 +99,7 @@
     return false;
 
   // Then insert each category.
-  for (auto category : catalog_proto->categories()) {
+  for (const auto& category : catalog_proto->categories()) {
     sql::Statement category_statement(
         db->GetCachedStatement(SQL_FROM_HERE, kInsertCategorySql));
 
@@ -113,8 +113,7 @@
     category_statement.BindString(col++, version_token);
     category_statement.BindInt(col++, static_cast<int>(category.type()));
     category_statement.BindString(col++, category.localized_title());
-    category_statement.BindBlob(col++, category.icon().data(),
-                                category.icon().length());
+    category_statement.BindBlob(col++, category.icon());
     category_statement.BindInt(col++, old_category_info.ntp_click_count);
     category_statement.BindInt(col++, old_category_info.ntp_shown_count);
 
@@ -130,7 +129,7 @@
       site_statement.BindString(col++, site.site_url());
       site_statement.BindInt64(col++, category_id);
       site_statement.BindString(col++, site.title());
-      site_statement.BindBlob(col++, site.icon().data(), site.icon().length());
+      site_statement.BindBlob(col++, site.icon());
 
       site_statement.Run();
     }
diff --git a/chrome/browser/android/metrics/android_session_durations_service.cc b/chrome/browser/android/metrics/android_session_durations_service.cc
index cef5de8..89d3cf9 100644
--- a/chrome/browser/android/metrics/android_session_durations_service.cc
+++ b/chrome/browser/android/metrics/android_session_durations_service.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/android/metrics/android_session_durations_service_factory.h"
 #include "chrome/browser/android/metrics/jni_headers/AndroidSessionDurationsServiceState_jni.h"
 #include "chrome/browser/profiles/profile_android.h"
+#include "chrome/browser/profiles/profile_manager.h"
 
 namespace {
 class IncognitoSessionDurationsMetricsRecorder {
@@ -154,7 +155,10 @@
 void AndroidSessionDurationsService::RestoreIncognitoSession(
     base::Time session_start,
     base::TimeDelta last_reported_duration) {
-  DCHECK(incognito_session_metrics_recorder_);
+  // TODO(https://crbug.com/1226462): Change back to DCHECK after investigation
+  // of the crash.
+  CHECK(incognito_session_metrics_recorder_);
+
   incognito_session_metrics_recorder_->RestoreSession(session_start,
                                                       last_reported_duration);
 }
@@ -193,6 +197,11 @@
   AndroidSessionDurationsService* duration_service =
       AndroidSessionDurationsServiceFactory::GetForProfile(profile);
 
+  // TODO(https://crbug.com/1226462): Remove after investigation of the crash.
+  CHECK_EQ(profile,
+           ProfileManager::GetLastUsedProfile()->GetPrimaryOTRProfile(false));
+  CHECK(duration_service);
+
   base::Time session_start_time = base::Time::FromJavaTime(
       Java_AndroidSessionDurationsServiceState_getSessionStartTime(
           env, j_duration_service));
diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
index f870b13..df128e0a 100644
--- a/chrome/browser/android/ntp/most_visited_sites_bridge.cc
+++ b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
@@ -157,7 +157,6 @@
   std::vector<int> title_sources;
   std::vector<int> sources;
   std::vector<int> section_types;
-  std::vector<int64_t> data_generation_times;
   for (const auto& section : sections) {
     const NTPTilesVector& tiles = section.second;
     section_types.resize(section_types.size() + tiles.size(),
@@ -168,8 +167,6 @@
       allowlist_icons.emplace_back(tile.allowlist_icon_path.value());
       title_sources.emplace_back(static_cast<int>(tile.title_source));
       sources.emplace_back(static_cast<int>(tile.source));
-      data_generation_times.emplace_back(
-          tile.data_generation_time.ToJavaTime());
     }
   }
   Java_MostVisitedSitesBridge_onURLsAvailable(
@@ -177,8 +174,7 @@
       url::GURLAndroid::ToJavaArrayOfGURLs(env, urls),
       ToJavaIntArray(env, section_types),
       ToJavaArrayOfStrings(env, allowlist_icons),
-      ToJavaIntArray(env, title_sources), ToJavaIntArray(env, sources),
-      ToJavaLongArray(env, data_generation_times));
+      ToJavaIntArray(env, title_sources), ToJavaIntArray(env, sources));
 }
 
 void MostVisitedSitesBridge::JavaObserver::OnIconMadeAvailable(
@@ -248,7 +244,6 @@
     jint jicon_type,
     jint jtitle_source,
     jint jsource,
-    jlong jdata_generation_time_ms,
     const JavaParamRef<jobject>& jurl) {
   std::unique_ptr<GURL> url = url::GURLAndroid::ToNativeGURL(env, jurl);
   TileTitleSource title_source = static_cast<TileTitleSource>(jtitle_source);
@@ -258,8 +253,7 @@
       static_cast<favicon_base::IconType>(jicon_type);
 
   ntp_tiles::metrics::RecordTileImpression(ntp_tiles::NTPTileImpression(
-      jindex, source, title_source, visual_type, icon_type,
-      base::Time::FromJavaTime(jdata_generation_time_ms), *url));
+      jindex, source, title_source, visual_type, icon_type, *url));
 }
 
 void MostVisitedSitesBridge::RecordOpenedMostVisitedItem(
@@ -268,13 +262,11 @@
     jint index,
     jint tile_type,
     jint title_source,
-    jint source,
-    jlong jdata_generation_time_ms) {
+    jint source) {
   ntp_tiles::metrics::RecordTileClick(ntp_tiles::NTPTileImpression(
       index, static_cast<TileSource>(source),
       static_cast<TileTitleSource>(title_source),
       static_cast<TileVisualType>(tile_type), favicon_base::IconType::kInvalid,
-      base::Time::FromJavaTime(jdata_generation_time_ms),
       /*url_for_rappor=*/GURL()));
 }
 
diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.h b/chrome/browser/android/ntp/most_visited_sites_bridge.h
index c04d015..d5dff6e 100644
--- a/chrome/browser/android/ntp/most_visited_sites_bridge.h
+++ b/chrome/browser/android/ntp/most_visited_sites_bridge.h
@@ -51,7 +51,6 @@
                             jint jicon_type,
                             jint jtitle_source,
                             jint jsource,
-                            jlong jdata_generation_time_ms,
                             const base::android::JavaParamRef<jobject>& jurl);
   void RecordOpenedMostVisitedItem(
       JNIEnv* env,
@@ -59,8 +58,7 @@
       jint index,
       jint tile_type,
       jint title_source,
-      jint source,
-      jlong jdata_generation_time_ms);
+      jint source);
 
  private:
   ~MostVisitedSitesBridge();
diff --git a/chrome/browser/android/send_tab_to_self/android_notification_handler.cc b/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
index 64d8b86..88d1bb5 100644
--- a/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
+++ b/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
@@ -21,6 +21,7 @@
 #include "components/messages/android/message_wrapper.h"
 #include "components/send_tab_to_self/features.h"
 #include "components/send_tab_to_self/send_tab_to_self_entry.h"
+#include "components/url_formatter/elide_url.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -70,7 +71,8 @@
       message_->SetTitle(l10n_util::GetStringFUTF16(
           IDS_SEND_TAB_TO_SELF_MESSAGE,
           base::UTF8ToUTF16(entry->GetDeviceName())));
-      message_->SetDescription(base::UTF8ToUTF16(entry->GetURL().spec()));
+      message_->SetDescription(
+          url_formatter::FormatUrlForSecurityDisplay(entry->GetURL()));
       message_->SetDescriptionMaxLines(1);
       message_->SetPrimaryButtonText(
           l10n_util::GetStringUTF16(IDS_SEND_TAB_TO_SELF_MESSAGE_OPEN));
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 41c345a..c0aba8fd 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -1128,15 +1128,17 @@
                             attachedSheet] isKindOfClass:[NSWindow class]];
 }
 
-// Called to validate menu items when there are no key windows. All the
-// items we care about have been set with the |commandDispatch:| action and
-// a target of FirstResponder in IB. If it's not one of those, let it
-// continue up the responder chain to be handled elsewhere. We pull out the
-// tag as the cross-platform constant to differentiate and dispatch the
-// various commands.
+// Validates menu items in the dock (always) and in the menu bar (if there is no
+// browser).
 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
   SEL action = [item action];
   BOOL enable = NO;
+  // Whether the profile is loaded and opening a new browser window is allowed.
+  BOOL canOpenNewBrowser =
+      [self safeProfileForNewWindows:[self lastProfileIfLoaded]] ? YES : NO;
+  // Commands from dock are always handled by commandFromDock:, but commands
+  // from the menu bar are only handled by commandDispatch: if there is no key
+  // window.
   if (action == @selector(commandDispatch:) ||
       action == @selector(commandFromDock:)) {
     NSInteger tag = [item tag];
@@ -1151,23 +1153,37 @@
         case IDC_RESTORE_TAB:
           enable = ![self keyWindowIsModal] && [self canRestoreTab];
           break;
-        // Browser-level items that open in new tabs should not open if there's
-        // a window- or app-modal dialog.
+        // Browser-level items that open in new tabs or perform an action in a
+        // current tab should not open if there's a window- or app-modal dialog.
         case IDC_OPEN_FILE:
         case IDC_NEW_TAB:
+        case IDC_FOCUS_LOCATION:
+        case IDC_FOCUS_SEARCH:
         case IDC_SHOW_HISTORY:
         case IDC_SHOW_BOOKMARK_MANAGER:
-          enable = ![self keyWindowIsModal];
+        case IDC_CLEAR_BROWSING_DATA:
+        case IDC_SHOW_DOWNLOADS:
+        case IDC_IMPORT_SETTINGS:
+        case IDC_MANAGE_EXTENSIONS:
+        case IDC_HELP_PAGE_VIA_MENU:
+        case IDC_OPTIONS:
+          enable = canOpenNewBrowser && ![self keyWindowIsModal];
           break;
-        // Browser-level items that open in new windows.
+        // Browser-level items that open in new windows: allow the user to open
+        // a new window even if there's a window-modal dialog.
+        case IDC_NEW_WINDOW:
+          enable = canOpenNewBrowser;
+          break;
         case IDC_TASK_MANAGER:
-          // Allow the user to open a new window if there's a window-modal
-          // dialog.
-          enable = ![self keyWindowIsModal];
+          enable = YES;
+          break;
+        case IDC_NEW_INCOGNITO_WINDOW:
+          enable = _menuState->IsCommandEnabled(tag) ? canOpenNewBrowser : NO;
           break;
         default:
           enable = _menuState->IsCommandEnabled(tag) ?
                    ![self keyWindowIsModal] : NO;
+          break;
       }
     }
 
@@ -1183,11 +1199,9 @@
   } else if (action == @selector(terminate:)) {
     enable = YES;
   } else if (action == @selector(showPreferences:)) {
-    enable = YES;
+    enable = canOpenNewBrowser;
   } else if (action == @selector(orderFrontStandardAboutPanel:)) {
-    enable = YES;
-  } else if (action == @selector(commandFromDock:)) {
-    enable = YES;
+    enable = canOpenNewBrowser;
   } else if (action == @selector(toggleConfirmToQuit:)) {
     [self updateConfirmToQuitPrefMenuItem:static_cast<NSMenuItem*>(item)];
     enable = YES;
diff --git a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
index 6699223..0dc483c 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
@@ -200,9 +200,6 @@
 
   arc_is_registered_ = true;
   extension_apps_->ObserveArc();
-  if (web_apps_) {
-    web_apps_->ObserveArc();
-  }
 }
 
 void AppServiceProxyChromeOs::FlushMojoCallsForTesting() {
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index 80e9162..8d73455 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/common/chrome_switches.h"
@@ -32,8 +31,8 @@
 std::string GetAppIdForWebContents(content::WebContents* web_contents) {
   std::string app_id;
 
-  web_app::WebAppTabHelperBase* web_app_tab_helper =
-      web_app::WebAppTabHelperBase::FromWebContents(web_contents);
+  web_app::WebAppTabHelper* web_app_tab_helper =
+      web_app::WebAppTabHelper::FromWebContents(web_contents);
   // web_app_tab_helper is nullptr in some unit tests.
   if (web_app_tab_helper) {
     app_id = web_app_tab_helper->GetAppId();
@@ -77,14 +76,14 @@
           app_id);
   if (extension && !extension->from_bookmark()) {
     DCHECK(extension->is_app());
-    web_app::WebAppTabHelperBase::FromWebContents(web_contents)
+    web_app::WebAppTabHelper::FromWebContents(web_contents)
         ->SetAppId(std::string());
     extensions::TabHelper::FromWebContents(web_contents)
         ->SetExtensionAppById(app_id);
   } else {
     web_app::AppRegistrar& registrar =
         web_app::WebAppProviderBase::GetProviderBase(profile)->registrar();
-    web_app::WebAppTabHelperBase::FromWebContents(web_contents)
+    web_app::WebAppTabHelper::FromWebContents(web_contents)
         ->SetAppId(registrar.IsInstalled(app_id) ? app_id : std::string());
     extensions::TabHelper::FromWebContents(web_contents)
         ->SetExtensionAppById(std::string());
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.cc b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
index 254d28ac..79437d2 100644
--- a/chrome/browser/apps/app_service/publishers/borealis_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ash/borealis/borealis_app_uninstaller.h"
 #include "chrome/browser/ash/borealis/borealis_context_manager.h"
 #include "chrome/browser/ash/borealis/borealis_features.h"
+#include "chrome/browser/ash/borealis/borealis_prefs.h"
 #include "chrome/browser/ash/borealis/borealis_service.h"
 #include "chrome/browser/ash/borealis/borealis_util.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
@@ -22,11 +23,32 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
 #include "components/services/app_service/public/cpp/publisher_base.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace {
 
+struct PermissionInfo {
+  app_management::mojom::BorealisPermissionType permission;
+  const char* pref_name;
+};
+
+constexpr PermissionInfo permission_infos[] = {
+    {app_management::mojom::BorealisPermissionType::MICROPHONE,
+     borealis::prefs::kBorealisMicAllowed},
+};
+
+const char* PermissionToPrefName(
+    app_management::mojom::BorealisPermissionType permission) {
+  for (const PermissionInfo& info : permission_infos) {
+    if (info.permission == permission) {
+      return info.pref_name;
+    }
+  }
+  return nullptr;
+}
+
 void SetAppAllowed(apps::mojom::App* app, bool allowed) {
   app->readiness = allowed ? apps::mojom::Readiness::kReady
                            : apps::mojom::Readiness::kDisabledByPolicy;
@@ -40,6 +62,7 @@
   app->show_in_launcher = opt_allowed;
   app->show_in_shelf = opt_allowed;
   app->show_in_search = opt_allowed;
+  app->show_in_management = opt_allowed;
 }
 
 apps::mojom::AppPtr GetBorealisLauncher(Profile* profile, bool allowed) {
@@ -58,6 +81,18 @@
   return app;
 }
 
+void PopulatePermissions(apps::mojom::App* app, Profile* profile) {
+  for (const PermissionInfo& info : permission_infos) {
+    auto permission = apps::mojom::Permission::New();
+    permission->permission_id = static_cast<uint32_t>(info.permission);
+    permission->value_type = apps::mojom::PermissionValueType::kBool;
+    permission->value =
+        static_cast<uint32_t>(profile->GetPrefs()->GetBoolean(info.pref_name));
+    permission->is_managed = false;
+    app->permissions.push_back(std::move(permission));
+  }
+}
+
 }  // namespace
 
 namespace apps {
@@ -127,6 +162,10 @@
   app->last_launch_time = registration.LastLaunchTime();
   app->install_time = registration.InstallTime();
 
+  if (registration.app_id() == borealis::kBorealisMainAppId) {
+    PopulatePermissions(app.get(), profile_);
+  }
+
   SetAppAllowed(app.get(), !registration.NoDisplay());
   return app;
 }
@@ -175,6 +214,17 @@
       app_id, base::DoNothing());
 }
 
+void BorealisApps::SetPermission(const std::string& app_id,
+                                 apps::mojom::PermissionPtr permission_ptr) {
+  auto permission = static_cast<app_management::mojom::BorealisPermissionType>(
+      permission_ptr->permission_id);
+  const char* pref_name = PermissionToPrefName(permission);
+  if (!pref_name) {
+    return;
+  }
+  profile_->GetPrefs()->SetBoolean(pref_name, permission_ptr->value);
+}
+
 void BorealisApps::Uninstall(const std::string& app_id,
                              apps::mojom::UninstallSource uninstall_source,
                              bool clear_site_data,
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.h b/chrome/browser/apps/app_service/publishers/borealis_apps.h
index 041843c2..8a450c9 100644
--- a/chrome/browser/apps/app_service/publishers/borealis_apps.h
+++ b/chrome/browser/apps/app_service/publishers/borealis_apps.h
@@ -61,6 +61,8 @@
               int32_t event_flags,
               apps::mojom::LaunchSource launch_source,
               apps::mojom::WindowInfoPtr window_info) override;
+  void SetPermission(const std::string& app_id,
+                     apps::mojom::PermissionPtr permission) override;
   void Uninstall(const std::string& app_id,
                  apps::mojom::UninstallSource uninstall_source,
                  bool clear_site_data,
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
index 93e99a45..efb6bd096 100644
--- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
+++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -21,9 +21,9 @@
 #include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/common/chrome_features.h"
 #include "components/services/app_service/public/mojom/types.mojom.h"
 #include "content/public/browser/browser_context.h"
@@ -196,8 +196,7 @@
     return absl::nullopt;
   }
 
-  auto* tab_helper =
-      web_app::WebAppTabHelperBase::FromWebContents(web_contents);
+  auto* tab_helper = web_app::WebAppTabHelper::FromWebContents(web_contents);
   if (tab_helper && tab_helper->GetAppId() == *app_id) {
     // Already in app scope, do not alter window state while using the app.
     return absl::nullopt;
diff --git a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_apitest.cc b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_apitest.cc
index 924e4d7..bf55d39b 100644
--- a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_apitest.cc
+++ b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_apitest.cc
@@ -130,7 +130,7 @@
 
     const char* custom_arg = NULL;
     std::string json_string;
-    if (!custom_arg_value.empty()) {
+    if (!custom_arg_value.GetList().empty()) {
       base::JSONWriter::Write(custom_arg_value, &json_string);
       custom_arg = json_string.c_str();
     }
diff --git a/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc b/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
index 3302959f..1f305818 100644
--- a/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
+++ b/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
@@ -191,7 +191,13 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, ActivatesWithTapOnSelectToSpeakTray) {
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_ActivatesWithTapOnSelectToSpeakTray DISABLED_ActivatesWithTapOnSelectToSpeakTray
+#else
+#define MAYBE_ActivatesWithTapOnSelectToSpeakTray ActivatesWithTapOnSelectToSpeakTray
+#endif
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, MAYBE_ActivatesWithTapOnSelectToSpeakTray) {
   base::RepeatingCallback<void()> callback = base::BindRepeating(
       &SelectToSpeakTest::SetSelectToSpeakState, GetWeakPtr());
   AccessibilityManager::Get()->SetSelectToSpeakStateObserverForTest(callback);
@@ -213,7 +219,13 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, WorksWithTouchSelection) {
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_WorksWithTouchSelection DISABLED_WorksWithTouchSelection
+#else
+#define MAYBE_WorksWithTouchSelection WorksWithTouchSelection
+#endif
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, MAYBE_WorksWithTouchSelection) {
   base::RepeatingCallback<void()> callback = base::BindRepeating(
       &SelectToSpeakTest::SetSelectToSpeakState, GetWeakPtr());
   AccessibilityManager::Get()->SetSelectToSpeakStateObserverForTest(callback);
@@ -299,7 +311,13 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossInlineUrl) {
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_SmoothlyReadsAcrossInlineUrl DISABLED_SmoothlyReadsAcrossInlineUrl
+#else
+#define MAYBE_SmoothlyReadsAcrossInlineUrl SmoothlyReadsAcrossInlineUrl
+#endif
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, MAYBE_SmoothlyReadsAcrossInlineUrl) {
   // Make sure an inline URL is read smoothly.
   ActivateSelectToSpeakInWindowBounds(
       "data:text/html;charset=utf-8,<p>This is some text <a href=\"\">with a"
@@ -311,7 +329,13 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossMultipleLines) {
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_SmoothlyReadsAcrossMultipleLines DISABLED_SmoothlyReadsAcrossMultipleLines
+#else
+#define MAYBE_SmoothlyReadsAcrossMultipleLines SmoothlyReadsAcrossMultipleLines
+#endif
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, MAYBE_SmoothlyReadsAcrossMultipleLines) {
   // Sentences spanning multiple lines.
   ActivateSelectToSpeakInWindowBounds(
       "data:text/html;charset=utf-8,<div style=\"width:100px\">This"
@@ -338,8 +362,16 @@
   sm_.Replay();
 }
 
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_ReadsStaticTextWithoutInlineTextChildren \
+  DISABLED_ReadsStaticTextWithoutInlineTextChildren
+#else
+#define MAYBE_ReadsStaticTextWithoutInlineTextChildren \
+  ReadsStaticTextWithoutInlineTextChildren
+#endif
 IN_PROC_BROWSER_TEST_F(SelectToSpeakTest,
-                       ReadsStaticTextWithoutInlineTextChildren) {
+                       MAYBE_ReadsStaticTextWithoutInlineTextChildren) {
   // Bold or formatted text
   ActivateSelectToSpeakInWindowBounds(
       "data:text/html;charset=utf-8,<canvas>This is some text</canvas>");
@@ -393,7 +425,13 @@
   sm_.Replay();
 }
 
-IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, DoesNotCrashWithMousewheelEvent) {
+// Flaky on ChromeOS MSAN bots: https://crbug.com/1227368
+#if defined(OS_CHROMEOS) && defined(MEMORY_SANITIZER)
+#define MAYBE_DoesNotCrashWithMousewheelEvent DISABLED_DoesNotCrashWithMousewheelEvent
+#else
+#define MAYBE_DoesNotCrashWithMousewheelEvent DoesNotCrashWithMousewheelEvent
+#endif
+IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, MAYBE_DoesNotCrashWithMousewheelEvent) {
   ui_test_utils::NavigateToURL(
       browser(), GURL("data:text/html;charset=utf-8,<p>This is some text</p>"));
   gfx::Rect bounds = GetWebContentsBounds();
diff --git a/chrome/browser/ash/app_mode/kiosk_app_manager.h b/chrome/browser/ash/app_mode/kiosk_app_manager.h
index c8c072e..5dcd9fc 100644
--- a/chrome/browser/ash/app_mode/kiosk_app_manager.h
+++ b/chrome/browser/ash/app_mode/kiosk_app_manager.h
@@ -31,11 +31,6 @@
 class CommandLine;
 }
 
-namespace chromeos {
-class KioskAutoLaunchViewsTest;
-class KioskTest;
-}  // namespace chromeos
-
 namespace extensions {
 class Extension;
 }
@@ -253,8 +248,8 @@
   friend struct base::LazyInstanceTraitsBase<KioskAppManager>;
   friend std::default_delete<KioskAppManager>;
   friend class KioskAppManagerTest;
-  friend class chromeos::KioskAutoLaunchViewsTest;
-  friend class chromeos::KioskTest;
+  friend class KioskAutoLaunchViewsTest;
+  friend class KioskTest;
 
   enum class AutoLoginState {
     kNone = 0,
diff --git a/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc b/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc
index 51b10e3..9876224 100644
--- a/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc
+++ b/chrome/browser/ash/apps/intent_helper/common_apps_navigation_throttle.cc
@@ -20,7 +20,7 @@
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_id_constants.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/browser_resources.h"
 #include "components/policy/core/common/policy_pref_names.h"
@@ -149,8 +149,7 @@
 
   // Don't capture if already inside the target app scope.
   if (app_type == apps::mojom::AppType::kWeb) {
-    auto* tab_helper =
-        web_app::WebAppTabHelperBase::FromWebContents(web_contents);
+    auto* tab_helper = web_app::WebAppTabHelper::FromWebContents(web_contents);
     if (tab_helper && tab_helper->GetAppId() == preferred_app_id.value())
       return false;
   }
diff --git a/chrome/browser/ash/arc/arc_util.cc b/chrome/browser/ash/arc/arc_util.cc
index f00bbdf1..0cfe3198 100644
--- a/chrome/browser/ash/arc/arc_util.cc
+++ b/chrome/browser/ash/arc/arc_util.cc
@@ -583,7 +583,7 @@
 
   const ArcSupervisionTransition supervision_transition =
       static_cast<ArcSupervisionTransition>(
-          profile->GetPrefs()->GetInteger(prefs::kArcSupervisionTransition));
+          profile->GetPrefs()->GetInteger(prefs::kArcManagementTransition));
   const bool is_child_to_regular_enabled =
       base::FeatureList::IsEnabled(kEnableChildToRegularTransitionFeature);
   const bool is_regular_to_child_enabled =
diff --git a/chrome/browser/ash/arc/arc_util_unittest.cc b/chrome/browser/ash/arc/arc_util_unittest.cc
index c0bb93cd..f6b08ef1 100644
--- a/chrome/browser/ash/arc/arc_util_unittest.cc
+++ b/chrome/browser/ash/arc/arc_util_unittest.cc
@@ -734,7 +734,7 @@
       arc::kEnableUnmanagedToManagedTransitionFeature);
 
   profile()->GetPrefs()->SetInteger(
-      arc::prefs::kArcSupervisionTransition,
+      arc::prefs::kArcManagementTransition,
       static_cast<int>(arc::ArcSupervisionTransition::UNMANAGED_TO_MANAGED));
 
   EXPECT_EQ(GetSupervisionTransition(profile()),
@@ -747,7 +747,7 @@
       arc::kEnableUnmanagedToManagedTransitionFeature);
 
   profile()->GetPrefs()->SetInteger(
-      arc::prefs::kArcSupervisionTransition,
+      arc::prefs::kArcManagementTransition,
       static_cast<int>(arc::ArcSupervisionTransition::UNMANAGED_TO_MANAGED));
 
   EXPECT_EQ(GetSupervisionTransition(profile()),
diff --git a/chrome/browser/ash/arc/auth/arc_auth_service.cc b/chrome/browser/ash/arc/auth/arc_auth_service.cc
index 71eb9e3..6dd3b1ae 100644
--- a/chrome/browser/ash/arc/auth/arc_auth_service.cc
+++ b/chrome/browser/ash/arc/auth/arc_auth_service.cc
@@ -383,7 +383,7 @@
     case mojom::ManagementChangeStatus::CLOUD_DPC_ENABLED:
     case mojom::ManagementChangeStatus::CLOUD_DPC_ALREADY_ENABLED:
       profile_->GetPrefs()->SetInteger(
-          prefs::kArcSupervisionTransition,
+          prefs::kArcManagementTransition,
           static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
       // TODO(brunokim): notify potential observers.
       break;
diff --git a/chrome/browser/ash/arc/notification/arc_management_transition_notification.cc b/chrome/browser/ash/arc/notification/arc_management_transition_notification.cc
index 2a6a889..95d246e 100644
--- a/chrome/browser/ash/arc/notification/arc_management_transition_notification.cc
+++ b/chrome/browser/ash/arc/notification/arc_management_transition_notification.cc
@@ -43,7 +43,7 @@
     ArcSessionManager::Get()->AddObserver(this);
     pref_change_registrar_.Init(profile_->GetPrefs());
     pref_change_registrar_.Add(
-        prefs::kArcSupervisionTransition,
+        prefs::kArcManagementTransition,
         base::BindRepeating(&NotificationDelegate::OnTransitionChanged,
                             base::Unretained(this)));
   }
diff --git a/chrome/browser/ash/arc/notification/arc_management_transition_notification_unittest.cc b/chrome/browser/ash/arc/notification/arc_management_transition_notification_unittest.cc
index e7dfe60..9c289c8 100644
--- a/chrome/browser/ash/arc/notification/arc_management_transition_notification_unittest.cc
+++ b/chrome/browser/ash/arc/notification/arc_management_transition_notification_unittest.cc
@@ -113,7 +113,7 @@
   const std::string app_id =
       ArcAppTest::GetAppId(arc_app_test()->fake_apps()[0]);
 
-  profile()->GetPrefs()->SetInteger(prefs::kArcSupervisionTransition,
+  profile()->GetPrefs()->SetInteger(prefs::kArcManagementTransition,
                                     static_cast<int>(arc_transition()));
 
   // Attempt to launch ARC app triggers notification.
@@ -150,14 +150,14 @@
 
   // Finishing transition automatically dismisses notification.
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
   EXPECT_FALSE(
       display_service()->GetNotification(kManagementTransitionNotificationId));
 
   // Re-activate notification and check opt out. On opt-out notification is also
-  // automatially dismissed.
-  profile()->GetPrefs()->SetInteger(prefs::kArcSupervisionTransition,
+  // automatically dismissed.
+  profile()->GetPrefs()->SetInteger(prefs::kArcManagementTransition,
                                     static_cast<int>(arc_transition()));
   ShowManagementTransitionNotification(profile());
   EXPECT_TRUE(
diff --git a/chrome/browser/ash/arc/session/arc_session_manager.cc b/chrome/browser/ash/arc/session/arc_session_manager.cc
index 34bcdfa..9bd7f8e5 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager.cc
@@ -1212,7 +1212,7 @@
 
   data_remover_->Schedule();
   profile_->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
   // To support 1) case above, maybe start data removal.
   if (state_ == State::STOPPED)
@@ -1473,7 +1473,7 @@
     // User has become managed, notify ARC by setting transition preference,
     // which is eventually passed to ARC via ArcSession parameters.
     profile_->GetPrefs()->SetInteger(
-        arc::prefs::kArcSupervisionTransition,
+        arc::prefs::kArcManagementTransition,
         static_cast<int>(arc::ArcSupervisionTransition::UNMANAGED_TO_MANAGED));
 
     // Restart ARC to perform managed re-provisioning.
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
index dcc52c9..531e99b2 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
@@ -787,7 +787,7 @@
   // Emulate the situation where a regular user has transitioned to a child
   // account.
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::REGULAR_TO_CHILD));
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndEnableFeature(
@@ -797,9 +797,8 @@
   arc_session_manager()->Initialize();
   EXPECT_TRUE(
       profile()->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested));
-  EXPECT_EQ(
-      static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
-      profile()->GetPrefs()->GetInteger(prefs::kArcSupervisionTransition));
+  EXPECT_EQ(static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
+            profile()->GetPrefs()->GetInteger(prefs::kArcManagementTransition));
   EXPECT_EQ(ArcSessionManager::State::REMOVING_DATA_DIR,
             arc_session_manager()->state());
 
@@ -810,7 +809,7 @@
   // Emulate the situation where a regular user has transitioned to a child
   // account, but the feature flag is disabled.
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::REGULAR_TO_CHILD));
   base::test::ScopedFeatureList feature_list;
   feature_list.InitAndDisableFeature(
@@ -821,9 +820,8 @@
   arc_session_manager()->RequestEnable();
   EXPECT_FALSE(
       profile()->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested));
-  EXPECT_EQ(
-      static_cast<int>(ArcSupervisionTransition::REGULAR_TO_CHILD),
-      profile()->GetPrefs()->GetInteger(prefs::kArcSupervisionTransition));
+  EXPECT_EQ(static_cast<int>(ArcSupervisionTransition::REGULAR_TO_CHILD),
+            profile()->GetPrefs()->GetInteger(prefs::kArcManagementTransition));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE,
             arc_session_manager()->state());
@@ -833,7 +831,7 @@
 
 TEST_F(ArcSessionManagerTest, ClearArcTransitionOnShutdown) {
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
 
   // Initialize ARC.
@@ -851,22 +849,20 @@
   arc_session_manager()->OnProvisioningFinished(
       ArcProvisioningResult(std::move(result)));
 
-  EXPECT_EQ(
-      static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
-      profile()->GetPrefs()->GetInteger(prefs::kArcSupervisionTransition));
+  EXPECT_EQ(static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
+            profile()->GetPrefs()->GetInteger(prefs::kArcManagementTransition));
 
   // Child started graduation.
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::CHILD_TO_REGULAR));
   // Simulate ARC shutdown.
   const bool enable_requested = arc_session_manager()->enable_requested();
   arc_session_manager()->RequestDisable();
   if (enable_requested)
     arc_session_manager()->RequestArcDataRemoval();
-  EXPECT_EQ(
-      static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
-      profile()->GetPrefs()->GetInteger(prefs::kArcSupervisionTransition));
+  EXPECT_EQ(static_cast<int>(ArcSupervisionTransition::NO_TRANSITION),
+            profile()->GetPrefs()->GetInteger(prefs::kArcManagementTransition));
 
   arc_session_manager()->Shutdown();
 }
@@ -895,7 +891,7 @@
 
   // Child started graduation.
   profile()->GetPrefs()->SetInteger(
-      prefs::kArcSupervisionTransition,
+      prefs::kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::CHILD_TO_REGULAR));
 
   arc_session_manager()->RequestArcDataRemoval();
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
index 3416e7ad..7ec16bf 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing_unittest.cc
@@ -12,6 +12,8 @@
 #include "chrome/browser/ash/arc/tracing/arc_app_performance_tracing_session.h"
 #include "chrome/browser/ash/arc/tracing/arc_app_performance_tracing_test_helper.h"
 #include "chrome/browser/ash/arc/tracing/arc_app_performance_tracing_uma_session.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
@@ -110,7 +112,9 @@
 
   TestingProfile::TestingFactories GetTestingFactories() override {
     return {{SyncServiceFactory::GetInstance(),
-             SyncServiceFactory::GetDefaultFactory()}};
+             SyncServiceFactory::GetDefaultFactory()},
+            {ChromeSigninClientFactory::GetInstance(),
+             base::BindRepeating(&signin::BuildTestSigninClient)}};
   }
 
  private:
diff --git a/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h b/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h
index 3b2ae91..cf7965d 100644
--- a/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h
+++ b/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h
@@ -9,10 +9,10 @@
 #include <string>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
 #include "base/timer/timer.h"
 
 namespace base {
diff --git a/chrome/browser/ash/borealis/borealis_installer_impl.cc b/chrome/browser/ash/borealis/borealis_installer_impl.cc
index 145cc362..ce0acc74 100644
--- a/chrome/browser/ash/borealis/borealis_installer_impl.cc
+++ b/chrome/browser/ash/borealis/borealis_installer_impl.cc
@@ -343,6 +343,10 @@
     return;
   }
 
+  // Reset mic permission, we don't want it to persist across
+  // re-installation.
+  profile_->GetPrefs()->SetBoolean(prefs::kBorealisMicAllowed, false);
+
   auto install_info = std::make_unique<InstallInfo>();
   install_info->vm_name = "borealis";
   install_info->container_name = "penguin";
diff --git a/chrome/browser/ash/borealis/borealis_prefs.cc b/chrome/browser/ash/borealis/borealis_prefs.cc
index a9f25caa..28ed14d 100644
--- a/chrome/browser/ash/borealis/borealis_prefs.cc
+++ b/chrome/browser/ash/borealis/borealis_prefs.cc
@@ -16,9 +16,12 @@
 
 const char kEngagementPrefsPrefix[] = "borealis.metrics";
 
+const char kBorealisMicAllowed[] = "borealis.microphone_allowed";
+
 void RegisterProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(kBorealisInstalledOnDevice, false);
   registry->RegisterBooleanPref(kBorealisAllowedForUser, true);
+  registry->RegisterBooleanPref(kBorealisMicAllowed, false);
   guest_os::prefs::RegisterEngagementProfilePrefs(registry,
                                                   kEngagementPrefsPrefix);
 }
diff --git a/chrome/browser/ash/borealis/borealis_prefs.h b/chrome/browser/ash/borealis/borealis_prefs.h
index dfa7cfbd..b43e72fe 100644
--- a/chrome/browser/ash/borealis/borealis_prefs.h
+++ b/chrome/browser/ash/borealis/borealis_prefs.h
@@ -20,6 +20,8 @@
 
 extern const char kEngagementPrefsPrefix[];
 
+extern const char kBorealisMicAllowed[];
+
 void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
 }  // namespace prefs
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_navigation_throttle.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_navigation_throttle.cc
index 2c3be6b..e3e096c9 100644
--- a/chrome/browser/ash/child_accounts/time_limits/web_time_limit_navigation_throttle.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/web_time_limit_navigation_throttle.cc
@@ -23,7 +23,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -163,8 +163,8 @@
                   (type == Browser::Type::TYPE_POPUP);
   }
 
-  web_app::WebAppTabHelperBase* web_app_helper =
-      web_app::WebAppTabHelperBase::FromWebContents(web_contents);
+  web_app::WebAppTabHelper* web_app_helper =
+      web_app::WebAppTabHelper::FromWebContents(web_contents);
 
   bool is_app = web_app_helper && !web_app_helper->GetAppId().empty();
 
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc
index 9f2d967..7cf7d16 100644
--- a/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc
@@ -8,8 +8,8 @@
 #include "chrome/browser/ash/child_accounts/time_limits/app_time_controller.h"
 #include "chrome/browser/ash/child_accounts/time_limits/web_time_limit_enforcer.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
@@ -48,8 +48,8 @@
       Profile::FromBrowserContext(web_contents()->GetBrowserContext());
   if (!web_app::AreWebAppsEnabled(profile))
     return false;
-  const web_app::WebAppTabHelperBase* web_app_helper =
-      web_app::WebAppTabHelperBase::FromWebContents(web_contents());
+  const web_app::WebAppTabHelper* web_app_helper =
+      web_app::WebAppTabHelper::FromWebContents(web_contents());
   return !web_app_helper->GetAppId().empty();
 }
 
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc
index a87e351..8849d9f 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator.cc
+++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -7,6 +7,8 @@
 #include <string>
 #include <utility>
 
+#include "ash/constants/ash_switches.h"
+#include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
@@ -22,10 +24,14 @@
 #include "chrome/browser/ash/crosapi/browser_util.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/common/chrome_paths.h"
+#include "chromeos/cryptohome/cryptohome_parameters.h"
+#include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/user_manager.h"
 #include "components/version_info/version_info.h"
+#include "google_apis/gaia/gaia_auth_util.h"
 
 namespace ash {
 namespace {
@@ -40,6 +46,9 @@
 // The base names of files and directories directory under the user data
 // directory.
 const char* const kCopyUserDataPaths[] = {"First Run"};
+// Flag values for `switches::kForceBrowserDataMigrationForTesting`.
+const char kBrowserDataMigrationForceSkip[] = "force-skip";
+const char kBrowserDataMigrationForceMigration[] = "force-migration";
 
 // Copies `item` to location pointed by `dest`. Returns true on success and
 // false on failure.
@@ -56,6 +65,26 @@
   PLOG(ERROR) << "Copy failed for " << item.path;
   return false;
 }
+
+void OnRestartRequestResponse(bool result) {
+  if (!result) {
+    LOG(ERROR) << "SessionManagerClient::RequestBrowserDataMigration failed.";
+    return;
+  }
+
+  chrome::AttemptRestart();
+}
+
+// This will be posted with `IsMigrationRequiredOnWorker()` as the reply on UI
+// thread or called directly from `MaybeRestartToMigrate()`.
+void MaybeRestartToMigrateCallback(const AccountId& account_id,
+                                   bool is_required) {
+  if (!is_required)
+    return;
+  SessionManagerClient::Get()->RequestBrowserDataMigration(
+      cryptohome::CreateAccountIdentifierFromAccountId(account_id),
+      base::BindOnce(&OnRestartRequestResponse));
+}
 }  // namespace
 
 BrowserDataMigrator::TargetItem::TargetItem(base::FilePath path,
@@ -71,9 +100,56 @@
 BrowserDataMigrator::TargetInfo::~TargetInfo() = default;
 
 // static
+void BrowserDataMigrator::MaybeRestartToMigrate(
+    const UserContext& user_context) {
+  const AccountId account_id = user_context.GetAccountId();
+  const user_manager::User* user =
+      user_manager::UserManager::Get()->FindUser(account_id);
+  // Check if lacros is enabled. If not immediately return.
+  if (!crosapi::browser_util::IsLacrosEnabledWithUser(user))
+    return;
+
+  // Check if the switch for testing is present.
+  const std::string force_migration_switch =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kForceBrowserDataMigrationForTesting);
+  if (force_migration_switch == kBrowserDataMigrationForceSkip)
+    return;
+  if (force_migration_switch == kBrowserDataMigrationForceMigration) {
+    MaybeRestartToMigrateCallback(account_id, true /* is_required */);
+    return;
+  }
+
+  // Browser data migration is only available for Googlers at the moment.
+  if (!gaia::IsGoogleInternalAccountEmail(account_id.GetUserEmail()))
+    return;
+
+  const std::string user_id_hash = user_context.GetUserIDHash();
+  if (crosapi::browser_util::IsDataWipeRequired(user_id_hash)) {
+    // If data wipe is required, no need for a further check to determine if
+    // lacros data dir exists or not.
+    MaybeRestartToMigrateCallback(account_id, true /* is_required */);
+    return;
+  }
+
+  base::FilePath user_data_dir;
+  if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
+    LOG(ERROR) << "Could not get the original user data dir path.";
+    return;
+  }
+
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+      base::BindOnce(&BrowserDataMigrator::IsMigrationRequiredOnWorker,
+                     user_data_dir, user_id_hash),
+      base::BindOnce(&MaybeRestartToMigrateCallback, account_id));
+}
+
+// static
 // Returns true if "lacros user data dir doesn't exist".
-bool BrowserDataMigrator::IsMigrationRequired(base::FilePath user_data_dir,
-                                              const std::string& user_id_hash) {
+bool BrowserDataMigrator::IsMigrationRequiredOnWorker(
+    base::FilePath user_data_dir,
+    const std::string& user_id_hash) {
   // Use `GetUserProfileDir()` to manually get base name for profile dir so that
   // this method can be called even before user profile is created.
   base::FilePath profile_data_dir =
@@ -86,7 +162,8 @@
                                   base::OnceClosure callback) {
   base::FilePath user_data_dir;
   if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
-    LOG(ERROR) << "Could not get the original UDD path. Aborting migration.";
+    LOG(ERROR)
+        << "Could not get the original user data dir path. Aborting migration.";
     RecordStatus(FinalStatus::kGetPathFailed);
     std::move(callback).Run();
     return;
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.h b/chrome/browser/ash/crosapi/browser_data_migrator.h
index b6560eb..e0ff2b0 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator.h
+++ b/chrome/browser/ash/crosapi/browser_data_migrator.h
@@ -97,10 +97,10 @@
   BrowserDataMigrator& operator=(const BrowserDataMigrator&) = delete;
   ~BrowserDataMigrator();
 
-  // The method includes a blocking operation. It checks if lacros user data dir
-  // already exists or not. Check if lacros is enabled or not beforehand.
-  static bool IsMigrationRequired(base::FilePath user_data_dir,
-                                  const std::string& user_id_hash);
+  // Checks if migration is required for the user identified by `user_context`
+  // and if it is required, calls a DBus method to session_manager and
+  // terminates ash-chrome.
+  static void MaybeRestartToMigrate(const UserContext& user_context);
 
   // The method needs to be called on UI thread. It instantiates
   // BrowserDataMigrator and posts `MigrateInternal()` on a worker thread. It
@@ -110,10 +110,16 @@
                       base::OnceClosure callback);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest,
+                           IsMigrationRequiredOnWorker);
   FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, GetTargetInfo);
   FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, RecordStatus);
   FRIEND_TEST_ALL_PREFIXES(BrowserDataMigratorTest, Migrate);
 
+  // The method includes a blocking operation. It checks if lacros user data dir
+  // already exists or not. Check if lacros is enabled or not beforehand.
+  static bool IsMigrationRequiredOnWorker(base::FilePath user_data_dir,
+                                          const std::string& user_id_hash);
   // Handles the migration on a worker thread. Returns the end status of data
   // wipe and migration.
   MigrationResult MigrateInternal();
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc
index 0665eb1b..1c7e7e37 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_data_migrator_unittest.cc
@@ -75,21 +75,21 @@
   base::FilePath from_dir_;
 };
 
-TEST_F(BrowserDataMigratorTest, IsMigrationRequired) {
+TEST_F(BrowserDataMigratorTest, IsMigrationRequiredOnWorker) {
   const std::string user_id_hash = "user";
   const base::FilePath user_data_dir_path = user_data_dir_.GetPath();
 
   // Lacros UDD does not exist.
-  EXPECT_TRUE(BrowserDataMigrator::IsMigrationRequired(user_data_dir_path,
-                                                       user_id_hash));
+  EXPECT_TRUE(BrowserDataMigrator::IsMigrationRequiredOnWorker(
+      user_data_dir_path, user_id_hash));
 
   // Create lacros user data dir.
   ASSERT_TRUE(base::CreateDirectory(
       user_data_dir_path.Append("user").Append(kLacrosDir)));
 
   // Lacros UDD exists.
-  EXPECT_FALSE(BrowserDataMigrator::IsMigrationRequired(user_data_dir_path,
-                                                        user_id_hash));
+  EXPECT_FALSE(BrowserDataMigrator::IsMigrationRequiredOnWorker(
+      user_data_dir_path, user_id_hash));
 }
 
 TEST_F(BrowserDataMigratorTest, GetTargetInfo) {
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index e88ab08..bbb5b2e 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -467,14 +467,7 @@
           ProfileManager::GetPrimaryUserProfile());
   // Check if user data directory needs to be wiped for a backward incompatible
   // update.
-  base::Version data_version =
-      browser_util::GetDataVer(g_browser_process->local_state(), user_id_hash);
-  base::Version current_version = version_info::GetVersion();
-  base::Version required_version =
-      base::Version(base::StringPiece(browser_util::kRequiredDataVersion));
-
-  bool cleared_user_data_dir = !browser_util::IsDataWipeRequired(
-      data_version, current_version, required_version);
+  bool cleared_user_data_dir = !browser_util::IsDataWipeRequired(user_id_hash);
 
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::MayBlock()},
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index b101d41..3a147a6 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -227,7 +227,7 @@
   }
 
   return result;
-}  // namespace
+}
 
 struct InterfaceVersionEntry {
   base::Token uuid;
@@ -297,6 +297,37 @@
   return false;
 }
 
+// Called from `IsDataWipeRequired()` or `IsDataWipeRequiredForTesting()`.
+// data_version` is the version of last data wipe. `current_version` is the
+// version of ash-chrome. `required_version` is the version that introduces some
+// breaking change. `data_version` needs to be greater or equal to
+// `required_version`. If `required_version` is newer than `current_version`,
+// data wipe is not required.
+bool IsDataWipeRequiredInternal(base::Version data_version,
+                                const base::Version& current_version,
+                                const base::Version& required_version) {
+  // `data_version` is invalid if any wipe has not been recorded yet. In
+  // such a case, assume that the last data wipe happened significantly long
+  // time ago.
+  if (!data_version.IsValid())
+    data_version = base::Version("0");
+
+  if (current_version < required_version) {
+    // If `current_version` is smaller than the `required_version`, that means
+    // that the data wipe doesn't need to happen yet.
+    return false;
+  }
+
+  if (data_version >= required_version) {
+    // If `data_version` is greater or equal to `required_version`, this means
+    // data wipe has already happened and that user data is compatible with the
+    // current lacros.
+    return false;
+  }
+
+  return true;
+}
+
 static_assert(
     crosapi::mojom::Crosapi::Version_ == 37,
     "if you add a new crosapi, please add it to kInterfaceVersionEntries");
@@ -686,29 +717,22 @@
   dict->SetString(user_id_hash, version.GetString());
 }
 
-bool IsDataWipeRequired(base::Version data_version,
-                        const base::Version& current_version,
-                        const base::Version& required_version) {
-  // `data_version` is invalid if any wipe has not been recorded yet. In
-  // such a case, assume that the last data wipe happened significantly long
-  // time ago.
-  if (!data_version.IsValid())
-    data_version = base::Version("0");
+bool IsDataWipeRequired(const std::string& user_id_hash) {
+  base::Version data_version =
+      GetDataVer(g_browser_process->local_state(), user_id_hash);
+  base::Version current_version = version_info::GetVersion();
+  base::Version required_version =
+      base::Version(base::StringPiece(kRequiredDataVersion));
 
-  if (current_version < required_version) {
-    // If `current_version` is smaller than the `required_version`, that means
-    // that the data wipe doesn't need to happen yet.
-    return false;
-  }
+  return IsDataWipeRequiredInternal(data_version, current_version,
+                                    required_version);
+}
 
-  if (data_version >= required_version) {
-    // If `data_version` is greater or equal to `required_version`, this means
-    // data wipe has already happened and that user data is compatible with the
-    // current lacros.
-    return false;
-  }
-
-  return true;
+bool IsDataWipeRequiredForTesting(base::Version data_version,
+                                  const base::Version& current_version,
+                                  const base::Version& required_version) {
+  return IsDataWipeRequiredInternal(data_version, current_version,
+                                    required_version);
 }
 
 base::Version GetRootfsLacrosVersionMayBlock(
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h
index 3cf8b6f7..848f01d 100644
--- a/chrome/browser/ash/crosapi/browser_util.h
+++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -204,14 +204,14 @@
                    const base::Version& version);
 
 // Checks if lacros' data directory needs to be wiped for backward incompatible
-// data. `data_version` is the version of last data wipe. `current_version` is
-// the version of ash-chrome. `required_version` is the version that introduces
-// some breaking change. `data_version` needs to be greater or equal to
-// `required_version`. If `required_version` is newer than `current_version`,
-// data wipe is not required.
-bool IsDataWipeRequired(base::Version data_version,
-                        const base::Version& current_version,
-                        const base::Version& required_version);
+// data.
+bool IsDataWipeRequired(const std::string& user_id_hash);
+
+// Exposed for testing. The arguments are passed to
+// `IsDataWipeRequiredInternal()`.
+bool IsDataWipeRequiredForTesting(base::Version data_version,
+                                  const base::Version& current_version,
+                                  const base::Version& required_version);
 
 // Gets the version of the rootfs lacros-chrome. By reading the metadata json
 // file in the correct format.
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc
index 56df19760..e0eaafb 100644
--- a/chrome/browser/ash/crosapi/browser_util_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -514,8 +514,8 @@
   const base::Version required{"2"};
 
   ASSERT_FALSE(data_version.IsValid());
-  EXPECT_TRUE(
-      browser_util::IsDataWipeRequired(data_version, current, required));
+  EXPECT_TRUE(browser_util::IsDataWipeRequiredForTesting(data_version, current,
+                                                         required));
 }
 
 TEST_F(BrowserUtilTest, IsDataWipeRequiredFutureVersion) {
@@ -523,8 +523,8 @@
   const base::Version current{"2"};
   const base::Version required{"3"};
 
-  EXPECT_FALSE(
-      browser_util::IsDataWipeRequired(data_version, current, required));
+  EXPECT_FALSE(browser_util::IsDataWipeRequiredForTesting(data_version, current,
+                                                          required));
 }
 
 TEST_F(BrowserUtilTest, IsDataWipeRequiredSameVersion) {
@@ -532,8 +532,8 @@
   const base::Version current{"4"};
   const base::Version required{"3"};
 
-  EXPECT_FALSE(
-      browser_util::IsDataWipeRequired(data_version, current, required));
+  EXPECT_FALSE(browser_util::IsDataWipeRequiredForTesting(data_version, current,
+                                                          required));
 }
 
 TEST_F(BrowserUtilTest, IsDataWipeRequired) {
@@ -541,8 +541,8 @@
   const base::Version current{"3"};
   const base::Version required{"2"};
 
-  EXPECT_TRUE(
-      browser_util::IsDataWipeRequired(data_version, current, required));
+  EXPECT_TRUE(browser_util::IsDataWipeRequiredForTesting(data_version, current,
+                                                         required));
 }
 
 TEST_F(BrowserUtilTest, IsDataWipeRequired2) {
@@ -550,8 +550,8 @@
   const base::Version current{"3"};
   const base::Version required{"3"};
 
-  EXPECT_TRUE(
-      browser_util::IsDataWipeRequired(data_version, current, required));
+  EXPECT_TRUE(browser_util::IsDataWipeRequiredForTesting(data_version, current,
+                                                         required));
 }
 
 TEST_F(BrowserUtilTest, GetRootfsLacrosVersionMayBlock) {
diff --git a/chrome/browser/ash/crosapi/environment_provider.cc b/chrome/browser/ash/crosapi/environment_provider.cc
index 7810a2c..dc5f068 100644
--- a/chrome/browser/ash/crosapi/environment_provider.cc
+++ b/chrome/browser/ash/crosapi/environment_provider.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/file_util.h"
 #include "base/system/sys_info.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -76,6 +77,12 @@
     // Typically /home/chronos/u-<hash>/MyFiles/Downloads.
     default_paths->downloads =
         file_manager::util::GetDownloadsFolderForProfile(profile);
+    auto* integration_service =
+        drive::DriveIntegrationServiceFactory::FindForProfile(profile);
+    if (integration_service && integration_service->is_enabled() &&
+        integration_service->IsMounted()) {
+      default_paths->drivefs = integration_service->GetMountPointPath();
+    }
   } else {
     // On developer linux workstations the above functions do path mangling to
     // support multi-signin which gets undone later in ash-specific code. This
@@ -83,6 +90,7 @@
     base::FilePath home = base::GetHomeDir();
     default_paths->documents = home.Append("Documents");
     default_paths->downloads = home.Append("Downloads");
+    default_paths->drivefs = home.Append("Drive");
   }
   return default_paths;
 }
diff --git a/chrome/browser/ash/crosapi/environment_provider.h b/chrome/browser/ash/crosapi/environment_provider.h
index a835a56..e943d0a 100644
--- a/chrome/browser/ash/crosapi/environment_provider.h
+++ b/chrome/browser/ash/crosapi/environment_provider.h
@@ -25,9 +25,9 @@
   virtual crosapi::mojom::SessionType GetSessionType();
   virtual crosapi::mojom::DeviceMode GetDeviceMode();
 
-  // Returns the default paths, such as Downloads and Documents (MyFiles).
-  // These are provided by ash because they are part of the device account,
-  // not the Lacros profile.
+  // Returns the default paths, such as Downloads, Documents (MyFiles) and the
+  // mount point for Drive. These are provided by ash because they are part of
+  // the device account, not the Lacros profile.
   virtual crosapi::mojom::DefaultPathsPtr GetDefaultPaths();
 
   // Deprecated. Use `GetDeviceAccount` instead.
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index 88e03b9..056d583 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -2273,12 +2273,10 @@
   }
 
   // The UI can only resize the default VM, so only (maybe) show the
-  // notification for the default VM. Additionally, ignore <= 0 as -1 means
-  // error and 0 is ambiguous meaning both no free space and missing data.
-  // TODO(crbug/1212890): Distinguish 0 bytes free from didn't populate field
-  // e.g. when VM is already running.
+  // notification for the default VM, if we got a value, and if the value isn't
+  // an error (the API we call for space returns -1 on error).
   if (vm_name == ContainerId::GetDefault().vm_name &&
-      response->free_bytes() > 0) {
+      response->free_bytes_has_value() && response->free_bytes() >= 0) {
     low_disk_notifier_->ShowNotificationIfAppropriate(response->free_bytes());
   }
 
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
index d7e1df7..7dc66893 100644
--- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -512,7 +512,8 @@
   const base::FilePath& disk_path = base::FilePath(kVmName);
   NotificationDisplayServiceTester notification_service(nullptr);
   vm_tools::concierge::StartVmResponse response;
-  response.set_free_bytes(1);
+  response.set_free_bytes(0);
+  response.set_free_bytes_has_value(true);
   response.set_success(true);
   response.set_status(::vm_tools::concierge::VmStatus::VM_STATUS_RUNNING);
   fake_concierge_client_->set_start_vm_response(response);
@@ -528,6 +529,28 @@
   EXPECT_NE(absl::nullopt, notification);
 }
 
+TEST_F(CrostiniManagerTest,
+       StartTerminaVmLowDiskNotificationNotShownIfNoValue) {
+  const base::FilePath& disk_path = base::FilePath(kVmName);
+  NotificationDisplayServiceTester notification_service(nullptr);
+  vm_tools::concierge::StartVmResponse response;
+  response.set_free_bytes(1234);
+  response.set_free_bytes_has_value(false);
+  response.set_success(true);
+  response.set_status(::vm_tools::concierge::VmStatus::VM_STATUS_RUNNING);
+  fake_concierge_client_->set_start_vm_response(response);
+
+  EnsureTerminaInstalled();
+  crostini_manager()->StartTerminaVm(
+      ContainerId::GetDefault().vm_name, disk_path, 0,
+      base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure()));
+  run_loop()->Run();
+
+  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  auto notification = notification_service.GetNotification("crostini_low_disk");
+  EXPECT_EQ(absl::nullopt, notification);
+}
+
 TEST_F(CrostiniManagerTest, OnStartTremplinRecordsRunningVm) {
   const base::FilePath& disk_path = base::FilePath(kVmName);
   const std::string owner_id = CryptohomeIdForProfile(profile());
diff --git a/chrome/browser/ash/dbus/chrome_features_service_provider.cc b/chrome/browser/ash/dbus/chrome_features_service_provider.cc
index b678829..0a2874f 100644
--- a/chrome/browser/ash/dbus/chrome_features_service_provider.cc
+++ b/chrome/browser/ash/dbus/chrome_features_service_provider.cc
@@ -162,6 +162,7 @@
       &arc::kFilePickerExperimentFeature,
       &arc::kNativeBridgeToggleFeature,
       &features::kSessionManagerLongKillTimeout,
+      &features::kSessionManagerLivenessCheck,
   };
 
   dbus::MessageReader reader(method_call);
diff --git a/chrome/browser/ash/login/app_mode/auto_launched_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/auto_launched_kiosk_browsertest.cc
index 9af30d98..1939d8e 100644
--- a/chrome/browser/ash/login/app_mode/auto_launched_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/auto_launched_kiosk_browsertest.cc
@@ -47,12 +47,11 @@
 #include "extensions/test/result_catcher.h"
 #include "net/dns/mock_host_resolver.h"
 
-namespace em = enterprise_management;
-
-namespace chromeos {
-
+namespace ash {
 namespace {
 
+namespace em = ::enterprise_management;
+
 // This is a simple test that only sends an extension message when app launch is
 // requested. Webstore data json is in
 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
@@ -405,4 +404,4 @@
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc
index d78fa00..2000cf5 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc
@@ -127,14 +127,13 @@
 #include "ui/base/page_transition_types.h"
 #include "ui/events/test/event_generator.h"
 
-using extensions::mojom::ManifestLocation;
-
-namespace em = enterprise_management;
-
-namespace chromeos {
-
+namespace ash {
 namespace {
 
+using ::extensions::mojom::ManifestLocation;
+
+namespace em = ::enterprise_management;
+
 const test::UIPath kConfigNetwork = {"app-launch-splash", "configNetwork"};
 const test::UIPath kAutolaunchConfirmButton = {"autolaunch", "confirmButton"};
 const test::UIPath kAutolaunchCancelButton = {"autolaunch", "cancelButton"};
@@ -546,7 +545,7 @@
   }
 
   bool LaunchApp(const std::string& app_id) {
-    return ash::LoginScreenTestApi::LaunchApp(app_id);
+    return LoginScreenTestApi::LaunchApp(app_id);
   }
 
   void ReloadKioskApps() {
@@ -579,9 +578,9 @@
 
   void PrepareAppLaunch() {
     // Wait for the Kiosk App configuration to reload.
-    int ui_update_count = ash::LoginScreenTestApi::GetUiUpdateCount();
+    int ui_update_count = LoginScreenTestApi::GetUiUpdateCount();
     ReloadKioskApps();
-    ash::LoginScreenTestApi::WaitForUiUpdate(ui_update_count);
+    LoginScreenTestApi::WaitForUiUpdate(ui_update_count);
   }
 
   void StartAppLaunchFromLoginScreen(
@@ -623,8 +622,7 @@
     EXPECT_TRUE(static_cast<ProfileImpl*>(app_profile)->chromeos_preferences_);
 
     // Check installer status.
-    EXPECT_EQ(chromeos::KioskAppLaunchError::Error::kNone,
-              chromeos::KioskAppLaunchError::Get());
+    EXPECT_EQ(KioskAppLaunchError::Error::kNone, KioskAppLaunchError::Get());
 
     // Check if the kiosk webapp is really installed for the default profile.
     const extensions::Extension* app =
@@ -719,16 +717,16 @@
     static_cast<AppLaunchSplashScreenView::Delegate*>(
         GetKioskLaunchController())
         ->OnConfigureNetwork();
-    EXPECT_FALSE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+    EXPECT_FALSE(LoginScreenTestApi::IsOobeDialogVisible());
     // There should be only one owner pod on this screen.
-    EXPECT_EQ(ash::LoginScreenTestApi::GetUsersCount(), 1);
+    EXPECT_EQ(LoginScreenTestApi::GetUsersCount(), 1);
 
     // A network error screen should be shown after authenticating.
     OobeScreenWaiter error_screen_waiter(ErrorScreenView::kScreenId);
-    ash::LoginScreenTestApi::SubmitPassword(test_owner_account_id_, "password",
-                                            /*check_if_submittable=*/true);
+    LoginScreenTestApi::SubmitPassword(test_owner_account_id_, "password",
+                                       /*check_if_submittable=*/true);
     error_screen_waiter.Wait();
-    EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+    EXPECT_TRUE(LoginScreenTestApi::IsOobeDialogVisible());
 
     ASSERT_TRUE(GetKioskLaunchController()->showing_network_dialog());
 
@@ -877,7 +875,7 @@
   EXPECT_TRUE(user_manager->IsLoggedInAsKioskApp());
 
   keyboard::KeyboardConfig config =
-      ash::KeyboardController::Get()->GetKeyboardConfig();
+      KeyboardController::Get()->GetKeyboardConfig();
   EXPECT_TRUE(config.auto_capitalize);
   EXPECT_TRUE(config.auto_complete);
   EXPECT_TRUE(config.auto_correct);
@@ -894,7 +892,7 @@
   EXPECT_TRUE(app_window_loaded_listener.WaitUntilSatisfied());
 
   // The shelf should be hidden at the beginning.
-  EXPECT_FALSE(ash::ShelfTestApi().IsVisible());
+  EXPECT_FALSE(ShelfTestApi().IsVisible());
 
   // Simulate the swipe-up gesture.
   Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
@@ -910,14 +908,14 @@
   const gfx::Rect display_bounds = window->bounds();
   const gfx::Point start_point = gfx::Point(
       display_bounds.width() / 4,
-      display_bounds.bottom() - ash::ShelfConfig::Get()->shelf_size() / 2);
+      display_bounds.bottom() - ShelfConfig::Get()->shelf_size() / 2);
   gfx::Point end_point(start_point.x(), start_point.y() - 80);
   ui::test::EventGenerator event_generator(window);
   event_generator.GestureScrollSequence(
       start_point, end_point, base::TimeDelta::FromMilliseconds(500), 4);
 
   // The shelf should be still hidden after the gesture.
-  EXPECT_FALSE(ash::ShelfTestApi().IsVisible());
+  EXPECT_FALSE(ShelfTestApi().IsVisible());
 }
 
 IN_PROC_BROWSER_TEST_F(KioskDeviceOwnedTest, ZoomSupport) {
@@ -1030,7 +1028,7 @@
   // Simulate Ctrl+Alt+N accelerator.
 
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kAppLaunchNetworkConfig);
+      LoginAcceleratorAction::kAppLaunchNetworkConfig);
   error_screen_waiter.Wait();
   ASSERT_TRUE(GetKioskLaunchController()->showing_network_dialog());
 
@@ -1104,10 +1102,10 @@
       chrome::NOTIFICATION_APP_TERMINATING,
       content::NotificationService::AllSources());
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kAppLaunchBailout);
+      LoginAcceleratorAction::kAppLaunchBailout);
   signal.Wait();
-  EXPECT_EQ(chromeos::KioskAppLaunchError::Error::kUserCancel,
-            chromeos::KioskAppLaunchError::Get());
+  EXPECT_EQ(KioskAppLaunchError::Error::kUserCancel,
+            KioskAppLaunchError::Get());
 }
 
 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) {
@@ -1182,7 +1180,7 @@
   wizard_controller->SkipToLoginForTesting();
   OobeScreenWaiter(GaiaView::kScreenId).Wait();
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kEnableConsumerKiosk);
+      LoginAcceleratorAction::kEnableConsumerKiosk);
 
   // Wait for the kiosk_enable screen to show and cancel the screen.
   OobeScreenWaiter(KioskEnableScreenView::kScreenId).Wait();
@@ -1210,7 +1208,7 @@
   wizard_controller->SkipToLoginForTesting();
   OobeScreenWaiter(GaiaView::kScreenId).Wait();
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kEnableConsumerKiosk);
+      LoginAcceleratorAction::kEnableConsumerKiosk);
 
   // Wait for the kiosk_enable screen to show and enable kiosk.
   OobeScreenWaiter(KioskEnableScreenView::kScreenId).Wait();
@@ -1239,7 +1237,7 @@
   wizard_controller->SkipToLoginForTesting();
   OobeScreenWaiter(GaiaView::kScreenId).Wait();
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kEnableConsumerKiosk);
+      LoginAcceleratorAction::kEnableConsumerKiosk);
 
   // Wait for the kiosk_enable screen to show and cancel the screen.
   OobeScreenWaiter(KioskEnableScreenView::kScreenId).Wait();
@@ -1254,7 +1252,7 @@
 
   // Show kiosk enable screen again.
   LoginDisplayHost::default_host()->HandleAccelerator(
-      ash::LoginAcceleratorAction::kEnableConsumerKiosk);
+      LoginAcceleratorAction::kEnableConsumerKiosk);
 
   // And it should show up.
   OobeScreenWaiter(KioskEnableScreenView::kScreenId).Wait();
@@ -2534,8 +2532,7 @@
   KioskSessionInitializedWaiter().Wait();
 
   // Check installer status.
-  EXPECT_EQ(chromeos::KioskAppLaunchError::Error::kNone,
-            chromeos::KioskAppLaunchError::Get());
+  EXPECT_EQ(KioskAppLaunchError::Error::kNone, KioskAppLaunchError::Get());
   EXPECT_EQ(ManifestLocation::kExternalPolicy, GetInstalledAppLocation());
 
   // Wait for the window to appear.
@@ -2717,7 +2714,7 @@
   EXPECT_TRUE(config.handwriting);
   EXPECT_TRUE(config.spell_check);
   EXPECT_TRUE(config.voice_input);
-  ash::KeyboardController::Get()->SetKeyboardConfig(config);
+  KeyboardController::Get()->SetKeyboardConfig(config);
 
   extensions::ResultCatcher catcher;
   StartAppLaunchFromLoginScreen(
@@ -2728,7 +2725,7 @@
 // Specialized test fixture for testing kiosk mode on the
 // hidden WebUI initialization flow for slow hardware.
 class KioskHiddenWebUITest : public KioskTest,
-                             public ash::WallpaperControllerObserver {
+                             public WallpaperControllerObserver {
  public:
   KioskHiddenWebUITest() = default;
 
@@ -2753,7 +2750,7 @@
 
   bool wallpaper_loaded() const { return wallpaper_loaded_; }
 
-  // ash::WallpaperControllerObserver:
+  // WallpaperControllerObserver:
   void OnWallpaperChanged() override {
     wallpaper_loaded_ = true;
     if (runner_.get())
@@ -2846,7 +2843,7 @@
 
 IN_PROC_BROWSER_TEST_F(KioskAutoLaunchViewsTest, ShowAutoLaunchScreen) {
   OobeScreenWaiter(KioskAutolaunchScreenView::kScreenId).Wait();
-  EXPECT_TRUE(ash::LoginScreenTestApi::IsOobeDialogVisible());
+  EXPECT_TRUE(LoginScreenTestApi::IsOobeDialogVisible());
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
index a0b9b39..bbe8462 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
@@ -215,10 +215,4 @@
 using ::ash::KioskLaunchController;
 }
 
-// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
-// source migration is finished.
-namespace ash {
-using ::chromeos::KioskLaunchController;
-}
-
 #endif  // CHROME_BROWSER_ASH_LOGIN_APP_MODE_KIOSK_LAUNCH_CONTROLLER_H_
diff --git a/chrome/browser/ash/login/app_mode/web_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/web_kiosk_browsertest.cc
index 8774edc..014a911 100644
--- a/chrome/browser/ash/login/app_mode/web_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/web_kiosk_browsertest.cc
@@ -32,8 +32,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/test/event_generator.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 const char kAppInstallUrl[] = "https://app.com/install";
@@ -42,8 +41,6 @@
 const test::UIPath kNetworkConfigureScreenContinueButton = {"error-message",
                                                             "continueButton"};
 
-}  // namespace
-
 class WebKioskTest : public OobeBaseTest {
  public:
   WebKioskTest()
@@ -82,11 +79,11 @@
             kAppInstallUrl)};
 
     settings_ = std::make_unique<ScopedDeviceSettings>();
-    int ui_update_count = ash::LoginScreenTestApi::GetUiUpdateCount();
+    int ui_update_count = LoginScreenTestApi::GetUiUpdateCount();
     policy::SetDeviceLocalAccounts(settings_->owner_settings_service(),
                                    device_local_accounts);
     // Wait for the Kiosk App configuration to reload.
-    ash::LoginScreenTestApi::WaitForUiUpdate(ui_update_count);
+    LoginScreenTestApi::WaitForUiUpdate(ui_update_count);
   }
 
   void MakeAppAlreadyInstalled() {
@@ -98,7 +95,7 @@
   }
 
   bool LaunchApp() {
-    return ash::LoginScreenTestApi::LaunchApp(
+    return LoginScreenTestApi::LaunchApp(
         WebKioskAppManager::Get()->GetAppByAccountId(account_id())->app_id());
   }
 
@@ -136,7 +133,7 @@
 
   void ExpectKeyboardConfig() {
     const keyboard::KeyboardConfig config =
-        ash::KeyboardController::Get()->GetKeyboardConfig();
+        KeyboardController::Get()->GetKeyboardConfig();
 
     // `auto_capitalize` is not controlled by the policy
     // 'VirtualKeyboardFeatures', and its default value remains true.
@@ -254,7 +251,7 @@
   KioskSessionInitializedWaiter().Wait();
 
   // The shelf should be hidden at the beginning.
-  EXPECT_FALSE(ash::ShelfTestApi().IsVisible());
+  EXPECT_FALSE(ShelfTestApi().IsVisible());
 
   // Simulate the swipe-up gesture.
   EXPECT_EQ(BrowserList::GetInstance()->size(), 1U);
@@ -263,14 +260,14 @@
   const gfx::Rect display_bounds = window->bounds();
   const gfx::Point start_point = gfx::Point(
       display_bounds.width() / 4,
-      display_bounds.bottom() - ash::ShelfConfig::Get()->shelf_size() / 2);
+      display_bounds.bottom() - ShelfConfig::Get()->shelf_size() / 2);
   gfx::Point end_point(start_point.x(), start_point.y() - 80);
   ui::test::EventGenerator event_generator(window);
   event_generator.GestureScrollSequence(
       start_point, end_point, base::TimeDelta::FromMilliseconds(500), 4);
 
   // The shelf should be still hidden after the gesture.
-  EXPECT_FALSE(ash::ShelfTestApi().IsVisible());
+  EXPECT_FALSE(ShelfTestApi().IsVisible());
 }
 
 IN_PROC_BROWSER_TEST_F(WebKioskTest, KeyboardConfigPolicy) {
@@ -298,4 +295,5 @@
   ASSERT_TRUE(settings_browser);
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/challenge_response_auth_keys_loader.h b/chrome/browser/ash/login/challenge_response_auth_keys_loader.h
index 82daf85..b4b48e5 100644
--- a/chrome/browser/ash/login/challenge_response_auth_keys_loader.h
+++ b/chrome/browser/ash/login/challenge_response_auth_keys_loader.h
@@ -93,4 +93,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ChallengeResponseAuthKeysLoader;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_CHALLENGE_RESPONSE_AUTH_KEYS_LOADER_H_
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
index 3651d31..c3012e22 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.cc
@@ -43,7 +43,7 @@
       base::Owned(remote_devices.DeepCopy()), base::Passed(&callback));
 
   // Private TPM key is needed only when adding new keys.
-  if (remote_devices.empty() ||
+  if (remote_devices.GetList().empty() ||
       tpm_key_manager->PrepareTpmKey(/*check_private_key=*/false,
                                      do_refresh_keys)) {
     do_refresh_keys.Run();
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
index 4e8f52ed..e6ff815 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_service_regular.cc
@@ -281,7 +281,7 @@
 
   DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
                                       prefs::kEasyUnlockPairing);
-  if (devices.empty())
+  if (devices.GetList().empty())
     pairing_update->RemoveKey(kKeyDevices);
   else
     pairing_update->SetKey(kKeyDevices, devices.Clone());
diff --git a/chrome/browser/ash/login/eula_browsertest.cc b/chrome/browser/ash/login/eula_browsertest.cc
index 22afdced..e9857cc0 100644
--- a/chrome/browser/ash/login/eula_browsertest.cc
+++ b/chrome/browser/ash/login/eula_browsertest.cc
@@ -350,13 +350,8 @@
           1)));
 }
 
-#if defined(OS_CHROMEOS) && defined(NDEBUG)
-#define MAYBE_AdditionalToS DISABLED_AdditionalToS
-#else
-#define MAYBE_AdditionalToS AdditionalToS
-#endif
 // Tests that "Additional ToS" dialog could be opened and closed.
-IN_PROC_BROWSER_TEST_F(EulaTest, MAYBE_AdditionalToS) {
+IN_PROC_BROWSER_TEST_F(EulaTest, AdditionalToS) {
   base::HistogramTester histogram_tester;
   ShowEulaScreen();
 
@@ -374,7 +369,8 @@
       .CreateWaiter(test::GetOobeElementPath(kAdditionalTermsDialog) +
                     ".open === false")
       ->Wait();
-  test::OobeJS().ExpectFocused(kAdditionalTermsLink);
+
+  test::OobeJS().CreateFocusWaiter(kAdditionalTermsLink)->Wait();
 
   EXPECT_THAT(
       histogram_tester.GetAllSamples("OOBE.EulaScreen.UserActions"),
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc
index 3eb8f8b..f54c52d 100644
--- a/chrome/browser/ash/login/existing_user_controller.cc
+++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -64,6 +64,8 @@
 #include "chrome/browser/chromeos/boot_times_recorder.h"
 #include "chrome/browser/chromeos/policy/handlers/minimum_version_policy_handler.h"
 #include "chrome/browser/chromeos/policy/handlers/powerwash_requirements_checker.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/lifetime/browser_shutdown.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
@@ -552,6 +554,8 @@
 // ExistingUserController, private:
 
 ExistingUserController::~ExistingUserController() {
+  if (browser_shutdown::IsTryingToQuit() || chrome::IsAttemptingShutdown())
+    return;
   CHECK(UserSessionManager::GetInstance());
   UserSessionManager::GetInstance()->DelegateDeleted(this);
 }
diff --git a/chrome/browser/ash/login/lock/fingerprint_unlock_browsertest.cc b/chrome/browser/ash/login/lock/fingerprint_unlock_browsertest.cc
index b352d0a..e0dcb24 100644
--- a/chrome/browser/ash/login/lock/fingerprint_unlock_browsertest.cc
+++ b/chrome/browser/ash/login/lock/fingerprint_unlock_browsertest.cc
@@ -27,7 +27,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 using QuickUnlockStorage = quick_unlock::QuickUnlockStorage;
@@ -153,8 +153,6 @@
   DISALLOW_COPY_AND_ASSIGN(FingerprintUnlockTest);
 };
 
-}  // namespace
-
 IN_PROC_BROWSER_TEST_F(FingerprintUnlockTest, FingerprintNotTimedOutTest) {
   // Show lock screen and wait until it is shown.
   ScreenLockerTester tester;
@@ -345,4 +343,5 @@
       static_cast<int>(quick_unlock::FingerprintUnlockResult::kMatchFailed), 1);
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/lock_screen_browsertest.cc b/chrome/browser/ash/login/lock/lock_screen_browsertest.cc
index 646c8b1..83797cc 100644
--- a/chrome/browser/ash/login/lock/lock_screen_browsertest.cc
+++ b/chrome/browser/ash/login/lock/lock_screen_browsertest.cc
@@ -16,7 +16,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 class LockScreenBaseTest : public LoginManagerTest {
@@ -75,12 +75,12 @@
 
   ScreenLockerTester locker_tester;
   locker_tester.Lock();
-  EXPECT_EQ(2, ash::LoginScreenTestApi::GetUsersCount());
+  EXPECT_EQ(2, LoginScreenTestApi::GetUsersCount());
   // IME state should be lock screen specific.
   EXPECT_NE(ime_states[0], input_manager->GetActiveIMEState());
   EXPECT_NE(ime_states[1], input_manager->GetActiveIMEState());
 
-  EXPECT_EQ(users[0].account_id, ash::LoginScreenTestApi::GetFocusedUser());
+  EXPECT_EQ(users[0].account_id, LoginScreenTestApi::GetFocusedUser());
   EXPECT_EQ(input_manager->GetActiveIMEState()->GetCurrentInputMethod().id(),
             user_input_methods_[0]);
   locker_tester.UnlockWithPassword(users[0].account_id, "password");
@@ -92,15 +92,15 @@
             user_input_methods_[0]);
 
   locker_tester.Lock();
-  EXPECT_EQ(2, ash::LoginScreenTestApi::GetUsersCount());
+  EXPECT_EQ(2, LoginScreenTestApi::GetUsersCount());
   // IME state should be lock screen specific.
   EXPECT_NE(ime_states[0], input_manager->GetActiveIMEState());
   EXPECT_NE(ime_states[1], input_manager->GetActiveIMEState());
 
-  EXPECT_EQ(users[0].account_id, ash::LoginScreenTestApi::GetFocusedUser());
+  EXPECT_EQ(users[0].account_id, LoginScreenTestApi::GetFocusedUser());
   EXPECT_EQ(input_manager->GetActiveIMEState()->GetCurrentInputMethod().id(),
             user_input_methods_[0]);
-  EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(users[1].account_id));
+  EXPECT_TRUE(LoginScreenTestApi::FocusUser(users[1].account_id));
   EXPECT_EQ(input_manager->GetActiveIMEState()->GetCurrentInputMethod().id(),
             user_input_methods_[1]);
   locker_tester.UnlockWithPassword(users[1].account_id, "password");
@@ -234,4 +234,4 @@
 }
 
 }  // namespace
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/screen_locker.cc b/chrome/browser/ash/login/lock/screen_locker.cc
index f605f306..250319a 100644
--- a/chrome/browser/ash/login/lock/screen_locker.cc
+++ b/chrome/browser/ash/login/lock/screen_locker.cc
@@ -74,11 +74,11 @@
 #include "ui/gfx/image/image.h"
 #include "url/gurl.h"
 
-using base::UserMetricsAction;
-namespace chromeos {
-
+namespace ash {
 namespace {
 
+using ::base::UserMetricsAction;
+
 // Returns true if fingerprint authentication is available for `user`.
 bool IsFingerprintAvailableForUser(const user_manager::User* user) {
   quick_unlock::QuickUnlockStorage* quick_unlock_storage =
@@ -211,7 +211,7 @@
 
   // Create and display lock screen.
   CHECK(LoginScreenClientImpl::HasInstance());
-  ash::LoginScreen::Get()->ShowLockScreen();
+  LoginScreen::Get()->ShowLockScreen();
   views_screen_locker_->Init();
 
   content::NotificationService::current()->Notify(
@@ -315,7 +315,7 @@
   weak_factory_.InvalidateWeakPtrs();
 
   VLOG(1) << "Hiding the lock screen.";
-  chromeos::ScreenLocker::Hide();
+  ScreenLocker::Hide();
 }
 
 void ScreenLocker::OnPasswordAuthSuccess(const UserContext& user_context) {
@@ -336,12 +336,12 @@
   CHECK(user) << "Invalid user - cannot enable authentication.";
 
   users_with_temporarily_disabled_auth_.erase(account_id);
-  ash::LoginScreen::Get()->GetModel()->EnableAuthForUser(account_id);
+  LoginScreen::Get()->GetModel()->EnableAuthForUser(account_id);
 }
 
 void ScreenLocker::TemporarilyDisableAuthForUser(
     const AccountId& account_id,
-    const ash::AuthDisabledData& auth_disabled_data) {
+    const AuthDisabledData& auth_disabled_data) {
   if (IsAuthTemporarilyDisabledForUser(account_id))
     return;
 
@@ -349,8 +349,8 @@
   CHECK(user) << "Invalid user - cannot disable authentication.";
 
   users_with_temporarily_disabled_auth_.insert(account_id);
-  ash::LoginScreen::Get()->GetModel()->DisableAuthForUser(account_id,
-                                                          auth_disabled_data);
+  LoginScreen::Get()->GetModel()->DisableAuthForUser(account_id,
+                                                     auth_disabled_data);
 }
 
 void ScreenLocker::Authenticate(const UserContext& user_context,
@@ -507,8 +507,7 @@
 
 void ScreenLocker::OnStartLockCallback(bool locked) {
   // Happens in tests that exit with a pending lock. In real lock failure,
-  // ash::LockStateController would cause the current user session to be
-  // terminated.
+  // LockStateController would cause the current user session to be terminated.
   if (!locked)
     return;
 
@@ -671,7 +670,7 @@
       user_manager::UserManager::Get()->FindUser(user_context.GetAccountId());
   if (!user || !user->is_active())
     return;
-  Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(user);
+  auto* profile = ProfileHelper::Get()->GetProfileByUser(user);
   if (profile)
     login::SaveSyncPasswordDataToProfile(user_context, profile);
 }
@@ -826,7 +825,7 @@
   }
   quick_unlock_storage->fingerprint_storage()->RecordFingerprintUnlockResult(
       quick_unlock::FingerprintUnlockResult::kSuccess);
-  ash::LoginScreen::Get()->GetModel()->NotifyFingerprintAuthResult(
+  LoginScreen::Get()->GetModel()->NotifyFingerprintAuthResult(
       primary_user->GetAccountId(), true /*success*/);
   VLOG(1) << "Fingerprint unlock is successful.";
   OnAuthSuccess(user_context);
@@ -845,7 +844,7 @@
 void ScreenLocker::OnFingerprintAuthFailure(const user_manager::User& user) {
   UMA_HISTOGRAM_ENUMERATION("ScreenLocker.AuthenticationFailure",
                             unlock_attempt_type_, UnlockType::AUTH_COUNT);
-  ash::LoginScreen::Get()->GetModel()->NotifyFingerprintAuthResult(
+  LoginScreen::Get()->GetModel()->NotifyFingerprintAuthResult(
       user.GetAccountId(), false /*success*/);
 
   quick_unlock::QuickUnlockStorage* quick_unlock_storage =
@@ -856,8 +855,8 @@
     if (quick_unlock_storage->fingerprint_storage()->ExceededUnlockAttempts()) {
       VLOG(1) << "Fingerprint unlock is disabled because it reached maximum"
               << " unlock attempt.";
-      ash::LoginScreen::Get()->GetModel()->SetFingerprintState(
-          user.GetAccountId(), ash::FingerprintState::DISABLED_FROM_ATTEMPTS);
+      LoginScreen::Get()->GetModel()->SetFingerprintState(
+          user.GetAccountId(), FingerprintState::DISABLED_FROM_ATTEMPTS);
       delegate_->ShowErrorMessage(IDS_LOGIN_ERROR_FINGERPRINT_MAX_ATTEMPT,
                                   HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
     }
@@ -903,8 +902,8 @@
       if (quick_unlock_storage->fingerprint_storage()
               ->IsFingerprintAvailable()) {
         VLOG(1) << "Require strong auth to make fingerprint unlock available.";
-        ash::LoginScreen::Get()->GetModel()->SetFingerprintState(
-            account_id, ash::FingerprintState::DISABLED_FROM_TIMEOUT);
+        LoginScreen::Get()->GetModel()->SetFingerprintState(
+            account_id, FingerprintState::DISABLED_FROM_TIMEOUT);
         fp_service_->EndCurrentAuthSession(base::BindOnce([](bool success) {
           if (success)
             return;
@@ -917,8 +916,8 @@
 
 void ScreenLocker::OnPinCanAuthenticate(const AccountId& account_id,
                                         bool can_authenticate) {
-  ash::LoginScreen::Get()->GetModel()->SetPinEnabledForUser(account_id,
-                                                            can_authenticate);
+  LoginScreen::Get()->GetModel()->SetPinEnabledForUser(account_id,
+                                                       can_authenticate);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/screen_locker.h b/chrome/browser/ash/login/lock/screen_locker.h
index f47f7373..a3bc2e6 100644
--- a/chrome/browser/ash/login/lock/screen_locker.h
+++ b/chrome/browser/ash/login/lock/screen_locker.h
@@ -23,7 +23,11 @@
 #include "chrome/browser/ash/login/security_token_pin_dialog_host_ash_impl.h"
 #include "chrome/browser/ash/login/ui/login_display.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chromeos/login/auth/authenticator.h"
 #include "chromeos/login/auth/challenge_response_key.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chromeos/login/auth/extended_authenticator.h"
 #include "chromeos/login/auth/user_context.h"
 #include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
@@ -34,10 +38,7 @@
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 
-namespace chromeos {
-
-class Authenticator;
-class ExtendedAuthenticator;
+namespace ash {
 class ViewsScreenLocker;
 
 // ScreenLocker displays the lock UI and takes care of authenticating the user
@@ -93,7 +94,7 @@
   // screen UI. `auth_disabled_data` is used to display information in the UI.
   void TemporarilyDisableAuthForUser(
       const AccountId& account_id,
-      const ash::AuthDisabledData& auth_disabled_data);
+      const AuthDisabledData& auth_disabled_data);
 
   // Reenables authentication for the user with `account_id` previously disabled
   // by `TemporarilyDisableAuthForUser`. Notifies lock screen UI.
@@ -322,11 +323,11 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenLocker);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 // TODO(https://crbug.com/1164001): remove when //c/b/ash/login moved to ash.
-namespace ash {
-using ::chromeos::ScreenLocker;
-}  // namespace ash
+namespace chromeos {
+using ::ash::ScreenLocker;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_LOCK_SCREEN_LOCKER_H_
diff --git a/chrome/browser/ash/login/lock/screen_locker_browsertest.cc b/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
index b3c6c73..043e90ab 100644
--- a/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
+++ b/chrome/browser/ash/login/lock/screen_locker_browsertest.cc
@@ -32,7 +32,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 constexpr char kFingerprint[] = "pinky";
@@ -87,8 +87,6 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenLockerTest);
 };
 
-}  // namespace
-
 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBadThenGoodPassword) {
   ScreenLockerTester tester;
   tester.Lock();
@@ -118,8 +116,7 @@
   // auto hidden when in immersive fullscreen.
   ScreenLockerTester tester;
   BrowserWindow* browser_window = browser()->window();
-  ash::WindowState* window_state =
-      ash::WindowState::Get(browser_window->GetNativeWindow());
+  auto* window_state = WindowState::Get(browser_window->GetNativeWindow());
   {
     FullscreenNotificationObserver fullscreen_waiter(browser());
     browser()
@@ -144,7 +141,7 @@
 
   // Browser window should be activated after screen locker is gone. Otherwise,
   // the rest of the test would fail.
-  ASSERT_EQ(window_state, ash::WindowState::ForActiveWindow());
+  ASSERT_EQ(window_state, WindowState::ForActiveWindow());
 
   // 2) Similar to 1) if the active browser window is in fullscreen and the
   // fullscreen window has all of the pixels, locking the screen should exit
@@ -208,10 +205,10 @@
   // Disable authentication for user.
   ScreenLocker::default_screen_locker()->TemporarilyDisableAuthForUser(
       user_manager::StubAccountId(),
-      ash::AuthDisabledData(ash::AuthDisabledReason::kTimeWindowLimit,
-                            base::Time::Now() + base::TimeDelta::FromHours(1),
-                            base::TimeDelta::FromHours(1),
-                            true /*disable_lock_screen_media*/));
+      AuthDisabledData(AuthDisabledReason::kTimeWindowLimit,
+                       base::Time::Now() + base::TimeDelta::FromHours(1),
+                       base::TimeDelta::FromHours(1),
+                       true /*disable_lock_screen_media*/));
 
   // Try to authenticate with password.
   tester.ForceSubmitPassword(user_manager::StubAccountId(), kPassword);
@@ -246,10 +243,10 @@
   // Disable authentication for user.
   ScreenLocker::default_screen_locker()->TemporarilyDisableAuthForUser(
       user_manager::StubAccountId(),
-      ash::AuthDisabledData(ash::AuthDisabledReason::kTimeUsageLimit,
-                            base::Time::Now() + base::TimeDelta::FromHours(1),
-                            base::TimeDelta::FromHours(3),
-                            true /*disable_lock_screen_media*/));
+      AuthDisabledData(AuthDisabledReason::kTimeUsageLimit,
+                       base::Time::Now() + base::TimeDelta::FromHours(1),
+                       base::TimeDelta::FromHours(3),
+                       true /*disable_lock_screen_media*/));
 
   // Try to authenticate with fingerprint.
   AuthenticateWithFingerprint();
@@ -269,4 +266,5 @@
       1, session_manager_client()->notify_lock_screen_dismissed_call_count());
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/screen_locker_tester.cc b/chrome/browser/ash/login/lock/screen_locker_tester.cc
index 0ba872f..55d0c68 100644
--- a/chrome/browser/ash/login/lock/screen_locker_tester.cc
+++ b/chrome/browser/ash/login/lock/screen_locker_tester.cc
@@ -27,7 +27,7 @@
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
+namespace ash {
 namespace {
 
 bool IsScreenLockerLocked() {
@@ -119,31 +119,29 @@
 }
 
 bool ScreenLockerTester::IsLocked() {
-  return IsScreenLockerLocked() && ash::LoginScreenTestApi::IsLockShown();
+  return IsScreenLockerLocked() && LoginScreenTestApi::IsLockShown();
 }
 
 bool ScreenLockerTester::IsLockRestartButtonShown() {
-  return IsScreenLockerLocked() &&
-         ash::LoginScreenTestApi::IsRestartButtonShown();
+  return IsScreenLockerLocked() && LoginScreenTestApi::IsRestartButtonShown();
 }
 
 bool ScreenLockerTester::IsLockShutdownButtonShown() {
-  return IsScreenLockerLocked() &&
-         ash::LoginScreenTestApi::IsShutdownButtonShown();
+  return IsScreenLockerLocked() && LoginScreenTestApi::IsShutdownButtonShown();
 }
 
 void ScreenLockerTester::UnlockWithPassword(const AccountId& account_id,
                                             const std::string& password) {
-  ash::LoginScreenTestApi::SubmitPassword(account_id, password,
-                                          true /*check_if_submittable*/);
+  LoginScreenTestApi::SubmitPassword(account_id, password,
+                                     true /*check_if_submittable*/);
   base::RunLoop().RunUntilIdle();
 }
 
 void ScreenLockerTester::ForceSubmitPassword(const AccountId& account_id,
                                              const std::string& password) {
-  ash::LoginScreenTestApi::SubmitPassword(account_id, password,
-                                          false /*check_if_submittable*/);
+  LoginScreenTestApi::SubmitPassword(account_id, password,
+                                     false /*check_if_submittable*/);
   base::RunLoop().RunUntilIdle();
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/screen_locker_tester.h b/chrome/browser/ash/login/lock/screen_locker_tester.h
index 113a2e81..ccde14bc 100644
--- a/chrome/browser/ash/login/lock/screen_locker_tester.h
+++ b/chrome/browser/ash/login/lock/screen_locker_tester.h
@@ -11,7 +11,7 @@
 
 class AccountId;
 
-namespace chromeos {
+namespace ash {
 
 // ScreenLockerTester provides a high-level API to test the lock screen.
 class ScreenLockerTester {
@@ -49,12 +49,12 @@
   DISALLOW_COPY_AND_ASSIGN(ScreenLockerTester);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 // TODO(https://crbug.com/1164001): remove after //chrome/browser/chromeos
 // source migration is finished.
-namespace ash {
-using ::chromeos::ScreenLockerTester;
-}  // namespace ash
+namespace chromeos {
+using ::ash::ScreenLockerTester;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_LOCK_SCREEN_LOCKER_TESTER_H_
diff --git a/chrome/browser/ash/login/lock/screen_locker_unittest.cc b/chrome/browser/ash/login/lock/screen_locker_unittest.cc
index 3bd7102..e393eea 100644
--- a/chrome/browser/ash/login/lock/screen_locker_unittest.cc
+++ b/chrome/browser/ash/login/lock/screen_locker_unittest.cc
@@ -56,8 +56,7 @@
 #include "services/audio/public/cpp/sounds/test_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
-
+namespace ash {
 namespace {
 
 std::unique_ptr<KeyedService> CreateCertificateProviderService(
@@ -65,8 +64,6 @@
   return std::make_unique<chromeos::CertificateProviderService>();
 }
 
-}  // namespace
-
 class ScreenLockerUnitTest : public testing::Test {
  public:
   ScreenLockerUnitTest() = default;
@@ -112,7 +109,7 @@
     AccessibilityManager::Initialize();
 
     // Initialize ScreenLocker dependencies:
-    chromeos::ProfileHelper::GetSigninProfile();
+    ProfileHelper::GetSigninProfile();
     SystemSaltGetter::Initialize();
   }
 
@@ -213,4 +210,5 @@
   base::RunLoop().RunUntilIdle();
 }
 
-}  // namespace chromeos
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/views_screen_locker.cc b/chrome/browser/ash/login/lock/views_screen_locker.cc
index 3027e23..36a68a59 100644
--- a/chrome/browser/ash/login/lock/views_screen_locker.cc
+++ b/chrome/browser/ash/login/lock/views_screen_locker.cc
@@ -39,7 +39,7 @@
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "ui/base/ime/chromeos/ime_keyboard.h"
 
-namespace chromeos {
+namespace ash {
 
 ViewsScreenLocker::ViewsScreenLocker(ScreenLocker* screen_locker)
     : screen_locker_(screen_locker),
@@ -66,9 +66,9 @@
 
   system_info_updater_->StartRequest();
 
-  ash::LoginScreen::Get()->GetModel()->SetUserList(
+  LoginScreen::Get()->GetModel()->SetUserList(
       user_selection_screen_->UpdateAndReturnUserListForAsh());
-  ash::LoginScreen::Get()->SetAllowLoginAsGuest(false /*show_guest*/);
+  LoginScreen::Get()->SetAllowLoginAsGuest(false /*show_guest*/);
 
   if (user_manager::UserManager::IsInitialized()) {
     // Enable pin and challenge-response authentication for any users who can
@@ -192,8 +192,7 @@
 }
 
 void ViewsScreenLocker::HandleLockScreenAppFocusOut(bool reverse) {
-  ash::LoginScreen::Get()->GetModel()->HandleFocusLeavingLockScreenApps(
-      reverse);
+  LoginScreen::Get()->GetModel()->HandleFocusLeavingLockScreenApps(reverse);
 }
 
 void ViewsScreenLocker::UpdatePinKeyboardState(const AccountId& account_id) {
@@ -206,14 +205,14 @@
     const AccountId& account_id) {
   const bool enable_challenge_response =
       ChallengeResponseAuthKeysLoader::CanAuthenticateUser(account_id);
-  ash::LoginScreen::Get()->GetModel()->SetChallengeResponseAuthEnabledForUser(
+  LoginScreen::Get()->GetModel()->SetChallengeResponseAuthEnabledForUser(
       account_id, enable_challenge_response);
 }
 
 void ViewsScreenLocker::OnPinCanAuthenticate(const AccountId& account_id,
                                              bool can_authenticate) {
-  ash::LoginScreen::Get()->GetModel()->SetPinEnabledForUser(account_id,
-                                                            can_authenticate);
+  LoginScreen::Get()->GetModel()->SetPinEnabledForUser(account_id,
+                                                       can_authenticate);
 }
 
-}  // namespace chromeos
+}  // namespace ash
diff --git a/chrome/browser/ash/login/lock/views_screen_locker.h b/chrome/browser/ash/login/lock/views_screen_locker.h
index 4210d157..e211d4b5 100644
--- a/chrome/browser/ash/login/lock/views_screen_locker.h
+++ b/chrome/browser/ash/login/lock/views_screen_locker.h
@@ -11,14 +11,15 @@
 #include "chrome/browser/ash/lock_screen_apps/focus_cycler_delegate.h"
 #include "chrome/browser/ash/login/lock/screen_locker.h"
 // TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ash/login/mojo_system_info_dispatcher.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
 #include "chrome/browser/ash/login/screens/user_selection_screen.h"
+// TODO(https://crbug.com/1164001): move to forward declaration.
+#include "chrome/browser/ash/login/user_board_view_mojo.h"
 #include "chrome/browser/ui/ash/login_screen_client_impl.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 
-namespace chromeos {
-
-class UserBoardViewMojo;
-class MojoSystemInfoDispatcher;
+namespace ash {
 
 // ViewsScreenLocker acts like LoginScreenClientImpl::Delegate which handles
 // method calls coming from ash into chrome.
@@ -95,6 +96,6 @@
   DISALLOW_COPY_AND_ASSIGN(ViewsScreenLocker);
 };
 
-}  // namespace chromeos
+}  // namespace ash
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_LOCK_VIEWS_SCREEN_LOCKER_H_
diff --git a/chrome/browser/ash/login/lock_screen_utils.cc b/chrome/browser/ash/login/lock_screen_utils.cc
index fb7fb16f..4bf6e87 100644
--- a/chrome/browser/ash/login/lock_screen_utils.cc
+++ b/chrome/browser/ash/login/lock_screen_utils.cc
@@ -118,7 +118,7 @@
   const base::ListValue* login_screen_input_methods = nullptr;
   if (!cros_settings->GetList(chromeos::kDeviceLoginScreenInputMethods,
                               &login_screen_input_methods) ||
-      login_screen_input_methods->empty()) {
+      login_screen_input_methods->GetList().empty()) {
     StopEnforcingPolicyInputMethods();
     return;
   }
diff --git a/chrome/browser/ash/login/login_auth_recorder.h b/chrome/browser/ash/login/login_auth_recorder.h
index 0a363b9..b87204e 100644
--- a/chrome/browser/ash/login/login_auth_recorder.h
+++ b/chrome/browser/ash/login/login_auth_recorder.h
@@ -84,4 +84,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::LoginAuthRecorder;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_LOGIN_AUTH_RECORDER_H_
diff --git a/chrome/browser/ash/login/mojo_system_info_dispatcher.h b/chrome/browser/ash/login/mojo_system_info_dispatcher.h
index 7c28745..a3f9acc 100644
--- a/chrome/browser/ash/login/mojo_system_info_dispatcher.h
+++ b/chrome/browser/ash/login/mojo_system_info_dispatcher.h
@@ -45,4 +45,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::MojoSystemInfoDispatcher;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_MOJO_SYSTEM_INFO_DISPATCHER_H_
diff --git a/chrome/browser/ash/login/quick_unlock/fingerprint_storage.h b/chrome/browser/ash/login/quick_unlock/fingerprint_storage.h
index 543fc5b..7449eed 100644
--- a/chrome/browser/ash/login/quick_unlock/fingerprint_storage.h
+++ b/chrome/browser/ash/login/quick_unlock/fingerprint_storage.h
@@ -98,4 +98,12 @@
 }  // namespace quick_unlock
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+namespace quick_unlock {
+using ::chromeos::quick_unlock::FingerprintUnlockResult;
+}
+}  // namespace ash
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_QUICK_UNLOCK_FINGERPRINT_STORAGE_H_
diff --git a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
index da4a5861..730df11 100644
--- a/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
+++ b/chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h
@@ -90,6 +90,8 @@
 using ::chromeos::quick_unlock::EnabledForTesting;
 using ::chromeos::quick_unlock::IsPinDisabledByPolicy;
 using ::chromeos::quick_unlock::IsPinEnabled;
+using ::chromeos::quick_unlock::PasswordConfirmationFrequency;
+using ::chromeos::quick_unlock::PasswordConfirmationFrequencyToTimeDelta;
 }  // namespace quick_unlock
 }  // namespace ash
 
diff --git a/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc b/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc
index 8b53dd1..f7c0b11a 100644
--- a/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc
+++ b/chrome/browser/ash/login/screens/lacros_data_migration_screen.cc
@@ -4,6 +4,11 @@
 
 #include "chrome/browser/ash/login/screens/lacros_data_migration_screen.h"
 
+#include "ash/constants/ash_switches.h"
+#include "base/command_line.h"
+#include "chrome/browser/ash/crosapi/browser_data_migrator.h"
+#include "chrome/browser/lifetime/application_lifetime.h"
+
 namespace ash {
 
 LacrosDataMigrationScreen::LacrosDataMigrationScreen(
@@ -31,6 +36,13 @@
   if (!view_)
     return;
 
+  const std::string user_id_hash =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+          switches::kBrowserDataMigrationForUser);
+  // Start browser data migration.
+  BrowserDataMigrator::Migrate(user_id_hash,
+                               base::BindOnce(&chrome::AttemptRestart));
+
   // Show the screen.
   view_->Show();
 }
diff --git a/chrome/browser/ash/login/screens/management_transition_screen_browsertest.cc b/chrome/browser/ash/login/screens/management_transition_screen_browsertest.cc
index cc04586..98475ee 100644
--- a/chrome/browser/ash/login/screens/management_transition_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/management_transition_screen_browsertest.cc
@@ -153,7 +153,7 @@
   EXPECT_FALSE(LoginScreenTestApi::IsAddUserButtonShown());
 
   ProfileManager::GetPrimaryUserProfile()->GetPrefs()->SetInteger(
-      arc::prefs::kArcSupervisionTransition,
+      arc::prefs::kArcManagementTransition,
       static_cast<int>(arc::ArcSupervisionTransition::NO_TRANSITION));
 
   EXPECT_FALSE(ProfileManager::GetPrimaryUserProfile()->GetPrefs()->GetBoolean(
diff --git a/chrome/browser/ash/login/screens/terms_of_service_screen.cc b/chrome/browser/ash/login/screens/terms_of_service_screen.cc
index e533dff..827a7262 100644
--- a/chrome/browser/ash/login/screens/terms_of_service_screen.cc
+++ b/chrome/browser/ash/login/screens/terms_of_service_screen.cc
@@ -299,10 +299,18 @@
 
 void TermsOfServiceScreen::SaveTos(const std::string& tos) {
   auto tos_path = GetTosFilePath();
-  base::ThreadPool::PostTask(FROM_HERE,
-                             {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
-                              base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-                             base::BindOnce(&SaveTosToFile, tos, tos_path));
+  base::ThreadPool::PostTaskAndReply(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+      base::BindOnce(&SaveTosToFile, tos, tos_path),
+      base::BindOnce(&TermsOfServiceScreen::OnTosSavedForTesting,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void TermsOfServiceScreen::OnTosSavedForTesting() {
+  if (tos_saved_for_testing_)
+    std::move(tos_saved_for_testing_).Run();
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/terms_of_service_screen.h b/chrome/browser/ash/login/screens/terms_of_service_screen.h
index 9cf160a..0966eaf 100644
--- a/chrome/browser/ash/login/screens/terms_of_service_screen.h
+++ b/chrome/browser/ash/login/screens/terms_of_service_screen.h
@@ -54,6 +54,11 @@
   // Called when view is destroyed so there is no dead reference to it.
   void OnViewDestroyed(TermsOfServiceScreenView* view);
 
+  // Set callback to wait for file saving in tests.
+  void set_tos_saved_callback_for_testing(base::OnceClosure callback) {
+    tos_saved_for_testing_ = std::move(callback);
+  }
+
   void set_exit_callback_for_testing(const ScreenExitCallback& exit_callback) {
     exit_callback_ = exit_callback;
   }
@@ -64,7 +69,6 @@
 
   // Get path for a user terms of service file.
   static base::FilePath GetTosFilePath();
-
  private:
   // BaseScreen:
   bool MaybeSkip(WizardContext* context) override;
@@ -87,9 +91,12 @@
   void OnTosLoadedFromFile(absl::optional<std::string> tos);
   // Save terms as text to a local file.
   void SaveTos(const std::string& tos);
+  // Runs callback for tests.
+  void OnTosSavedForTesting();
 
   TermsOfServiceScreenView* view_;
   ScreenExitCallback exit_callback_;
+  base::OnceClosure tos_saved_for_testing_;
 
   std::unique_ptr<network::SimpleURLLoader> terms_of_service_loader_;
 
diff --git a/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc b/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
index f567a73..6555f76 100644
--- a/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/terms_of_service_screen_browsertest.cc
@@ -311,10 +311,14 @@
         ->set_value(TestServerBaseUrl(embedded_test_server()));
   }
 
-  void SetUpExitCallback() {
-    TermsOfServiceScreen* screen = static_cast<TermsOfServiceScreen*>(
+  TermsOfServiceScreen* GetTosScreen() {
+    return static_cast<TermsOfServiceScreen*>(
         WizardController::default_controller()->screen_manager()->GetScreen(
             TermsOfServiceScreenView::kScreenId));
+  }
+
+  void SetUpExitCallback() {
+    auto* screen = GetTosScreen();
     original_callback_ = screen->get_exit_callback_for_testing();
     screen->set_exit_callback_for_testing(base::BindRepeating(
         &ManagedUserTosScreenTest::HandleScreenExit, base::Unretained(this)));
@@ -387,7 +391,6 @@
 
 IN_PROC_BROWSER_TEST_F(ManagedUserTosScreenTest, Accepted) {
   SetUpTermsOfServiceUrlPolicy();
-  EXPECT_FALSE(TosFileExists());
   StartManagedUserSession();
 
   WaitFosScreenShown();
@@ -396,8 +399,6 @@
   test::OobeJS().TapOnPath({"terms-of-service", "acceptButton"});
   WaitForScreenExit();
 
-  EXPECT_TRUE(TosFileExists());
-  EXPECT_TRUE(SavedTosMatchString(std::string(kTosText)));
   EXPECT_EQ(result_.value(), TermsOfServiceScreen::Result::ACCEPTED);
   histogram_tester_.ExpectTotalCount(
       "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Accepted", 1);
@@ -410,7 +411,6 @@
 
 IN_PROC_BROWSER_TEST_F(ManagedUserTosScreenTest, Declined) {
   SetUpTermsOfServiceUrlPolicy();
-  EXPECT_FALSE(TosFileExists());
   StartManagedUserSession();
 
   WaitFosScreenShown();
@@ -419,8 +419,6 @@
   test::OobeJS().TapOnPath({"terms-of-service", "backButton"});
   WaitForScreenExit();
 
-  EXPECT_TRUE(TosFileExists());
-  EXPECT_TRUE(SavedTosMatchString(std::string(kTosText)));
   EXPECT_EQ(result_.value(), TermsOfServiceScreen::Result::DECLINED);
   histogram_tester_.ExpectTotalCount(
       "OOBE.StepCompletionTimeByExitReason.Terms-of-service.Accepted", 0);
@@ -431,5 +429,19 @@
   EXPECT_TRUE(session_manager_client()->session_stopped());
 }
 
+IN_PROC_BROWSER_TEST_F(ManagedUserTosScreenTest, TosSaved) {
+  SetUpTermsOfServiceUrlPolicy();
+  EXPECT_FALSE(TosFileExists());
+  base::RunLoop run_loop;
+  GetTosScreen()->set_tos_saved_callback_for_testing(run_loop.QuitClosure());
+  StartManagedUserSession();
+
+  WaitFosScreenShown();
+  run_loop.Run();
+
+  EXPECT_TRUE(TosFileExists());
+  EXPECT_TRUE(SavedTosMatchString(std::string(kTosText)));
+}
+
 }  // namespace
 }  // namespace ash
diff --git a/chrome/browser/ash/login/security_token_pin_dialog_host_ash_impl.h b/chrome/browser/ash/login/security_token_pin_dialog_host_ash_impl.h
index a04b681..ca30e20 100644
--- a/chrome/browser/ash/login/security_token_pin_dialog_host_ash_impl.h
+++ b/chrome/browser/ash/login/security_token_pin_dialog_host_ash_impl.h
@@ -65,4 +65,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::SecurityTokenPinDialogHostAshImpl;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_SECURITY_TOKEN_PIN_DIALOG_HOST_ASH_IMPL_H_
diff --git a/chrome/browser/ash/login/security_token_session_controller.cc b/chrome/browser/ash/login/security_token_session_controller.cc
index 2c1739c..01131e2 100644
--- a/chrome/browser/ash/login/security_token_session_controller.cc
+++ b/chrome/browser/ash/login/security_token_session_controller.cc
@@ -324,7 +324,7 @@
     case Behavior::kIgnore:
       return;
     case Behavior::kLock:
-      chromeos::ScreenLocker::Show();
+      ScreenLocker::Show();
       AddLockNotification();
       return;
     case Behavior::kLogout:
diff --git a/chrome/browser/ash/login/session/chrome_session_manager.cc b/chrome/browser/ash/login/session/chrome_session_manager.cc
index ba25a89..5ba8645 100644
--- a/chrome/browser/ash/login/session/chrome_session_manager.cc
+++ b/chrome/browser/ash/login/session/chrome_session_manager.cc
@@ -47,6 +47,7 @@
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
 #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
@@ -233,6 +234,14 @@
     return;
   }
 
+  if (parsed_command_line.HasSwitch(switches::kBrowserDataMigrationForUser)) {
+    VLOG(1) << "Ash is running to do browser data migration.";
+    // Show UI for browser data migration. The migration itself will be started
+    // in `LacrosDataMigrationScreen::ShowImpl`.
+    ShowLoginWizard(LacrosDataMigrationScreenView::kScreenId);
+    return;
+  }
+
   DemoSession::PreloadOfflineResourcesIfInDemoMode();
   if (parsed_command_line.HasSwitch(switches::kLoginManager) &&
       (!is_running_test || force_login_screen_in_test)) {
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc
index ba30f1e..d89865a 100644
--- a/chrome/browser/ash/login/session/user_session_manager.cc
+++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -43,6 +43,7 @@
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/base/locale_util.h"
 #include "chrome/browser/ash/child_accounts/child_policy_observer.h"
+#include "chrome/browser/ash/crosapi/browser_data_migrator.h"
 #include "chrome/browser/ash/hats/hats_config.h"
 #include "chrome/browser/ash/login/auth/chrome_cryptohome_authenticator.h"
 #include "chrome/browser/ash/login/chrome_restart_request.h"
@@ -1260,6 +1261,7 @@
     case Profile::CREATE_STATUS_CREATED:
       CHECK(profile);
       // Profile created but before initializing extensions and promo resources.
+      BrowserDataMigrator::MaybeRestartToMigrate(user_context);
       InitProfilePreferences(profile, user_context);
       break;
     case Profile::CREATE_STATUS_INITIALIZED:
@@ -1468,8 +1470,9 @@
 void UserSessionManager::UserProfileInitialized(Profile* profile,
                                                 bool is_incognito_profile,
                                                 const AccountId& account_id) {
-  // Only migrate sync prefs for existing users. New users are given the choice
-  // to turn on OS sync in OOBE, so they get the default sync pref values.
+  // Only migrate sync prefs for existing users. New users are given the
+  // choice to turn on OS sync in OOBE, so they get the default sync pref
+  // values.
   if (!IsNewProfile(profile))
     os_sync_util::MigrateOsSyncPreferences(profile->GetPrefs());
 
@@ -1494,9 +1497,9 @@
   btl->AddLoginTimeMarker("UserProfileGotten", false);
 
   // Associates AppListClient with the current active profile.
-  // Make sure AppListClient is active when AppListSyncableService builds model
-  // to avoid oem folder being created with invalid position. Note we should put
-  // this call before OAuth check in case of gaia sign in.
+  // Make sure AppListClient is active when AppListSyncableService builds
+  // model to avoid oem folder being created with invalid position. Note we
+  // should put this call before OAuth check in case of gaia sign in.
   AppListClientImpl::GetInstance()->UpdateProfile();
 
   if (user_context_.IsUsingOAuth()) {
@@ -1527,21 +1530,21 @@
     } else if (!in_session_password_change_feature_enabled ||
                user_context_.GetAuthFlow() ==
                    UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML) {
-      // These attributes are no longer relevant and should be deleted if either
-      // a) the in-session password change feature is no longer enabled or
-      // b) this user is no longer using SAML to log in.
+      // These attributes are no longer relevant and should be deleted if
+      // either a) the in-session password change feature is no longer enabled
+      // or b) this user is no longer using SAML to log in.
       SamlPasswordAttributes::DeleteFromPrefs(profile->GetPrefs());
     }
 
-    // Transfers authentication-related data from the profile that was used for
-    // authentication to the user's profile. The proxy authentication state is
-    // transferred unconditionally. If the user authenticated via an auth
-    // extension, authentication cookies will be transferred as well when the
-    // user's cookie jar is empty. If the cookie jar is not empty, the
-    // authentication states in the browser context and the user's profile must
-    // be merged using /MergeSession instead. Authentication cookies set by a
-    // SAML IdP will also be transferred when the user's cookie jar is not empty
-    // if `transfer_saml_auth_cookies_on_subsequent_login` is true.
+    // Transfers authentication-related data from the profile that was used
+    // for authentication to the user's profile. The proxy authentication
+    // state is transferred unconditionally. If the user authenticated via an
+    // auth extension, authentication cookies will be transferred as well when
+    // the user's cookie jar is empty. If the cookie jar is not empty, the
+    // authentication states in the browser context and the user's profile
+    // must be merged using /MergeSession instead. Authentication cookies set
+    // by a SAML IdP will also be transferred when the user's cookie jar is
+    // not empty if `transfer_saml_auth_cookies_on_subsequent_login` is true.
     const bool transfer_auth_cookies_on_first_login = has_auth_cookies_;
 
     content::StoragePartition* signin_partition = login::GetSigninPartition();
diff --git a/chrome/browser/ash/login/test/device_state_mixin.h b/chrome/browser/ash/login/test/device_state_mixin.h
index 7f984d6..b16ce44 100644
--- a/chrome/browser/ash/login/test/device_state_mixin.h
+++ b/chrome/browser/ash/login/test/device_state_mixin.h
@@ -128,6 +128,8 @@
 
 // TODO(https://crbug.com/1164001): remove after //chrome/browser/chromeos
 // source migration is finished.
-using chromeos::DeviceStateMixin;
+namespace ash {
+using ::chromeos::DeviceStateMixin;
+}
 
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_DEVICE_STATE_MIXIN_H_
diff --git a/chrome/browser/ash/login/test/embedded_test_server_mixin.h b/chrome/browser/ash/login/test/embedded_test_server_mixin.h
index 95f0ef17..65336286 100644
--- a/chrome/browser/ash/login/test/embedded_test_server_mixin.h
+++ b/chrome/browser/ash/login/test/embedded_test_server_mixin.h
@@ -35,4 +35,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::EmbeddedTestServerSetupMixin;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_EMBEDDED_TEST_SERVER_MIXIN_H_
diff --git a/chrome/browser/ash/login/test/oobe_window_visibility_waiter.h b/chrome/browser/ash/login/test/oobe_window_visibility_waiter.h
index 76f2c54..e5c7440 100644
--- a/chrome/browser/ash/login/test/oobe_window_visibility_waiter.h
+++ b/chrome/browser/ash/login/test/oobe_window_visibility_waiter.h
@@ -41,4 +41,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source code migration is finished.
+namespace ash {
+using ::chromeos::OobeWindowVisibilityWaiter;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_TEST_OOBE_WINDOW_VISIBILITY_WAITER_H_
diff --git a/chrome/browser/ash/login/ui/login_display_host_mojo.cc b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
index 4b22ba0..90d034e 100644
--- a/chrome/browser/ash/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
@@ -36,6 +36,7 @@
 #include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_password_changed_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_fatal_error_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/user_creation_screen_handler.h"
@@ -140,6 +141,11 @@
   ShowDialog();
 }
 
+void LoginDisplayHostMojo::StartBrowserDataMigration() {
+  DCHECK(GetOobeUI());
+  wizard_controller_->AdvanceToScreen(LacrosDataMigrationScreenView::kScreenId);
+}
+
 void LoginDisplayHostMojo::ShowAllowlistCheckFailedError() {
   DCHECK(GetOobeUI());
   GetOobeUI()->signin_screen_handler()->ShowAllowlistCheckFailedError();
diff --git a/chrome/browser/ash/login/ui/login_display_host_mojo.h b/chrome/browser/ash/login/ui/login_display_host_mojo.h
index af328f5..1985423 100644
--- a/chrome/browser/ash/login/ui/login_display_host_mojo.h
+++ b/chrome/browser/ash/login/ui/login_display_host_mojo.h
@@ -94,6 +94,7 @@
   void VerifyOwnerForKiosk(base::OnceClosure on_success) override;
   void ShowPasswordChangedDialog(const AccountId& account_id,
                                  bool show_password_error) override;
+  void StartBrowserDataMigration() override;
   void AddObserver(LoginDisplayHost::Observer* observer) override;
   void RemoveObserver(LoginDisplayHost::Observer* observer) override;
 
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.cc b/chrome/browser/ash/login/ui/login_display_host_webui.cc
index e8b2093..bfb744d5b 100644
--- a/chrome/browser/ash/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_webui.cc
@@ -72,6 +72,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/lacros_data_migration_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/browser/ui/webui/chromeos/login/user_creation_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/welcome_screen_handler.h"
@@ -242,7 +243,12 @@
   if (LoginDisplayHost::default_host()) {
     // Tests may have already allocated an instance for us to use.
     display_host = LoginDisplayHost::default_host();
-  } else if (ShouldShowSigninScreen(first_screen)) {
+  } else if (ShouldShowSigninScreen(first_screen) ||
+             first_screen == LacrosDataMigrationScreenView::kScreenId) {
+    // TODO(crbug.com/1178702): Once lacros is officially released,
+    // `ShowLoginWizard()` will no longer be called with lacros screen id.
+    // Instead simply call `SigninUI::StartBrowserDataMigration()` as part of
+    // the login flow.
     display_host = new LoginDisplayHostMojo(DisplayedScreen::SIGN_IN_SCREEN);
   } else {
     display_host = new LoginDisplayHostWebUI();
@@ -345,7 +351,7 @@
   // compatibility, if dynamically switching locales on the login screen will be
   // implemented.
   std::string login_screen_locale;
-  if (login_screen_locales->empty() ||
+  if (login_screen_locales->GetList().empty() ||
       !login_screen_locales->GetString(0, &login_screen_locale))
     return std::string();
 
@@ -449,8 +455,6 @@
   SessionManagerClient::Get()->AddObserver(this);
   CrasAudioHandler::Get()->AddAudioObserver(this);
 
-  display::Screen::GetScreen()->AddObserver(this);
-
   ui::DeviceDataManager::GetInstance()->AddObserver(this);
 
   // When we wait for WebUI to be initialized we wait for one of
@@ -475,7 +479,6 @@
 
   SessionManagerClient::Get()->RemoveObserver(this);
   CrasAudioHandler::Get()->RemoveAudioObserver(this);
-  display::Screen::GetScreen()->RemoveObserver(this);
 
   if (waiting_for_configuration_) {
     OobeConfiguration::Get()->RemoveObserver(this);
@@ -1065,6 +1068,10 @@
   NOTREACHED();
 }
 
+void LoginDisplayHostWebUI::StartBrowserDataMigration() {
+  NOTREACHED();
+}
+
 void LoginDisplayHostWebUI::AddObserver(LoginDisplayHost::Observer* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.h b/chrome/browser/ash/login/ui/login_display_host_webui.h
index 22bd15a..6cc57cb 100644
--- a/chrome/browser/ash/login/ui/login_display_host_webui.h
+++ b/chrome/browser/ash/login/ui/login_display_host_webui.h
@@ -93,6 +93,7 @@
   void VerifyOwnerForKiosk(base::OnceClosure) override;
   void ShowPasswordChangedDialog(const AccountId& account_id,
                                  bool show_password_error) override;
+  void StartBrowserDataMigration() override;
   void AddObserver(LoginDisplayHost::Observer* observer) override;
   void RemoveObserver(LoginDisplayHost::Observer* observer) override;
 
@@ -271,6 +272,8 @@
   // Measures OOBE WebUI load time.
   absl::optional<base::ElapsedTimer> oobe_load_timer_;
 
+  display::ScopedDisplayObserver display_observer_{this};
+
   base::ObserverList<LoginDisplayHost::Observer> observers_;
 
   base::WeakPtrFactory<LoginDisplayHostWebUI> weak_factory_{this};
@@ -280,4 +283,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source code migration is finished.
+namespace ash {
+using ::chromeos::LoginDisplayHostWebUI;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_UI_LOGIN_DISPLAY_HOST_WEBUI_H_
diff --git a/chrome/browser/ash/login/ui/mock_signin_ui.h b/chrome/browser/ash/login/ui/mock_signin_ui.h
index 5feffff..f298acf 100644
--- a/chrome/browser/ash/login/ui/mock_signin_ui.h
+++ b/chrome/browser/ash/login/ui/mock_signin_ui.h
@@ -39,6 +39,7 @@
               ShowSigninError,
               (SigninError, const std::string&, int),
               (override));
+  MOCK_METHOD(void, StartBrowserDataMigration, (), (override));
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ash/login/ui/signin_ui.h b/chrome/browser/ash/login/ui/signin_ui.h
index 6312a7a..8757deb 100644
--- a/chrome/browser/ash/login/ui/signin_ui.h
+++ b/chrome/browser/ash/login/ui/signin_ui.h
@@ -65,6 +65,9 @@
   virtual void ShowSigninError(SigninError error,
                                const std::string& details,
                                int login_attempts) = 0;
+
+  // Show the browser data migration UI and start the migration.
+  virtual void StartBrowserDataMigration() = 0;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ash/login/user_board_view_mojo.h b/chrome/browser/ash/login/user_board_view_mojo.h
index 749f1ab8..70591ac 100644
--- a/chrome/browser/ash/login/user_board_view_mojo.h
+++ b/chrome/browser/ash/login/user_board_view_mojo.h
@@ -51,4 +51,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::UserBoardViewMojo;
+}
+
 #endif  // CHROME_BROWSER_ASH_LOGIN_USER_BOARD_VIEW_MOJO_H_
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index fd4912c..319825d4 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -930,6 +930,10 @@
   AdvanceToScreen(ActiveDirectoryPasswordChangeView::kScreenId);
 }
 
+void WizardController::ShowLacrosDataMigrationScreen() {
+  SetCurrentScreen(GetScreen(LacrosDataMigrationScreenView::kScreenId));
+}
+
 void WizardController::OnActiveDirectoryPasswordChangeScreenExit() {
   OnScreenExit(ActiveDirectoryPasswordChangeView::kScreenId,
                kDefaultExitReason);
@@ -1903,6 +1907,8 @@
     ShowMarketingOptInScreen();
   } else if (screen_id == ManagementTransitionScreenView::kScreenId) {
     ShowManagementTransitionScreen();
+  } else if (screen_id == LacrosDataMigrationScreenView::kScreenId) {
+    ShowLacrosDataMigrationScreen();
   } else if (screen_id == TpmErrorView::kScreenId ||
              screen_id == GaiaPasswordChangedView::kScreenId ||
              screen_id == ActiveDirectoryPasswordChangeView::kScreenId ||
diff --git a/chrome/browser/ash/login/wizard_controller.h b/chrome/browser/ash/login/wizard_controller.h
index 06db29a..afbc2cb 100644
--- a/chrome/browser/ash/login/wizard_controller.h
+++ b/chrome/browser/ash/login/wizard_controller.h
@@ -286,6 +286,7 @@
   void ShowEduCoexistenceLoginScreen();
   void ShowParentalHandoffScreen();
   void ShowOsInstallScreen();
+  void ShowLacrosDataMigrationScreen();
 
   // Shows images login screen.
   void ShowLoginScreen();
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc b/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc
index 870669a0..b3995a0 100644
--- a/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/ash/policy/core/browser_policy_connector_chromeos.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h"
 
+#include <memory>
 #include <string>
 #include <utility>
 
@@ -57,6 +58,7 @@
 #include "chrome/browser/chromeos/policy/networking/device_network_configuration_updater.h"
 #include "chrome/browser/chromeos/policy/remote_commands/affiliated_remote_commands_invalidator.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h"
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_executor.h"
 #include "chrome/browser/chromeos/policy/server_backed_state/device_cloud_state_keys_uploader.h"
 #include "chrome/browser/chromeos/policy/server_backed_state/server_backed_state_keys_broker.h"
 #include "chrome/browser/chromeos/printing/bulk_printers_calculator_factory.h"
@@ -279,7 +281,9 @@
   device_scheduled_update_checker_ =
       std::make_unique<DeviceScheduledUpdateChecker>(
           ash::CrosSettings::Get(),
-          chromeos::NetworkHandler::Get()->network_state_handler());
+          chromeos::NetworkHandler::Get()->network_state_handler(),
+          std::make_unique<ScheduledTaskExecutor>(
+              update_checker_internal::kUpdateCheckTimerTag));
 
   chromeos::BulkPrintersCalculatorFactory* calculator_factory =
       chromeos::BulkPrintersCalculatorFactory::Get();
diff --git a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.cc b/chrome/browser/ash/policy/core/cached_policy_key_loader.cc
similarity index 82%
rename from chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.cc
rename to chrome/browser/ash/policy/core/cached_policy_key_loader.cc
index 58a5b48..16793efc 100644
--- a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.cc
+++ b/chrome/browser/ash/policy/core/cached_policy_key_loader.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h"
+#include "chrome/browser/ash/policy/core/cached_policy_key_loader.h"
 
 #include <stddef.h>
 
@@ -33,7 +33,7 @@
 
 }  // namespace
 
-CachedPolicyKeyLoaderChromeOS::CachedPolicyKeyLoaderChromeOS(
+CachedPolicyKeyLoader::CachedPolicyKeyLoader(
     chromeos::CryptohomeMiscClient* cryptohome_misc_client,
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     const AccountId& account_id,
@@ -43,10 +43,9 @@
       account_id_(account_id),
       user_policy_key_dir_(user_policy_key_dir) {}
 
-CachedPolicyKeyLoaderChromeOS::~CachedPolicyKeyLoaderChromeOS() {}
+CachedPolicyKeyLoader::~CachedPolicyKeyLoader() {}
 
-void CachedPolicyKeyLoaderChromeOS::EnsurePolicyKeyLoaded(
-    base::OnceClosure callback) {
+void CachedPolicyKeyLoader::EnsurePolicyKeyLoaded(base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (key_loaded_) {
@@ -70,12 +69,11 @@
       cryptohome::CreateAccountIdentifierFromAccountId(account_id_)
           .account_id());
   cryptohome_misc_client_->GetSanitizedUsername(
-      request,
-      base::BindOnce(&CachedPolicyKeyLoaderChromeOS::OnGetSanitizedUsername,
-                     weak_factory_.GetWeakPtr()));
+      request, base::BindOnce(&CachedPolicyKeyLoader::OnGetSanitizedUsername,
+                              weak_factory_.GetWeakPtr()));
 }
 
-bool CachedPolicyKeyLoaderChromeOS::LoadPolicyKeyImmediately() {
+bool CachedPolicyKeyLoader::LoadPolicyKeyImmediately() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   user_data_auth::GetSanitizedUsernameRequest request;
@@ -95,8 +93,7 @@
   return true;
 }
 
-void CachedPolicyKeyLoaderChromeOS::ReloadPolicyKey(
-    base::OnceClosure callback) {
+void CachedPolicyKeyLoader::ReloadPolicyKey(base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   key_loaded_callbacks_.push_back(std::move(callback));
@@ -117,17 +114,15 @@
         cryptohome::CreateAccountIdentifierFromAccountId(account_id_)
             .account_id());
     cryptohome_misc_client_->GetSanitizedUsername(
-        request,
-        base::BindOnce(&CachedPolicyKeyLoaderChromeOS::OnGetSanitizedUsername,
-                       weak_factory_.GetWeakPtr()));
+        request, base::BindOnce(&CachedPolicyKeyLoader::OnGetSanitizedUsername,
+                                weak_factory_.GetWeakPtr()));
   } else {
     TriggerLoadPolicyKey();
   }
 }
 
 // static
-std::string CachedPolicyKeyLoaderChromeOS::LoadPolicyKey(
-    const base::FilePath& path) {
+std::string CachedPolicyKeyLoader::LoadPolicyKey(const base::FilePath& path) {
   std::string key;
 
   if (!base::PathExists(path)) {
@@ -154,18 +149,18 @@
   return key;
 }
 
-void CachedPolicyKeyLoaderChromeOS::TriggerLoadPolicyKey() {
+void CachedPolicyKeyLoader::TriggerLoadPolicyKey() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   base::PostTaskAndReplyWithResult(
       task_runner_.get(), FROM_HERE,
-      base::BindOnce(&CachedPolicyKeyLoaderChromeOS::LoadPolicyKey,
+      base::BindOnce(&CachedPolicyKeyLoader::LoadPolicyKey,
                      cached_policy_key_path_),
-      base::BindOnce(&CachedPolicyKeyLoaderChromeOS::OnPolicyKeyLoaded,
+      base::BindOnce(&CachedPolicyKeyLoader::OnPolicyKeyLoaded,
                      weak_factory_.GetWeakPtr()));
 }
 
-void CachedPolicyKeyLoaderChromeOS::OnPolicyKeyLoaded(const std::string& key) {
+void CachedPolicyKeyLoader::OnPolicyKeyLoaded(const std::string& key) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   cached_policy_key_ = key;
@@ -175,7 +170,7 @@
   NotifyAndClearCallbacks();
 }
 
-void CachedPolicyKeyLoaderChromeOS::OnGetSanitizedUsername(
+void CachedPolicyKeyLoader::OnGetSanitizedUsername(
     absl::optional<user_data_auth::GetSanitizedUsernameReply> reply) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!reply.has_value() || reply->sanitized_username().empty()) {
@@ -192,7 +187,7 @@
   TriggerLoadPolicyKey();
 }
 
-void CachedPolicyKeyLoaderChromeOS::NotifyAndClearCallbacks() {
+void CachedPolicyKeyLoader::NotifyAndClearCallbacks() {
   std::vector<base::OnceClosure> callbacks = std::move(key_loaded_callbacks_);
   key_loaded_callbacks_.clear();
 
diff --git a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h b/chrome/browser/ash/policy/core/cached_policy_key_loader.h
similarity index 86%
rename from chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h
rename to chrome/browser/ash/policy/core/cached_policy_key_loader.h
index eb0eaef..add0a6a 100644
--- a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h
+++ b/chrome/browser/ash/policy/core/cached_policy_key_loader.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_CHROMEOS_H_
-#define CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_CHROMEOS_H_
+#ifndef CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_H_
+#define CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_H_
 
 #include <string>
 #include <vector>
@@ -29,14 +29,13 @@
 namespace policy {
 
 // Loads policy key cached by session_manager.
-class CachedPolicyKeyLoaderChromeOS {
+class CachedPolicyKeyLoader {
  public:
-  CachedPolicyKeyLoaderChromeOS(
-      chromeos::CryptohomeMiscClient* cryptohome_misc_client,
-      scoped_refptr<base::SequencedTaskRunner> task_runner,
-      const AccountId& account_id,
-      const base::FilePath& user_policy_key_dir);
-  ~CachedPolicyKeyLoaderChromeOS();
+  CachedPolicyKeyLoader(chromeos::CryptohomeMiscClient* cryptohome_misc_client,
+                        scoped_refptr<base::SequencedTaskRunner> task_runner,
+                        const AccountId& account_id,
+                        const base::FilePath& user_policy_key_dir);
+  ~CachedPolicyKeyLoader();
 
   // Invokes |callback| after loading |policy_key_|, if it hasn't been loaded
   // yet; otherwise invokes |callback| immediately.
@@ -97,11 +96,11 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Must be the last memeber.
-  base::WeakPtrFactory<CachedPolicyKeyLoaderChromeOS> weak_factory_{this};
+  base::WeakPtrFactory<CachedPolicyKeyLoader> weak_factory_{this};
 
-  DISALLOW_COPY_AND_ASSIGN(CachedPolicyKeyLoaderChromeOS);
+  DISALLOW_COPY_AND_ASSIGN(CachedPolicyKeyLoader);
 };
 
 }  // namespace policy
 
-#endif  // CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_CHROMEOS_H_
+#endif  // CHROME_BROWSER_ASH_POLICY_CORE_CACHED_POLICY_KEY_LOADER_H_
diff --git a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos_unittest.cc b/chrome/browser/ash/policy/core/cached_policy_key_loader_unittest.cc
similarity index 98%
rename from chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos_unittest.cc
rename to chrome/browser/ash/policy/core/cached_policy_key_loader_unittest.cc
index 4322650..a93d88bc 100644
--- a/chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos_unittest.cc
+++ b/chrome/browser/ash/policy/core/cached_policy_key_loader_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h"
+#include "chrome/browser/ash/policy/core/cached_policy_key_loader.h"
 
 #include <memory>
 
@@ -34,7 +34,7 @@
   void SetUp() override {
     ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
 
-    cached_policy_key_loader_ = std::make_unique<CachedPolicyKeyLoaderChromeOS>(
+    cached_policy_key_loader_ = std::make_unique<CachedPolicyKeyLoader>(
         &cryptohome_misc_client_, task_environment_.GetMainThreadTaskRunner(),
         account_id_, user_policy_keys_dir());
   }
@@ -75,7 +75,7 @@
   const cryptohome::AccountIdentifier cryptohome_id_ =
       cryptohome::CreateAccountIdentifierFromAccountId(account_id_);
 
-  std::unique_ptr<CachedPolicyKeyLoaderChromeOS> cached_policy_key_loader_;
+  std::unique_ptr<CachedPolicyKeyLoader> cached_policy_key_loader_;
 
   // Counts how many times OnPolicyKeyLoaded() has been invoked.
   int policy_key_loaded_callback_invocations_ = 0;
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_chromeos.h b/chrome/browser/ash/policy/core/device_cloud_policy_manager_chromeos.h
index cce75f1..073f2e66 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_chromeos.h
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_chromeos.h
@@ -22,8 +22,8 @@
 namespace ash {
 namespace attestation {
 class AttestationPolicyObserver;
-class EnrollmentPolicyObserver;
 class EnrollmentCertificateUploader;
+class EnrollmentPolicyObserver;
 class MachineCertificateUploader;
 }  // namespace attestation
 }  // namespace ash
@@ -131,13 +131,6 @@
         component_policy_disabled_for_testing;
   }
 
-  // Return a pointer to the enrollment certificate uploader. The callers do
-  // not take ownership of that pointer.
-  ash::attestation::EnrollmentCertificateUploader*
-  GetEnrollmentCertificateUploader() {
-    return enrollment_certificate_uploader_.get();
-  }
-
   // Return a pointer to the machine certificate uploader. The callers do
   // not take ownership of that pointer.
   ash::attestation::MachineCertificateUploader*
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc b/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc
index ec1b4a61..fe290fa9 100644
--- a/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc
+++ b/chrome/browser/ash/policy/core/device_local_account_policy_provider.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/values.h"
-#include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/ash/policy/external_data/device_local_account_external_data_manager.h"
 #include "chromeos/dbus/power/power_policy_controller.h"
 #include "components/policy/core/common/cloud/cloud_policy_core.h"
@@ -25,10 +24,10 @@
 DeviceLocalAccountPolicyProvider::DeviceLocalAccountPolicyProvider(
     const std::string& user_id,
     DeviceLocalAccountPolicyService* service,
-    std::unique_ptr<PolicyMap> chrome_policy_overrides)
+    DeviceLocalAccount::Type type)
     : user_id_(user_id),
       service_(service),
-      chrome_policy_overrides_(std::move(chrome_policy_overrides)),
+      type_(type),
       store_initialized_(false),
       waiting_for_policy_refresh_(false) {
   service_->AddObserver(this);
@@ -51,28 +50,9 @@
     return nullptr;
   }
 
-  std::unique_ptr<PolicyMap> chrome_policy_overrides;
-  if (type == DeviceLocalAccount::TYPE_PUBLIC_SESSION) {
-    chrome_policy_overrides = std::make_unique<PolicyMap>();
-
-    // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the
-    // ash shelf does not auto-hide.
-    chrome_policy_overrides->Set(key::kShelfAutoHideBehavior,
-                                 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                                 POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
-                                 base::Value("Never"), nullptr);
-    // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big,
-    // red logout button is shown in the ash system tray.
-    chrome_policy_overrides->Set(key::kShowLogoutButtonInTray,
-                                 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                                 POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
-                                 base::Value(true), nullptr);
-  }
-
   std::unique_ptr<DeviceLocalAccountPolicyProvider> provider(
-      new DeviceLocalAccountPolicyProvider(user_id,
-                                           device_local_account_policy_service,
-                                           std::move(chrome_policy_overrides)));
+      new DeviceLocalAccountPolicyProvider(
+          user_id, device_local_account_policy_service, type));
   // In case of restore-after-restart broker should already be initialized.
   if (force_immediate_load && provider->GetBroker())
     provider->GetBroker()->LoadImmediately();
@@ -157,12 +137,23 @@
   // administrator given that this is an enterprise user.
   SetEnterpriseUsersDefaults(&chrome_policy);
 
-  // Apply overrides.
-  if (chrome_policy_overrides_) {
-    for (const auto& policy_override : *chrome_policy_overrides_) {
-      const PolicyMap::Entry& entry = policy_override.second;
-      chrome_policy.Set(policy_override.first, entry.level, entry.scope,
-                        entry.source, entry.value()->Clone(), nullptr);
+  // Apply managed guest session specific default values if no value is fetched
+  // from the cloud.
+  if (type_ == DeviceLocalAccount::TYPE_PUBLIC_SESSION) {
+    if (chrome_policy.GetValue(key::kShelfAutoHideBehavior) == nullptr) {
+      // Force the |ShelfAutoHideBehavior| policy to |Never|, ensuring that the
+      // ash shelf does not auto-hide.
+      chrome_policy.Set(key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY,
+                        POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT,
+                        base::Value("Never"), nullptr);
+    }
+
+    if (chrome_policy.GetValue(key::kShowLogoutButtonInTray) == nullptr) {
+      // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a
+      // big, red logout button is shown in the ash system tray.
+      chrome_policy.Set(key::kShowLogoutButtonInTray, POLICY_LEVEL_MANDATORY,
+                        POLICY_SCOPE_MACHINE, POLICY_SOURCE_ENTERPRISE_DEFAULT,
+                        base::Value(true), nullptr);
     }
   }
 
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_provider.h b/chrome/browser/ash/policy/core/device_local_account_policy_provider.h
index 91e714b..5199ec0 100644
--- a/chrome/browser/ash/policy/core/device_local_account_policy_provider.h
+++ b/chrome/browser/ash/policy/core/device_local_account_policy_provider.h
@@ -12,14 +12,13 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/ash/policy/core/device_local_account_policy_service.h"
 #include "chrome/browser/ash/policy/external_data/device_local_account_external_data_manager.h"
 #include "components/policy/core/common/configuration_policy_provider.h"
 
 namespace policy {
 
-class PolicyMap;
-
 // Policy provider for a device-local account. Pulls policy from
 // DeviceLocalAccountPolicyService. Note that this implementation keeps
 // functioning when the device-local account disappears from
@@ -30,10 +29,9 @@
     : public ConfigurationPolicyProvider,
       public DeviceLocalAccountPolicyService::Observer {
  public:
-  DeviceLocalAccountPolicyProvider(
-      const std::string& user_id,
-      DeviceLocalAccountPolicyService* service,
-      std::unique_ptr<PolicyMap> chrome_policy_overrides);
+  DeviceLocalAccountPolicyProvider(const std::string& user_id,
+                                   DeviceLocalAccountPolicyService* service,
+                                   DeviceLocalAccount::Type type);
   ~DeviceLocalAccountPolicyProvider() override;
 
   // Factory function to create and initialize a provider for |user_id|. Returns
@@ -71,11 +69,7 @@
   scoped_refptr<DeviceLocalAccountExternalDataManager> external_data_manager_;
 
   DeviceLocalAccountPolicyService* service_;
-
-  // A policy map providing overrides to apply on top of the Chrome policy
-  // received from |service_|. This is used to fix certain policies for public
-  // sessions regardless of what's actually specified in policy.
-  std::unique_ptr<PolicyMap> chrome_policy_overrides_;
+  DeviceLocalAccount::Type type_;
 
   bool store_initialized_;
   bool waiting_for_policy_refresh_;
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
index b54947b..029f8c1 100644
--- a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
@@ -823,14 +823,13 @@
   provider_->AddObserver(&provider_observer_);
 
   // Values implicitly enforced for public accounts.
-  expected_policy_map_.Set(key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY,
-                           POLICY_SCOPE_MACHINE,
-                           POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
-                           base::Value("Never"), nullptr);
+  expected_policy_map_.Set(
+      key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+      POLICY_SOURCE_ENTERPRISE_DEFAULT, base::Value("Never"), nullptr);
   expected_policy_map_.Set(key::kShowLogoutButtonInTray, POLICY_LEVEL_MANDATORY,
                            POLICY_SCOPE_MACHINE,
-                           POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
-                           base::Value(true), nullptr);
+                           POLICY_SOURCE_ENTERPRISE_DEFAULT, base::Value(true),
+                           nullptr);
 
   // Policy defaults (for policies not set by admin).
   SetEnterpriseUsersDefaults(&expected_policy_map_);
@@ -889,6 +888,23 @@
   ASSERT_TRUE(policy_value);
   EXPECT_FALSE(policy_value->GetBool());
 
+  // |ShelfAutoHideBehavior| and |ShowLogoutButtonInTray| should have their
+  // defaults set.
+  auto* policy_entry =
+      provider_->policies()
+          .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+          .Get(key::kShelfAutoHideBehavior);
+  ASSERT_TRUE(policy_entry->value());
+  EXPECT_EQ("Never", policy_entry->value()->GetString());
+  EXPECT_EQ(POLICY_SOURCE_ENTERPRISE_DEFAULT, policy_entry->source);
+
+  policy_entry = provider_->policies()
+                     .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+                     .Get(key::kShowLogoutButtonInTray);
+  ASSERT_TRUE(policy_entry->value());
+  EXPECT_TRUE(policy_entry->value()->GetBool());
+  EXPECT_EQ(POLICY_SOURCE_ENTERPRISE_DEFAULT, policy_entry->source);
+
   // Policy change should be reported.
   EXPECT_CALL(provider_observer_, OnUpdatePolicy(provider_.get()))
       .Times(AtLeast(1));
@@ -909,8 +925,8 @@
            POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
   EXPECT_TRUE(expected_policy_bundle.Equals(provider_->policies()));
 
-  // Any values set for the |ShelfAutoHideBehavior|, |ShowLogoutButtonInTray|
-  // and |ExtensionAllowedTypes| policies should be overridden.
+  // The default value of |ShelfAutoHideBehavior| and |ShowLogoutButtonInTray|
+  // should be overridden if they are set in the cloud.
   EXPECT_CALL(provider_observer_, OnUpdatePolicy(provider_.get()))
       .Times(AtLeast(1));
   device_local_account_policy_.payload()
@@ -919,6 +935,15 @@
   device_local_account_policy_.payload()
       .mutable_showlogoutbuttonintray()
       ->set_value(false);
+  expected_policy_bundle
+      .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+      .Set(key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY,
+           POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value("Always"),
+           nullptr);
+  expected_policy_bundle
+      .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+      .Set(key::kShowLogoutButtonInTray, POLICY_LEVEL_MANDATORY,
+           POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(false), nullptr);
   InstallDeviceLocalAccountPolicy(kAccount1);
   broker->core()->store()->Load();
   FlushDeviceSettings();
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.cc b/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.cc
index 1842651..a3698ad6 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.cc
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.cc
@@ -13,7 +13,7 @@
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
 #include "chrome/browser/ash/crosapi/browser_manager.h"
-#include "chrome/browser/ash/policy/core/cached_policy_key_loader_chromeos.h"
+#include "chrome/browser/ash/policy/core/cached_policy_key_loader.h"
 #include "chrome/browser/chromeos/policy/value_validation/onc_user_policy_value_validator.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chromeos/cryptohome/cryptohome_parameters.h"
@@ -49,11 +49,11 @@
       session_manager_client_(session_manager_client),
       account_id_(account_id),
       is_active_directory_(is_active_directory),
-      cached_policy_key_loader_(std::make_unique<CachedPolicyKeyLoaderChromeOS>(
-          cryptohome_misc_client,
-          background_task_runner,
-          account_id,
-          user_policy_key_dir)) {}
+      cached_policy_key_loader_(
+          std::make_unique<CachedPolicyKeyLoader>(cryptohome_misc_client,
+                                                  background_task_runner,
+                                                  account_id,
+                                                  user_policy_key_dir)) {}
 
 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {}
 
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.h b/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.h
index d7ea01a..d33be33 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.h
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_store_chromeos.h
@@ -28,7 +28,7 @@
 
 namespace policy {
 
-class CachedPolicyKeyLoaderChromeOS;
+class CachedPolicyKeyLoader;
 
 // Implements a policy store backed by the Chrome OS' session_manager, which
 // takes care of persisting policy to disk and is accessed via DBus calls
@@ -97,7 +97,7 @@
   bool is_active_directory_;
 
   // Used to load the policy key provided by session manager as a file.
-  std::unique_ptr<CachedPolicyKeyLoaderChromeOS> cached_policy_key_loader_;
+  std::unique_ptr<CachedPolicyKeyLoader> cached_policy_key_loader_;
 
   base::WeakPtrFactory<UserCloudPolicyStoreChromeOS> weak_factory_{this};
 
diff --git a/chrome/browser/ash/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/ash/policy/dlp/dlp_clipboard_notifier.cc
index c4b13dd..069e433b 100644
--- a/chrome/browser/ash/policy/dlp/dlp_clipboard_notifier.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_clipboard_notifier.cc
@@ -264,7 +264,6 @@
 }
 
 void DlpClipboardNotifier::WebContentsDestroyed() {
-  std::move(blink_paste_cb_);
   CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
 }
 
diff --git a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
index 08d5ee9..efc0e65 100644
--- a/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
+++ b/chrome/browser/ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc
@@ -330,7 +330,7 @@
   device_local_account_policy_provider_ =
       std::make_unique<DeviceLocalAccountPolicyProvider>(
           account_id.GetUserEmail(), device_local_account_policy_service_.get(),
-          std::unique_ptr<PolicyMap>());
+          DeviceLocalAccount::TYPE_PUBLIC_SESSION);
 
   PolicyServiceImpl::Providers providers;
   providers.push_back(device_local_account_policy_provider_.get());
diff --git a/chrome/browser/ash/release_notes/release_notes_storage.cc b/chrome/browser/ash/release_notes/release_notes_storage.cc
index 86dd1b4..7141942 100644
--- a/chrome/browser/ash/release_notes/release_notes_storage.cc
+++ b/chrome/browser/ash/release_notes/release_notes_storage.cc
@@ -36,12 +36,31 @@
 }
 
 bool IsEligibleProfile(Profile* profile) {
-  std::string user_email = profile->GetProfileUserName();
-  return gaia::IsGoogleInternalAccountEmail(user_email) ||
-         (ash::ProfileHelper::Get()
-              ->GetUserByProfile(profile)
-              ->HasGaiaAccount() &&
-          !profile->GetProfilePolicyConnector()->IsManaged());
+  // Do not show the notification for Ephemeral and Guest profiles.
+  if (ash::ProfileHelper::IsEphemeralUserProfile(profile))
+    return false;
+  if (profile->IsGuestSession())
+    return false;
+
+  // Do not show the notification for managed profiles (e.g. Enterprise,
+  // Education), except for Googlers and Unicorn accounts.
+
+  // Show the notification for Googlers.
+  if (gaia::IsGoogleInternalAccountEmail(profile->GetProfileUserName()))
+    return true;
+
+  // Show the notification for Unicorn profiles. Education profiles are Regular
+  // profiles, so they will not pass this check.
+  if (profile->IsChild())
+    return true;
+
+  // After the above exceptions, do not show the notification for profiles
+  // managed by a policy.
+  if (profile->GetProfilePolicyConnector()->IsManaged())
+    return false;
+
+  // Otherwise, show the notification for Consumer profiles.
+  return ash::ProfileHelper::Get()->GetUserByProfile(profile)->HasGaiaAccount();
 }
 
 bool ShouldShowForCurrentChannel() {
diff --git a/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc b/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc
index 9dcdb69b..b5fc174 100644
--- a/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc
+++ b/chrome/browser/ash/release_notes/release_notes_storage_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/version.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/supervised_user/supervised_user_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/login/login_state/login_state.h"
@@ -40,31 +41,50 @@
             std::unique_ptr<FakeChromeUserManager>(user_manager_)) {}
   ~ReleaseNotesStorageTest() override {}
 
-  std::unique_ptr<Profile> CreateProfile(std::string email) {
-    AccountId account_id_ = AccountId::FromUserEmailGaiaId(email, "12345");
-    user_manager_->AddUser(account_id_);
+  void SetUpProfile() {
     TestingProfile::Builder builder;
-    builder.SetProfileName(email);
-    return builder.Build();
+    if (is_guest_) {
+      builder.SetGuestSession();
+    } else {
+      AccountId account_id_ = AccountId::FromUserEmailGaiaId(email_, "12345");
+      user_manager_->AddUser(account_id_);
+      builder.SetProfileName(email_);
+
+      builder.OverridePolicyConnectorIsManagedForTesting(is_managed_);
+      if (is_ephemeral_) {
+        // Enabling ephemeral users passes the |IsEphemeralUserProfile| check.
+        user_manager_->set_ephemeral_users_enabled(true);
+      } else if (is_unicorn_) {
+        user_manager_->set_current_user_child(true);
+        builder.SetSupervisedUserId(supervised_users::kChildAccountSUID);
+      }
+    }
+    profile_ = builder.Build();
+    release_notes_storage_ =
+        std::make_unique<ReleaseNotesStorage>(profile_.get());
   }
 
-  std::unique_ptr<Profile> SetupStandardEnvironmentAndProfile(std::string email,
-                                                              bool is_managed) {
+  void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
         /*enabled_features=*/{features::kReleaseNotesNotification,
                               features::kReleaseNotesNotificationAllChannels,
                               features::kReleaseNotesSuggestionChip},
         /*disabled_features=*/{});
-    std::unique_ptr<Profile> profile = CreateProfile(email);
-    profile->GetProfilePolicyConnector()->OverrideIsManagedForTesting(
-        is_managed);
-    return profile;
   }
 
   FakeChromeUserManager* user_manager_;
   user_manager::ScopedUserManager scoped_user_manager_;
   content::BrowserTaskEnvironment task_environment_;
   base::test::ScopedFeatureList scoped_feature_list_;
+  std::unique_ptr<Profile> profile_;
+  std::unique_ptr<ReleaseNotesStorage> release_notes_storage_;
+
+  // Data members for SetUpProfile().
+  std::string email_ = "test@gmail.com";
+  bool is_guest_ = false;
+  bool is_managed_ = false;
+  bool is_ephemeral_ = false;
+  bool is_unicorn_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(ReleaseNotesStorageTest);
 };
@@ -72,152 +92,139 @@
 // Release notes are not shown for profiles that have been created in this
 // milestone.
 TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesOOBE) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  profile.get()->GetPrefs()->SetString(prefs::kProfileCreatedByVersion,
-                                       version_info::GetVersion().GetString());
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetString(prefs::kProfileCreatedByVersion,
+                                        version_info::GetVersion().GetString());
 
-  EXPECT_EQ(false, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
 }
 
 // Release notes are shown for profiles that have been created in an earlier
 // version of chrome.
 TEST_F(ReleaseNotesStorageTest, ShouldShowReleaseNotesOldProfile) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  profile.get()->GetPrefs()->SetString(prefs::kProfileCreatedByVersion,
-                                       "20.0.0.0");
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetString(prefs::kProfileCreatedByVersion,
+                                        "20.0.0.0");
 
-  EXPECT_EQ(true, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(true, release_notes_storage_->ShouldNotify());
 }
 
 // We have previously seen another notification on an earlier chrome version,
 // release notes should be shown.
 TEST_F(ReleaseNotesStorageTest, ShouldShowReleaseNotes) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetInteger(
       prefs::kHelpAppNotificationLastShownMilestone, 20);
 
-  EXPECT_EQ(true, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(true, release_notes_storage_->ShouldNotify());
 }
 
 // We have already seen the notification on the current chrome version.
 TEST_F(ReleaseNotesStorageTest,
        ShouldNotShowReleaseNotesIfShownInCurrentChromeVersion) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetInteger(
       prefs::kHelpAppNotificationLastShownMilestone, CurrentMilestone());
 
-  EXPECT_EQ(false, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
 }
 
 // Release notes ShouldNotify is false after being shown once.
 TEST_F(ReleaseNotesStorageTest, ReleaseNotesShouldOnlyBeNotifiedOnce) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
-      prefs::kHelpAppNotificationLastShownMilestone, 20);
-  ASSERT_EQ(true, release_notes_storage->ShouldNotify());
+  SetUpProfile();
 
-  release_notes_storage->MarkNotificationShown();
+  ASSERT_EQ(true, release_notes_storage_->ShouldNotify());
 
-  EXPECT_NE(20, profile.get()->GetPrefs()->GetInteger(
+  release_notes_storage_->MarkNotificationShown();
+
+  EXPECT_NE(20, profile_.get()->GetPrefs()->GetInteger(
                     prefs::kHelpAppNotificationLastShownMilestone));
-  EXPECT_EQ(false, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
+}
+
+TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesForEphemeralProfile) {
+  is_ephemeral_ = true;
+  SetUpProfile();
+
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
+}
+
+TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesForGuestProfile) {
+  is_guest_ = true;
+  SetUpProfile();
+
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
 }
 
 TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesForManagedProfile) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@company.com", true);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
-      prefs::kHelpAppNotificationLastShownMilestone, 20);
+  is_managed_ = true;
+  SetUpProfile();
 
-  EXPECT_EQ(false, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
 }
 
 TEST_F(ReleaseNotesStorageTest, ShouldShowReleaseNotesForGoogler) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@google.com", true);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
-      prefs::kHelpAppNotificationLastShownMilestone, 20);
+  is_managed_ = true;
+  email_ = "test@google.com";
+  SetUpProfile();
 
-  EXPECT_EQ(true, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(true, release_notes_storage_->ShouldNotify());
 }
 
-TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesIfFeatureDisabled) {
-  scoped_feature_list_.InitAndDisableFeature(
-      features::kReleaseNotesNotification);
-  std::unique_ptr<Profile> profile = CreateProfile("test@gmail.com");
-  profile->GetProfilePolicyConnector()->OverrideIsManagedForTesting(false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
-      prefs::kHelpAppNotificationLastShownMilestone, 20);
+TEST_F(ReleaseNotesStorageTest, ShouldShowReleaseNotesForUnicornProfile) {
+  is_managed_ = true;
+  is_unicorn_ = true;
+  SetUpProfile();
 
-  EXPECT_EQ(false, release_notes_storage->ShouldNotify());
+  EXPECT_EQ(true, release_notes_storage_->ShouldNotify());
 }
 
 // Tests that when kReleaseNotesSuggestionChipTimesLeftToShow is 0,
 // ReleaseNotesStorage::ShouldShowSuggestionChip returns false.
 TEST_F(ReleaseNotesStorageTest, DoesNotShowReleaseNotesSuggestionChip) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
 
-  EXPECT_EQ(false, release_notes_storage->ShouldShowSuggestionChip());
+  EXPECT_EQ(false, release_notes_storage_->ShouldShowSuggestionChip());
 }
 
 // Tests that when kReleaseNotesSuggestionChipTimesLeftToShow is greater than 0,
 // ReleaseNotesStorage::ShouldShowSuggestionChip returns true, and when
 // decreased the method returns false again.
 TEST_F(ReleaseNotesStorageTest, ShowReleaseNotesSuggestionChip) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
-  profile.get()->GetPrefs()->SetInteger(
+  SetUpProfile();
+  profile_.get()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1);
-  ASSERT_EQ(true, release_notes_storage->ShouldShowSuggestionChip());
 
-  release_notes_storage->DecreaseTimesLeftToShowSuggestionChip();
+  ASSERT_EQ(true, release_notes_storage_->ShouldShowSuggestionChip());
 
-  EXPECT_EQ(0, profile.get()->GetPrefs()->GetInteger(
+  release_notes_storage_->DecreaseTimesLeftToShowSuggestionChip();
+
+  EXPECT_EQ(0, profile_.get()->GetPrefs()->GetInteger(
                    prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
-  EXPECT_EQ(false, release_notes_storage->ShouldShowSuggestionChip());
+  EXPECT_EQ(false, release_notes_storage_->ShouldShowSuggestionChip());
 }
 
 // Tests that when we mark a notification as shown, we also show the suggestion
 // chip.
 TEST_F(ReleaseNotesStorageTest, ShowSuggestionChipWhenNotificationShown) {
-  std::unique_ptr<Profile> profile =
-      SetupStandardEnvironmentAndProfile("test@gmail.com", false);
-  std::unique_ptr<ReleaseNotesStorage> release_notes_storage =
-      std::make_unique<ReleaseNotesStorage>(profile.get());
+  SetUpProfile();
 
-  release_notes_storage->MarkNotificationShown();
+  release_notes_storage_->MarkNotificationShown();
 
-  EXPECT_EQ(3, profile.get()->GetPrefs()->GetInteger(
+  EXPECT_EQ(3, profile_.get()->GetPrefs()->GetInteger(
                    prefs::kReleaseNotesSuggestionChipTimesLeftToShow));
-  EXPECT_EQ(true, release_notes_storage->ShouldShowSuggestionChip());
+  EXPECT_EQ(true, release_notes_storage_->ShouldShowSuggestionChip());
+}
+
+TEST_F(ReleaseNotesStorageTest, ShouldNotShowReleaseNotesIfFeatureDisabled) {
+  scoped_feature_list_.Reset();
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kReleaseNotesNotification);
+  SetUpProfile();
+
+  EXPECT_EQ(false, release_notes_storage_->ShouldNotify());
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc b/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc
index 9af939b..5ea1998c 100644
--- a/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc
+++ b/chrome/browser/ash/scanning/lorgnette_scanner_manager.cc
@@ -185,7 +185,7 @@
     // Iterate through each lorgnette scanner and add its info to an existing
     // Scanner if it has a matching IP address. Otherwise, create a new Scanner
     // for the lorgnette scanner.
-    base::flat_map<net::IPAddress, chromeos::Scanner*> known_ip_addresses =
+    base::flat_map<net::IPAddress, std::string> known_ip_addresses =
         GetKnownIpAddresses();
     for (const auto& lorgnette_scanner : response->scanners()) {
       std::string ip_address_str;
@@ -196,7 +196,9 @@
         if (ip_address.AssignFromIPLiteral(ip_address_str)) {
           const auto it = known_ip_addresses.find(ip_address);
           if (it != known_ip_addresses.end()) {
-            it->second->device_names[protocol].emplace(
+            const auto existing = deduped_scanners_.find(it->second);
+            DCHECK(existing != deduped_scanners_.end());
+            existing->second.device_names[protocol].emplace(
                 lorgnette_scanner.name());
             continue;
           }
@@ -225,14 +227,15 @@
       deduped_scanners_[scanner.display_name] = scanner;
   }
 
-  // Returns a map of IP addresses to the scanners they correspond to in
-  // deduped_scanners_. This enables deduplication of network scanners by making
-  // it easy to check for and modify them using their IP addresses.
-  base::flat_map<net::IPAddress, chromeos::Scanner*> GetKnownIpAddresses() {
-    base::flat_map<net::IPAddress, chromeos::Scanner*> known_ip_addresses;
+  // Returns a map of IP addresses to the display names (lookup keys) of
+  // scanners they correspond to in deduped_scanners_. This enables
+  // deduplication of network scanners by making it easy to check for and modify
+  // them using their IP addresses.
+  base::flat_map<net::IPAddress, std::string> GetKnownIpAddresses() {
+    base::flat_map<net::IPAddress, std::string> known_ip_addresses;
     for (auto& entry : deduped_scanners_) {
       for (const auto& ip_address : entry.second.ip_addresses)
-        known_ip_addresses[ip_address] = &entry.second;
+        known_ip_addresses[ip_address] = entry.second.display_name;
     }
 
     return known_ip_addresses;
diff --git a/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc b/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc
index b22523a..7ce24070 100644
--- a/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc
+++ b/chrome/browser/ash/scanning/lorgnette_scanner_manager_unittest.cc
@@ -304,6 +304,28 @@
   EXPECT_THAT(scanner_names(), ElementsAreArray({scanner.display_name}));
 }
 
+// Test that two detected scanners with the same IP address are deduplicated and
+// reported with single scanner name, while USB of the same model is reported
+// separately.
+TEST_F(LorgnetteScannerManagerTest, DeduplicateNetPlusUsbScanner) {
+  lorgnette::ListScannersResponse response;
+  lorgnette::ScannerInfo info =
+      CreateLorgnetteScanner(kLorgnetteUsbDeviceName, "MX3100");
+  *response.add_scanners() = std::move(info);
+  info = CreateLorgnetteScanner(kLorgnetteNetworkIpDeviceName, "MX3100");
+  *response.add_scanners() = std::move(info);
+
+  GetLorgnetteManagerClient()->SetListScannersResponse(response);
+  auto scanner = CreateZeroconfScanner();
+  fake_zeroconf_scanner_detector()->AddDetections({scanner});
+  CompleteTasks();
+  GetScannerNames();
+  WaitForResult();
+  EXPECT_THAT(scanner_names(),
+              ElementsAreArray(
+                  {scanner.display_name, scanner.display_name + " (USB)"}));
+}
+
 // Test that a lorgnette scanner with a URL in the name gets reported as a
 // network scanner instead of a USB scanner (i.e. USB is not in the returned
 // scanner name).
diff --git a/chrome/browser/ash/settings/cros_settings.cc b/chrome/browser/ash/settings/cros_settings.cc
index 74cccb0..50c34956 100644
--- a/chrome/browser/ash/settings/cros_settings.cc
+++ b/chrome/browser/ash/settings/cros_settings.cc
@@ -150,9 +150,12 @@
 bool CrosSettings::GetDouble(const std::string& path,
                              double* out_value) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const base::Value* value = GetPref(path);
-  if (value)
-    return value->GetAsDouble(out_value);
+  // `GetIfDouble` incapsulates type check.
+  absl::optional<double> maybe_value = GetPref(path)->GetIfDouble();
+  if (maybe_value.has_value()) {
+    *out_value = maybe_value.value();
+    return true;
+  }
   return false;
 }
 
diff --git a/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.cc b/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.cc
index 63dd682e..12569db 100644
--- a/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.cc
+++ b/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.cc
@@ -22,16 +22,21 @@
 void CrosSharesheetServiceDelegate::ShowBubble(
     std::vector<::sharesheet::TargetInfo> targets,
     apps::mojom::IntentPtr intent,
-    ::sharesheet::DeliveredCallback delivered_callback) {
+    ::sharesheet::DeliveredCallback delivered_callback,
+    ::sharesheet::CloseCallback close_callback) {
   if (IsBubbleVisible()) {
     if (delivered_callback) {
       std::move(delivered_callback)
           .Run(::sharesheet::SharesheetResult::kErrorAlreadyOpen);
     }
+    if (close_callback) {
+      std::move(close_callback).Run();
+    }
     return;
   }
   sharesheet_bubble_view_->ShowBubble(std::move(targets), std::move(intent),
-                                      std::move(delivered_callback));
+                                      std::move(delivered_callback),
+                                      std::move(close_callback));
 }
 
 void CrosSharesheetServiceDelegate::ShowNearbyShareBubble(
diff --git a/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.h b/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.h
index c94a191..dcb7a65 100644
--- a/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.h
+++ b/chrome/browser/ash/sharesheet/cros_sharesheet_service_delegate.h
@@ -34,7 +34,8 @@
   // ::sharesheet::SharesheetServiceDelegate overrides:
   void ShowBubble(std::vector<::sharesheet::TargetInfo> targets,
                   apps::mojom::IntentPtr intent,
-                  ::sharesheet::DeliveredCallback delivered_callback) override;
+                  ::sharesheet::DeliveredCallback delivered_callback,
+                  ::sharesheet::CloseCallback close_callback) override;
   void ShowNearbyShareBubble(
       apps::mojom::IntentPtr intent,
       ::sharesheet::DeliveredCallback delivered_callback,
diff --git a/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc
index ffea4d3..9c16ab4 100644
--- a/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc
+++ b/chrome/browser/ash/web_applications/diagnostics_app_integration_browsertest.cc
@@ -26,7 +26,7 @@
 // spot checks on the manifest.
 IN_PROC_BROWSER_TEST_P(DiagnosticsAppIntegrationTest,
                        DiagnosticsAppInLauncher) {
-  const GURL url(chromeos::kChromeUIDiagnosticsAppUrl);
+  const GURL url(ash::kChromeUIDiagnosticsAppUrl);
   EXPECT_NO_FATAL_FAILURE(ExpectSystemWebAppValid(
       web_app::SystemAppType::DIAGNOSTICS, url, "Diagnostics"));
 }
diff --git a/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc b/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc
index 58bbeb2..04d9018 100644
--- a/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc
+++ b/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc
@@ -19,8 +19,8 @@
 CreateWebAppInfoForDiagnosticsSystemWebApp() {
   std::unique_ptr<WebApplicationInfo> info =
       std::make_unique<WebApplicationInfo>();
-  info->start_url = GURL(chromeos::kChromeUIDiagnosticsAppUrl);
-  info->scope = GURL(chromeos::kChromeUIDiagnosticsAppUrl);
+  info->start_url = GURL(ash::kChromeUIDiagnosticsAppUrl);
+  info->scope = GURL(ash::kChromeUIDiagnosticsAppUrl);
 
   // TODO(jimmyxgong): Update the title with finalized i18n copy.
   info->title = u"Diagnostics";
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index 404f204..dcc255d 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -40,7 +40,11 @@
 // Adds an item to the context menu that copies a link to the page with the
 // selected text highlighted.
 const base::Feature kCopyLinkToText{"CopyLinkToText",
-                                    base::FEATURE_DISABLED_BY_DEFAULT};
+                                    base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Adds a "Snooze" action to mute notifications during screen sharing sessions.
+const base::Feature kMuteNotificationSnoozeAction{
+    "MuteNotificationSnoozeAction", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index b6aeedfb..e6832e47 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -30,6 +30,7 @@
 
 #if !defined(OS_ANDROID)
 extern const base::Feature kCopyLinkToText;
+extern const base::Feature kMuteNotificationSnoozeAction;
 #endif
 
 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/browsing_data/access_context_audit_database.cc b/chrome/browser/browsing_data/access_context_audit_database.cc
index ae87705..9a9427f 100644
--- a/chrome/browser/browsing_data/access_context_audit_database.cc
+++ b/chrome/browser/browsing_data/access_context_audit_database.cc
@@ -453,6 +453,21 @@
   transaction.Commit();
 }
 
+void AccessContextAuditDatabase::RemoveAllRecordsForTimeRangeHistory(
+    base::Time begin,
+    base::Time end) {
+  std::vector<AccessContextAuditDatabase::AccessRecord>
+      cross_site_storage_records;
+  if (base::FeatureList::IsEnabled(
+          browsing_data::features::kEnableRemovingAllThirdPartyCookies)) {
+    cross_site_storage_records =
+        SelectCrossSiteStorageRecordsWithoutTopLevelOrigins(
+            GetStorageRecordsForTimeRange(begin, end));
+  }
+  RemoveAllRecordsForTimeRange(begin, end);
+  AddRecords(cross_site_storage_records);
+}
+
 void AccessContextAuditDatabase::RemoveSessionOnlyRecords(
     const ContentSettingsForOneType& content_settings) {
   // ContentSettingsForOneType is a list of settings in decreasing specificity
@@ -692,6 +707,26 @@
 }
 
 std::vector<AccessContextAuditDatabase::AccessRecord>
+AccessContextAuditDatabase::GetStorageRecordsForTimeRange(base::Time begin,
+                                                          base::Time end) {
+  std::vector<AccessContextAuditDatabase::AccessRecord> records;
+
+  const char kSelectStorageApiRecords[] =
+      "SELECT top_frame_origin, type, origin, access_utc FROM "
+      "originStorageAPIs WHERE access_utc BETWEEN ? AND ?";
+  sql::Statement select_storage_api(
+      db_.GetCachedStatement(SQL_FROM_HERE, kSelectStorageApiRecords));
+
+  select_storage_api.BindTime(0, begin);
+  select_storage_api.BindTime(1, end);
+  while (select_storage_api.Step()) {
+    records.emplace_back(StorageAccessRecordFromStatement(select_storage_api));
+  }
+
+  return records;
+}
+
+std::vector<AccessContextAuditDatabase::AccessRecord>
 AccessContextAuditDatabase::GetAllRecords() {
   std::vector<AccessContextAuditDatabase::AccessRecord> records =
       GetCookieRecords();
diff --git a/chrome/browser/browsing_data/access_context_audit_database.h b/chrome/browser/browsing_data/access_context_audit_database.h
index 0d084a31..93c176e 100644
--- a/chrome/browser/browsing_data/access_context_audit_database.h
+++ b/chrome/browser/browsing_data/access_context_audit_database.h
@@ -107,6 +107,12 @@
   // Removes all records where |begin| <= record.last_access_time <= |end|.
   void RemoveAllRecordsForTimeRange(base::Time begin, base::Time end);
 
+  // Removes all records where |begin| <= record.last_access_time <= |end| from
+  // a history deletion. Like RemoveAllRecordsHistory, we keep cross-site
+  // storage access records and make the top-level origin opaque when user
+  // controls for third-party data clearing is enabled.
+  void RemoveAllRecordsForTimeRangeHistory(base::Time begin, base::Time end);
+
   // Removes all records that match the provided cookie details.
   void RemoveAllRecordsForCookie(const std::string& name,
                                  const std::string& domain,
@@ -144,6 +150,8 @@
 
   std::vector<AccessRecord> GetStorageRecordsForTopFrameOrigins(
       const std::vector<url::Origin>& origins);
+  std::vector<AccessRecord> GetStorageRecordsForTimeRange(base::Time begin,
+                                                          base::Time end);
 
   sql::Database db_;
   sql::MetaTable meta_table_;
diff --git a/chrome/browser/browsing_data/access_context_audit_database_unittest.cc b/chrome/browser/browsing_data/access_context_audit_database_unittest.cc
index 888d1eb1..76add427 100644
--- a/chrome/browser/browsing_data/access_context_audit_database_unittest.cc
+++ b/chrome/browser/browsing_data/access_context_audit_database_unittest.cc
@@ -439,6 +439,33 @@
   ValidateDatabaseRecords(database(), test_records);
 }
 
+TEST_F(AccessContextAuditDatabaseTest, RemoveAllRecordsForTimeRangeHistory) {
+  // Check that records within the specified time range are removed.
+  auto test_records = GetTestRecords();
+  OpenDatabase();
+  database()->AddRecords(test_records);
+  ValidateDatabaseRecords(database(), test_records);
+
+  auto begin_time =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(4));
+  auto end_time =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(6));
+
+  database()->RemoveAllRecordsForTimeRangeHistory(begin_time, end_time);
+
+  test_records.erase(
+      std::remove_if(
+          test_records.begin(), test_records.end(),
+          [=](const AccessContextAuditDatabase::AccessRecord& record) {
+            return record.last_access_time >= begin_time &&
+                   record.last_access_time <= end_time;
+          }),
+      test_records.end());
+
+  EXPECT_GT(GetTestRecords().size(), test_records.size());
+  ValidateDatabaseRecords(database(), test_records);
+}
+
 TEST_F(AccessContextAuditDatabaseTest, RemoveAllCookieRecords) {
   // Check that all matching cookie records are removed from the database.
   auto test_records = GetTestRecords();
@@ -830,3 +857,72 @@
               kCrossSiteOrigin, kLaterAccessTime),
       });
 }
+
+TEST_F(AccessContextAuditDatabaseThirdPartyDataClearingTest,
+       RemoveAllRecordsForTimeRangeHistory) {
+  const url::Origin kTopFrameOrigin =
+      url::Origin::Create(GURL("https://toplevel.com/"));
+  const url::Origin kCrossSiteOrigin =
+      url::Origin::Create(GURL("https://cross.site.com/"));
+
+  const base::Time kBeginTime =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(4));
+  const base::Time kEndTime =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(6));
+  const base::Time kInsideRange =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(5));
+  const base::Time kOutsideRange =
+      base::Time::FromDeltaSinceWindowsEpoch(base::TimeDelta::FromHours(7));
+
+  std::vector<AccessContextAuditDatabase::AccessRecord> test_records = {
+      // Same-site and cross-site cookie records in the time range must be
+      // removed.
+      AccessContextAuditDatabase::AccessRecord(
+          kTopFrameOrigin, "samesite", "toplevel.com", "/", kInsideRange,
+          /* is_persistent */ true),
+      AccessContextAuditDatabase::AccessRecord(kTopFrameOrigin, "xsite",
+                                               "xsite.com", "/", kInsideRange,
+                                               /* is_persistent */ true),
+      // Cookie records outside the time range should remain.
+      AccessContextAuditDatabase::AccessRecord(
+          kTopFrameOrigin, "outside", "toplevel.com", "/", kOutsideRange,
+          /* is_persistent */ true),
+      // Same-site storage access record inside the itme range. This should be
+      // removed.
+      AccessContextAuditDatabase::AccessRecord(
+          kTopFrameOrigin,
+          AccessContextAuditDatabase::StorageAPIType::kLocalStorage,
+          kTopFrameOrigin, kInsideRange),
+      // Cross-site record inside the time range should have its top-level
+      // origin removed.
+      AccessContextAuditDatabase::AccessRecord(
+          kTopFrameOrigin,
+          AccessContextAuditDatabase::StorageAPIType::kLocalStorage,
+          kCrossSiteOrigin, kInsideRange),
+      // Cross-site record outside the time range should not be modified.
+      AccessContextAuditDatabase::AccessRecord(
+          kTopFrameOrigin,
+          AccessContextAuditDatabase::StorageAPIType::kIndexedDB,
+          kCrossSiteOrigin, kOutsideRange),
+  };
+  OpenDatabase();
+  database()->AddRecords(test_records);
+  ValidateDatabaseRecords(database(), test_records);
+
+  database()->RemoveAllRecordsForTimeRangeHistory(kBeginTime, kEndTime);
+  ValidateDatabaseRecords(
+      database(),
+      {
+          AccessContextAuditDatabase::AccessRecord(
+              kTopFrameOrigin, "outside", "toplevel.com", "/", kOutsideRange,
+              /* is_persistent */ true),
+          AccessContextAuditDatabase::AccessRecord(
+              url::Origin(),
+              AccessContextAuditDatabase::StorageAPIType::kLocalStorage,
+              kCrossSiteOrigin, kInsideRange),
+          AccessContextAuditDatabase::AccessRecord(
+              kTopFrameOrigin,
+              AccessContextAuditDatabase::StorageAPIType::kIndexedDB,
+              kCrossSiteOrigin, kOutsideRange),
+      });
+}
diff --git a/chrome/browser/browsing_data/access_context_audit_service.cc b/chrome/browser/browsing_data/access_context_audit_service.cc
index 2a86f14e..c4e9f81 100644
--- a/chrome/browser/browsing_data/access_context_audit_service.cc
+++ b/chrome/browser/browsing_data/access_context_audit_service.cc
@@ -334,7 +334,7 @@
     database_task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(
-            &AccessContextAuditDatabase::RemoveAllRecordsForTimeRange,
+            &AccessContextAuditDatabase::RemoveAllRecordsForTimeRangeHistory,
             database_, deletion_info.time_range().begin(),
             deletion_info.time_range().end()));
   }
diff --git a/chrome/browser/browsing_data/access_context_audit_service.h b/chrome/browser/browsing_data/access_context_audit_service.h
index 28b4793d..b3c8d94e 100644
--- a/chrome/browser/browsing_data/access_context_audit_service.h
+++ b/chrome/browser/browsing_data/access_context_audit_service.h
@@ -151,6 +151,8 @@
                            HistoryDeletion);
   FRIEND_TEST_ALL_PREFIXES(AccessContextAuditThirdPartyDataClearingTest,
                            AllHistoryDeletion);
+  FRIEND_TEST_ALL_PREFIXES(AccessContextAuditThirdPartyDataClearingTest,
+                           TimeRangeHistoryDeletion);
 
   // Records accesses for all cookies in |details| against |top_frame_origin|.
   // Should only be accessed via the CookieAccessHelper.
diff --git a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
index 107474ee..1b88195 100644
--- a/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
+++ b/chrome/browser/browsing_data/access_context_audit_service_unittest.cc
@@ -916,3 +916,85 @@
 
   ValidateCrossSiteStorageRecords(kCrossSiteURL);
 }
+
+TEST_F(AccessContextAuditThirdPartyDataClearingTest, TimeRangeHistoryDeletion) {
+  const GURL kTopLevelURL("https://toplevel.com/");
+  const GURL kInsideTimeRangeURL("https://inside.range.com/");
+  const GURL kOutsideTimeRangeURL("https://outside.range.com/");
+
+  const url::Origin kTopLevelOrigin = url::Origin::Create(kTopLevelURL);
+  const url::Origin kInsideTimeRangeOrigin =
+      url::Origin::Create(kInsideTimeRangeURL);
+  const url::Origin kOutsideTimeRangeOrigin =
+      url::Origin::Create(kOutsideTimeRangeURL);
+
+  clock()->SetNow(base::Time::Now());
+  service()->SetClockForTesting(clock());
+  const base::Time kInsideTimeRange =
+      clock()->Now() + base::TimeDelta::FromHours(1);
+  const base::Time kOutsideTimeRange =
+      clock()->Now() + base::TimeDelta::FromHours(3);
+
+  clock()->SetNow(kOutsideTimeRange);
+  // A cookie record outside the time range should not be modified.
+  service()->RecordCookieAccess(
+      {*net::CanonicalCookie::Create(
+          kOutsideTimeRangeURL, "same=site; max-age=3600", kOutsideTimeRange,
+          absl::nullopt /* server_time */)},
+      kTopLevelOrigin);
+  clock()->SetNow(kInsideTimeRange);
+  // A cookie record inside the time range should be deleted.
+  service()->RecordCookieAccess(
+      {*net::CanonicalCookie::Create(
+          kInsideTimeRangeURL, "cross=site; max-age=3600", kInsideTimeRange,
+          absl::nullopt /* server_time */)},
+      kTopLevelOrigin);
+  // A same-site storage record in the time range should be deleted.
+  service()->RecordStorageAPIAccess(
+      kTopLevelOrigin, AccessContextAuditDatabase::StorageAPIType::kIndexedDB,
+      kTopLevelOrigin);
+  // Set a cross-site storage access record in the time range. This should be
+  // kept but the top-level origin should be removed.
+  service()->RecordStorageAPIAccess(
+      kInsideTimeRangeOrigin,
+      AccessContextAuditDatabase::StorageAPIType::kLocalStorage,
+      kTopLevelOrigin);
+  clock()->SetNow(kOutsideTimeRange);
+  // A cross-site storage record outside the time range should not be modified.
+  service()->RecordStorageAPIAccess(
+      kOutsideTimeRangeOrigin,
+      AccessContextAuditDatabase::StorageAPIType::kServiceWorker,
+      kTopLevelOrigin);
+  EXPECT_EQ(5u, GetAllAccessRecords().size());
+
+  history_service()->AddPageWithDetails(kTopLevelURL, u"Test1", 1, 1,
+                                        kInsideTimeRange, false,
+                                        history::SOURCE_BROWSED);
+  history_service()->AddPageWithDetails(kTopLevelURL, u"Test1", 1, 1,
+                                        kOutsideTimeRange, false,
+                                        history::SOURCE_BROWSED);
+
+  // Expire history in target time range.
+  base::RunLoop run_loop;
+  base::CancelableTaskTracker task_tracker;
+  history_service()->ExpireHistoryBetween(
+      std::set<GURL>(), kInsideTimeRange - base::TimeDelta::FromMinutes(10),
+      kInsideTimeRange + base::TimeDelta::FromMinutes(10),
+      /*user_initiated*/ true, run_loop.QuitClosure(), &task_tracker);
+  run_loop.Run();
+
+  std::vector<AccessContextAuditDatabase::AccessRecord> records =
+      GetAllAccessRecords();
+  EXPECT_EQ(3u, records.size());
+  size_t n_storage_records = 0;
+  for (const auto& record : records) {
+    if (record.type == AccessContextAuditDatabase::StorageAPIType::kCookie) {
+      EXPECT_EQ("outside.range.com", record.domain);
+      continue;
+    }
+    n_storage_records++;
+    EXPECT_EQ(record.origin == url::Origin::Create(kInsideTimeRangeURL),
+              record.top_frame_origin.opaque());
+  }
+  EXPECT_EQ(2u, n_storage_records);
+}
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 22ddfa5..503fac23 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
@@ -55,6 +55,8 @@
 #include "chrome/browser/permissions/permission_actions_history.h"
 #include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
 #include "chrome/browser/spellchecker/spellcheck_factory.h"
 #include "chrome/browser/spellchecker/spellcheck_service.h"
@@ -1086,7 +1088,9 @@
         }));
     profile_builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
                                       SyncServiceFactory::GetDefaultFactory());
-
+    profile_builder.AddTestingFactory(
+        ChromeSigninClientFactory::GetInstance(),
+        base::BindRepeating(&signin::BuildTestSigninClient));
     profile_ = profile_builder.Build();
 
     remover_ = profile_->GetBrowsingDataRemover();
diff --git a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
index bc9db6bb..5cdbc376 100644
--- a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/password_manager/account_password_store_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
@@ -81,6 +82,14 @@
     // finishes. GetLogins() blocks until reading on the background thread is
     // finished
     passwords_helper::GetLogins(store_);
+
+    // At this point, the calculation on DB thread should have finished, and
+    // a callback should be scheduled on the UI thread. Process the tasks until
+    // we get a finished result.
+    if (finished_)
+      return;
+    run_loop_ = std::make_unique<base::RunLoop>();
+    run_loop_->Run();
   }
 
   BrowsingDataCounter::ResultInt GetResult() {
@@ -104,11 +113,8 @@
       result_ = password_result->Value();
       domain_examples_ = password_result->domain_examples();
     }
-  }
-
-  void WaitForUICallbacksFromAddingLogins() {
-    base::RunLoop loop;
-    loop.RunUntilIdle();
+    if (run_loop_ && finished_)
+      run_loop_->Quit();
   }
 
  private:
@@ -128,6 +134,7 @@
 
   password_manager::PasswordStoreInterface* store_;
 
+  std::unique_ptr<base::RunLoop> run_loop_;
   base::Time time_;
   int times_used_;
 
@@ -144,7 +151,6 @@
   AddLogin("https://www.google.com", "user3", false);
   AddLogin("https://www.chrome.com", "user1", false);
   AddLogin("https://www.chrome.com", "user2", false);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
@@ -168,7 +174,6 @@
   AddLogin("https://www.google.com", "user1", false);
   AddLogin("https://www.google.com", "user2", true);
   AddLogin("https://www.chrome.com", "user3", true);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
@@ -194,7 +199,6 @@
   SetPasswordsDeletionPref(false);
   AddLogin("https://www.google.com", "user", false);
   AddLogin("https://www.chrome.com", "user", false);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
@@ -217,7 +221,6 @@
 // the password store changes.
 IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, StoreChanged) {
   AddLogin("https://www.google.com", "user", false);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
@@ -254,7 +257,6 @@
   AddLogin("https://example.com", "user2", false);
   RevertTimeInDays(30);
   AddLogin("https://www.chrome.com", "user", false);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
@@ -304,7 +306,6 @@
   AddLogin("https://www.example.com", "user", false);
   SetTimesUsed(2);
   AddLogin("https://www.chrome.com", "user", false);
-  WaitForUICallbacksFromAddingLogins();
 
   Profile* profile = browser()->profile();
   browsing_data::PasswordsCounter counter(
diff --git a/chrome/browser/cart/cart_discount_fetcher.cc b/chrome/browser/cart/cart_discount_fetcher.cc
index 393cbf6..20d8035 100644
--- a/chrome/browser/cart/cart_discount_fetcher.cc
+++ b/chrome/browser/cart/cart_discount_fetcher.cc
@@ -12,6 +12,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/cart/cart_db.h"
 #include "chrome/browser/cart/cart_db_content.pb.h"
+#include "chrome/browser/cart/cart_discount_metric_collector.h"
 #include "chrome/browser/endpoint_fetcher/endpoint_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
@@ -255,6 +256,7 @@
       base::BindOnce(&CartDiscountFetcher::OnDiscountsAvailable,
                      std::move(fetcher), std::move(callback)),
       nullptr);
+  CartDiscountMetricCollector::RecordFetchingForDiscounts();
 }
 
 std::unique_ptr<EndpointFetcher> CartDiscountFetcher::CreateEndpointFetcher(
diff --git a/chrome/browser/cart/cart_discount_link_fetcher.cc b/chrome/browser/cart/cart_discount_link_fetcher.cc
index bc3a451..c794b46c5 100644
--- a/chrome/browser/cart/cart_discount_link_fetcher.cc
+++ b/chrome/browser/cart/cart_discount_link_fetcher.cc
@@ -10,6 +10,7 @@
 #include "base/sequence_checker.h"
 #include "chrome/browser/cart/cart_db.h"
 #include "chrome/browser/cart/cart_db_content.pb.h"
+#include "chrome/browser/cart/cart_discount_metric_collector.h"
 #include "chrome/browser/endpoint_fetcher/endpoint_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
@@ -39,6 +40,7 @@
   fetcher_ptr->PerformRequest(
       base::BindOnce(&OnLinkFetched, std::move(fetcher), std::move(callback)),
       nullptr);
+  CartDiscountMetricCollector::RecordFetchingForDiscountedLink();
 }
 
 std::unique_ptr<EndpointFetcher> CartDiscountLinkFetcher::CreateEndpointFetcher(
diff --git a/chrome/browser/cart/cart_discount_metric_collector.cc b/chrome/browser/cart/cart_discount_metric_collector.cc
new file mode 100644
index 0000000..e64874d
--- /dev/null
+++ b/chrome/browser/cart/cart_discount_metric_collector.cc
@@ -0,0 +1,39 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/cart/cart_discount_metric_collector.h"
+
+#include "base/hash/hash.h"
+#include "base/metrics/histogram_functions.h"
+
+namespace {
+enum CartDataRequestType {
+  kCartDiscountInfo = 0,
+  kCartDiscountUrl = 1,
+  kMaxValue = kCartDiscountUrl,
+};
+}  // namespace
+
+void CartDiscountMetricCollector::RecordFetchingForDiscounts() {
+  base::UmaHistogramSparse("NewTabPage.Carts.DataRequest",
+                           CartDataRequestType::kCartDiscountInfo);
+  base::UmaHistogramSparse("NewTabPage.Modules.DataRequest",
+                           base::PersistentHash("chrome_cart"));
+}
+
+void CartDiscountMetricCollector::RecordFetchingForDiscountedLink() {
+  base::UmaHistogramSparse("NewTabPage.Carts.DataRequest",
+                           CartDataRequestType::kCartDiscountUrl);
+  base::UmaHistogramSparse("NewTabPage.Modules.DataRequest",
+                           base::PersistentHash("chrome_cart"));
+}
+
+void CartDiscountMetricCollector::RecordAppliedDiscount() {
+  base::UmaHistogramSparse("NewTabPage.Carts.AppliedDiscount", 1);
+}
+
+void CartDiscountMetricCollector::RecordClickedOnDiscount(bool has_discounts) {
+  base::UmaHistogramBoolean("NewTabPage.Carts.ClickCart.HasDiscount",
+                            has_discounts);
+}
\ No newline at end of file
diff --git a/chrome/browser/cart/cart_discount_metric_collector.h b/chrome/browser/cart/cart_discount_metric_collector.h
new file mode 100644
index 0000000..e6deba3
--- /dev/null
+++ b/chrome/browser/cart/cart_discount_metric_collector.h
@@ -0,0 +1,25 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CART_CART_DISCOUNT_METRIC_COLLECTOR_H_
+#define CHROME_BROWSER_CART_CART_DISCOUNT_METRIC_COLLECTOR_H_
+
+// This is used to collect metric related to the Cart Discount.
+class CartDiscountMetricCollector {
+ public:
+  // Gets called when Chrome fetches for discount. It increments the number of
+  // discount fetches.
+  static void RecordFetchingForDiscounts();
+  // Gets called when the user clicks on the discounted cart. It increments
+  // the number of discounted url fetches.
+  static void RecordFetchingForDiscountedLink();
+  // Gets called when chrome receives the discounted cart url. It increments
+  // the number of discounted link is used.
+  static void RecordAppliedDiscount();
+  // Gets called when the user clicks on the cart item. It records whether
+  // the cart has discounts.
+  static void RecordClickedOnDiscount(bool has_discounts);
+};
+
+#endif  // CHROME_BROWSER_CART_CART_DISCOUNT_METRIC_COLLECTOR_H_
diff --git a/chrome/browser/cart/cart_service.cc b/chrome/browser/cart/cart_service.cc
index 216d33e..1244d4e7 100644
--- a/chrome/browser/cart/cart_service.cc
+++ b/chrome/browser/cart/cart_service.cc
@@ -10,6 +10,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/thread_pool.h"
 #include "chrome/browser/cart/cart_db_content.pb.h"
+#include "chrome/browser/cart/cart_discount_metric_collector.h"
 #include "chrome/browser/cart/fetch_discount_worker.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
@@ -331,6 +332,7 @@
     base::OnceCallback<void(const ::GURL&)> callback) {
   if (!IsPartnerMerchant(cart_url) || !IsCartDiscountEnabled()) {
     std::move(callback).Run(cart_url);
+    CartDiscountMetricCollector::RecordClickedOnDiscount(false);
     return;
   }
   LoadCart(eTLDPlusOne(cart_url),
@@ -347,12 +349,14 @@
   DCHECK_EQ(proto_pairs.size(), 1U);
   if (proto_pairs.size() != 1U) {
     std::move(callback).Run(default_cart_url);
+    CartDiscountMetricCollector::RecordClickedOnDiscount(false);
     return;
   }
   auto& cart_proto = proto_pairs[0].second;
   if (!IsCartDiscountEnabled() ||
       cart_proto.discount_info().discount_info().empty()) {
     std::move(callback).Run(default_cart_url);
+    CartDiscountMetricCollector::RecordClickedOnDiscount(false);
     return;
   }
   auto pending_factory = profile_->GetDefaultStoragePartition()
@@ -364,6 +368,8 @@
       base::BindOnce(&CartService::OnDiscountURLFetched,
                      weak_ptr_factory_.GetWeakPtr(), default_cart_url,
                      std::move(callback), cart_proto));
+
+  CartDiscountMetricCollector::RecordClickedOnDiscount(true);
 }
 
 void CartService::OnDiscountURLFetched(
@@ -376,6 +382,7 @@
   if (discount_url.is_valid()) {
     CacheUsedDiscounts(cart_proto);
     CleanUpDiscounts(cart_proto);
+    CartDiscountMetricCollector::RecordAppliedDiscount();
   }
 }
 
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 73f153f..0c90b3a3 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -190,7 +190,6 @@
 #include "chrome/browser/ui/webui/chromeos/network_ui.h"
 #include "chrome/browser/ui/webui/chromeos/vm/vm.mojom.h"
 #include "chrome/browser/ui/webui/chromeos/vm/vm_ui.h"
-#include "chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom.h"
 #include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h"
 #include "chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.h"
 #include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"  // nogncheck crbug.com/1125897
@@ -715,9 +714,6 @@
                                          TabSearchUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
-      ::mojom::web_app_internals::WebAppInternalsPageHandler, InternalsUI>(map);
-
-  RegisterWebUIControllerInterfaceBinder<
       download_shelf::mojom::PageHandlerFactory, DownloadShelfUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
@@ -821,22 +817,22 @@
       chromeos::NetworkUI, chromeos::ConnectivityDiagnosticsUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
-      chromeos::diagnostics::mojom::InputDataProvider,
-      chromeos::DiagnosticsDialogUI>(map);
+      ash::diagnostics::mojom::InputDataProvider, ash::DiagnosticsDialogUI>(
+      map);
 
   if (chromeos::features::IsNetworkingInDiagnosticsAppEnabled()) {
     RegisterWebUIControllerInterfaceBinder<
-        chromeos::diagnostics::mojom::NetworkHealthProvider,
-        chromeos::DiagnosticsDialogUI>(map);
+        ash::diagnostics::mojom::NetworkHealthProvider,
+        ash::DiagnosticsDialogUI>(map);
   }
 
   RegisterWebUIControllerInterfaceBinder<
-      chromeos::diagnostics::mojom::SystemDataProvider,
-      chromeos::DiagnosticsDialogUI>(map);
+      ash::diagnostics::mojom::SystemDataProvider, ash::DiagnosticsDialogUI>(
+      map);
 
   RegisterWebUIControllerInterfaceBinder<
-      chromeos::diagnostics::mojom::SystemRoutineController,
-      chromeos::DiagnosticsDialogUI>(map);
+      ash::diagnostics::mojom::SystemRoutineController,
+      ash::DiagnosticsDialogUI>(map);
 
   RegisterWebUIControllerInterfaceBinder<
       chromeos::vm::mojom::VmDiagnosticsProvider, chromeos::VmUI>(map);
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 4930c38..be93859 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -509,10 +509,6 @@
   // If we're running tests (ui_task is non-null).
   if (parameters.ui_task)
     browser_defaults::enable_help_app = false;
-
-#if !defined(OS_ANDROID)
-  shutdown_watcher_ = std::make_unique<ShutdownWatcherHelper>();
-#endif  // !defined(OS_ANDROID)
 }
 
 ChromeBrowserMainParts::~ChromeBrowserMainParts() {
@@ -1817,9 +1813,21 @@
   // disconnects DBus services in its PostDestroyThreads.
   UpgradeDetector::GetInstance()->Shutdown();
 
-  // Start watching for jank during shutdown. It gets disarmed when
-  // |shutdown_watcher_| object is destructed.
-  shutdown_watcher_->Arm(base::TimeDelta::FromSeconds(300));
+  // Two different types of hang detection cannot attempt to upload crashes at
+  // the same time or they would interfere with each other.
+  constexpr base::TimeDelta kShutdownHangDelay{
+      base::TimeDelta::FromSeconds(300)};
+  if (base::HangWatcher::IsCrashReportingEnabled()) {
+    // Use ShutdownWatcherHelper logic to choose delay to get identical
+    // behavior.
+    watch_hangs_scope_.emplace(
+        ShutdownWatcherHelper::GetPerChannelTimeout(kShutdownHangDelay));
+  } else {
+    // Start watching for jank during shutdown. It gets disarmed when
+    // |shutdown_watcher_| object is destructed.
+    shutdown_watcher_ = std::make_unique<ShutdownWatcherHelper>();
+    shutdown_watcher_->Arm(kShutdownHangDelay);
+  }
 
   web_usb_detector_.reset();
 
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index 362e1cf..ef9c223 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "base/threading/hang_watcher.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chrome_process_singleton.h"
@@ -149,6 +150,9 @@
   // it is destroyed last.
   std::unique_ptr<ShutdownWatcherHelper> shutdown_watcher_;
 
+  // HangWatcher based equivalent to |shutdown_watcher_|
+  absl::optional<base::WatchHangsInScope> watch_hangs_scope_;
+
   std::unique_ptr<WebUsbDetector> web_usb_detector_;
 #endif  // !defined(OS_ANDROID)
 
diff --git a/chrome/browser/chrome_browser_main_parts_lacros.cc b/chrome/browser/chrome_browser_main_parts_lacros.cc
index 28068892..cfdff63 100644
--- a/chrome/browser/chrome_browser_main_parts_lacros.cc
+++ b/chrome/browser/chrome_browser_main_parts_lacros.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/lacros/metrics_reporting_observer.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chromeos/lacros/lacros_dbus_helper.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
@@ -50,6 +51,12 @@
   }
 }
 
+void ChromeBrowserMainPartsLacros::PostDestroyThreads() {
+  chromeos::LacrosShutdownDBus();
+
+  ChromeBrowserMainPartsLinux::PostDestroyThreads();
+}
+
 void ChromeBrowserMainPartsLacros::OnBrowserAdded(Browser* browser) {
   keep_alive_.reset();
 }
diff --git a/chrome/browser/chrome_browser_main_parts_lacros.h b/chrome/browser/chrome_browser_main_parts_lacros.h
index 88ca0cde..dda9fd1 100644
--- a/chrome/browser/chrome_browser_main_parts_lacros.h
+++ b/chrome/browser/chrome_browser_main_parts_lacros.h
@@ -27,6 +27,7 @@
   // ChromeBrowserMainParts:
   int PreEarlyInitialization() override;
   void PreProfileInit() override;
+  void PostDestroyThreads() override;
 
  private:
   // BrowserListObserver:
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index b04663a..209de37 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1933,8 +1933,8 @@
     "../ash/policy/arc/android_management_client.h",
     "../ash/policy/core/browser_policy_connector_chromeos.cc",
     "../ash/policy/core/browser_policy_connector_chromeos.h",
-    "../ash/policy/core/cached_policy_key_loader_chromeos.cc",
-    "../ash/policy/core/cached_policy_key_loader_chromeos.h",
+    "../ash/policy/core/cached_policy_key_loader.cc",
+    "../ash/policy/core/cached_policy_key_loader.h",
     "../ash/policy/core/device_cloud_policy_manager_chromeos.cc",
     "../ash/policy/core/device_cloud_policy_manager_chromeos.h",
     "../ash/policy/core/device_cloud_policy_store_chromeos.cc",
@@ -2921,6 +2921,8 @@
     "policy/scheduled_task_handler/os_and_policies_update_checker.h",
     "policy/scheduled_task_handler/scheduled_task_executor.cc",
     "policy/scheduled_task_handler/scheduled_task_executor.h",
+    "policy/scheduled_task_handler/scheduled_task_util.cc",
+    "policy/scheduled_task_handler/scheduled_task_util.h",
     "policy/scheduled_task_handler/scoped_wake_lock.cc",
     "policy/scheduled_task_handler/scoped_wake_lock.h",
     "policy/scheduled_task_handler/task_executor_with_retries.cc",
@@ -3916,7 +3918,7 @@
     "../ash/policy/active_directory/component_active_directory_policy_retriever_unittest.cc",
     "../ash/policy/active_directory/component_active_directory_policy_service_unittest.cc",
     "../ash/policy/arc/android_management_client_unittest.cc",
-    "../ash/policy/core/cached_policy_key_loader_chromeos_unittest.cc",
+    "../ash/policy/core/cached_policy_key_loader_unittest.cc",
     "../ash/policy/core/device_cloud_policy_manager_chromeos_unittest.cc",
     "../ash/policy/core/device_cloud_policy_store_chromeos_unittest.cc",
     "../ash/policy/core/device_local_account_policy_service_unittest.cc",
@@ -3941,8 +3943,8 @@
     "../ash/policy/dlp/mock_dlp_content_manager.h",
     "../ash/policy/dlp/mock_dlp_rules_manager.cc",
     "../ash/policy/dlp/mock_dlp_rules_manager.h",
-    "../ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc",
     "../ash/policy/enrollment/account_status_check_fetcher_unittest.cc",
+    "../ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc",
     "../ash/policy/enrollment/device_cloud_policy_initializer_unittest.cc",
     "../ash/policy/external_data/cloud_external_data_manager_base_unittest.cc",
     "../ash/policy/external_data/cloud_external_data_policy_observer_unittest.cc",
@@ -4073,6 +4075,7 @@
     "extensions/file_manager/device_event_router_unittest.cc",
     "extensions/file_manager/drivefs_event_router_unittest.cc",
     "extensions/file_manager/event_router_unittest.cc",
+    "extensions/file_manager/system_notification_manager_unittest.cc",
     "extensions/gfx_utils_unittest.cc",
     "extensions/install_limiter_unittest.cc",
     "extensions/login_screen/login/login_api_unittest.cc",
diff --git a/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc b/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc
index ca6e17a9..b977a3b 100644
--- a/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc
+++ b/chrome/browser/chromeos/eche_app/eche_app_manager_factory.cc
@@ -62,11 +62,16 @@
   kMaxValue = kOpenAppStreaming,
 };
 
-void LaunchEcheApp(Profile* profile, int64_t notification_id) {
+void LaunchEcheApp(Profile* profile,
+                   int64_t notification_id,
+                   std::string package_name) {
   double now_seconds = base::Time::Now().ToDoubleT();
   int64_t now_ms = static_cast<int64_t>(now_seconds * 1000);
+
   std::string url = "chrome://eche-app/#notification_id=";
   url.append(base::NumberToString(notification_id));
+  url.append("&package_name=");
+  url.append(package_name);
   url.append("&timestamp=");
   url.append(base::NumberToString(now_ms));
   web_app::SystemAppLaunchParams params;
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index 06847dac..3f0ec52 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -1175,8 +1175,8 @@
   // default_screen_locker()->locked() is set when the UI is ready, so this
   // tells us both views based lockscreen UI and screenlocker are ready.
   const bool is_screen_locked =
-      !!chromeos::ScreenLocker::default_screen_locker() &&
-      chromeos::ScreenLocker::default_screen_locker()->locked();
+      !!ash::ScreenLocker::default_screen_locker() &&
+      ash::ScreenLocker::default_screen_locker()->locked();
 
   if (user_manager) {
     result->SetBoolean("isLoggedIn", user_manager->IsUserLoggedIn());
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
index 440a75d6..37e1ef10 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.cc
@@ -73,8 +73,8 @@
   pin_status.transfer_state = file_manager_private::TRANSFER_STATE_FAILED;
   pin_status.hide_when_zero_jobs = true;
 
-  DispatchOnFileTransfersUpdatedEvent(sync_status);
-  DispatchOnPinTransfersUpdatedEvent(pin_status);
+  BroadcastOnFileTransfersUpdatedEvent(sync_status);
+  BroadcastOnPinTransfersUpdatedEvent(pin_status);
 
   dialog_callback_.Reset();
 }
@@ -147,7 +147,7 @@
       file_manager_private::OnFileTransfersUpdated::kEventName);
 
   if (sync_status.total == 0) {
-    DispatchOnFileTransfersUpdatedEvent(sync_status);
+    BroadcastOnFileTransfersUpdatedEvent(sync_status);
   } else {
     for (const auto* item : sync_events) {
       sync_status.transfer_state = ConvertItemEventState(item->state);
@@ -155,14 +155,13 @@
       for (const auto& listener_url : urls) {
         sync_status.file_url =
             ConvertDrivePathToFileSystemUrl(path, listener_url).spec();
-        DispatchOnFileTransfersUpdatedEventToExtension(listener_url.host(),
-                                                       sync_status);
+        BroadcastOnFileTransfersUpdatedEvent(sync_status);
       }
     }
   }
 
   if (pin_status.total == 0) {
-    DispatchOnPinTransfersUpdatedEvent(pin_status);
+    BroadcastOnPinTransfersUpdatedEvent(pin_status);
   } else {
     for (const auto* item : pin_events) {
       pin_status.transfer_state = ConvertItemEventState(item->state);
@@ -170,8 +169,7 @@
       for (const auto& listener_url : urls) {
         pin_status.file_url =
             ConvertDrivePathToFileSystemUrl(path, listener_url).spec();
-        DispatchOnPinTransfersUpdatedEventToExtension(listener_url.host(),
-                                                      pin_status);
+        BroadcastOnPinTransfersUpdatedEvent(pin_status);
       }
     }
   }
@@ -233,11 +231,9 @@
            file_manager_private::OnDriveSyncError::kEventName)) {
     event.file_url =
         ConvertDrivePathToFileSystemUrl(error.path, listener_url).spec();
-    DispatchEventToExtension(
-        listener_url.host(),
-        extensions::events::FILE_MANAGER_PRIVATE_ON_DRIVE_SYNC_ERROR,
-        file_manager_private::OnDriveSyncError::kEventName,
-        file_manager_private::OnDriveSyncError::Create(event));
+    BroadcastEvent(extensions::events::FILE_MANAGER_PRIVATE_ON_DRIVE_SYNC_ERROR,
+                   file_manager_private::OnDriveSyncError::kEventName,
+                   file_manager_private::OnDriveSyncError::Create(event));
   }
 }
 
@@ -261,8 +257,7 @@
   for (const auto& listener_url : urls) {
     event.file_url =
         ConvertDrivePathToFileSystemUrl(reason.path, listener_url).spec();
-    DispatchEventToExtension(
-        listener_url.host(),
+    BroadcastEvent(
         extensions::events::FILE_MANAGER_PRIVATE_ON_DRIVE_CONFIRM_DIALOG,
         file_manager_private::OnDriveConfirmDialog::kEventName,
         file_manager_private::OnDriveConfirmDialog::Create(event));
@@ -275,37 +270,17 @@
   }
 }
 
-void DriveFsEventRouter::DispatchOnFileTransfersUpdatedEvent(
+void DriveFsEventRouter::BroadcastOnFileTransfersUpdatedEvent(
     const extensions::api::file_manager_private::FileTransferStatus& status) {
-  for (const auto& listener_url : GetEventListenerURLs(
-           file_manager_private::OnFileTransfersUpdated::kEventName)) {
-    DispatchOnFileTransfersUpdatedEventToExtension(listener_url.host(), status);
-  }
-}
-
-void DriveFsEventRouter::DispatchOnFileTransfersUpdatedEventToExtension(
-    const std::string& extension_id,
-    const extensions::api::file_manager_private::FileTransferStatus& status) {
-  DispatchEventToExtension(
-      extension_id,
+  BroadcastEvent(
       extensions::events::FILE_MANAGER_PRIVATE_ON_FILE_TRANSFERS_UPDATED,
       file_manager_private::OnFileTransfersUpdated::kEventName,
       file_manager_private::OnFileTransfersUpdated::Create(status));
 }
 
-void DriveFsEventRouter::DispatchOnPinTransfersUpdatedEvent(
+void DriveFsEventRouter::BroadcastOnPinTransfersUpdatedEvent(
     const extensions::api::file_manager_private::FileTransferStatus& status) {
-  for (const auto& listener_url : GetEventListenerURLs(
-           file_manager_private::OnPinTransfersUpdated::kEventName)) {
-    DispatchOnPinTransfersUpdatedEventToExtension(listener_url.host(), status);
-  }
-}
-
-void DriveFsEventRouter::DispatchOnPinTransfersUpdatedEventToExtension(
-    const std::string& extension_id,
-    const extensions::api::file_manager_private::FileTransferStatus& status) {
-  DispatchEventToExtension(
-      extension_id,
+  BroadcastEvent(
       extensions::events::FILE_MANAGER_PRIVATE_ON_PIN_TRANSFERS_UPDATED,
       file_manager_private::OnPinTransfersUpdated::kEventName,
       file_manager_private::OnPinTransfersUpdated::Create(status));
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
index c968d87..9229c7e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router.h
@@ -37,8 +37,11 @@
 class DriveFsEventRouter : public drivefs::DriveFsHostObserver {
  public:
   explicit DriveFsEventRouter(SystemNotificationManager* notification_manager);
+  DriveFsEventRouter(const DriveFsEventRouter&) = delete;
   virtual ~DriveFsEventRouter();
 
+  DriveFsEventRouter& operator=(const DriveFsEventRouter&) = delete;
+
   // Triggers an event in the UI to display a confirmation dialog.
   void DisplayConfirmDialog(
       const drivefs::mojom::DialogReason& reason,
@@ -70,9 +73,6 @@
       const std::vector<drivefs::mojom::FileChange>& changes) override;
   void OnError(const drivefs::mojom::DriveError& error) override;
 
-  void DispatchOnFileTransfersUpdatedEvent(
-      const extensions::api::file_manager_private::FileTransferStatus& status);
-
   virtual std::set<GURL> GetEventListenerURLs(
       const std::string& event_name) = 0;
 
@@ -83,28 +83,16 @@
 
   virtual bool IsPathWatched(const base::FilePath& path) = 0;
 
-  void DispatchOnFileTransfersUpdatedEventToExtension(
-      const std::string& extension_id,
+  void BroadcastOnFileTransfersUpdatedEvent(
       const extensions::api::file_manager_private::FileTransferStatus& status);
 
-  void DispatchOnPinTransfersUpdatedEvent(
-      const extensions::api::file_manager_private::FileTransferStatus& status);
-
-  void DispatchOnPinTransfersUpdatedEventToExtension(
-      const std::string& extension_id,
+  void BroadcastOnPinTransfersUpdatedEvent(
       const extensions::api::file_manager_private::FileTransferStatus& status);
 
   void BroadcastOnDirectoryChangedEvent(
       const base::FilePath& directory,
       const extensions::api::file_manager_private::FileWatchEvent& event);
 
-  // Helper method for dispatching an event to an extension.
-  virtual void DispatchEventToExtension(
-      const std::string& extension_id,
-      extensions::events::HistogramValue histogram_value,
-      const std::string& event_name,
-      std::vector<base::Value> event_args) = 0;
-
   // Helper method for broadcasting events.
   virtual void BroadcastEvent(
       extensions::events::HistogramValue histogram_value,
@@ -122,8 +110,6 @@
   SyncingStatusState sync_status_state_;
   SyncingStatusState pin_status_state_;
   base::OnceCallback<void(drivefs::mojom::DialogResult)> dialog_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(DriveFsEventRouter);
 };
 
 }  // namespace file_manager
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
index 0a7272da..03344fc 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
@@ -78,15 +78,6 @@
             extensions::Extension::GetBaseURLFromExtensionId("ext")}));
   }
 
-  void DispatchEventToExtension(
-      const std::string& extension_id,
-      extensions::events::HistogramValue histogram_value,
-      const std::string& event_name,
-      std::vector<base::Value> event_args) override {
-    DispatchEventToExtensionImpl(extension_id, event_name,
-                                 base::Value(std::move(event_args)));
-  }
-
   void BroadcastEvent(extensions::events::HistogramValue histogram_value,
                       const std::string& event_name,
                       std::vector<base::Value> event_args) override {
@@ -94,11 +85,6 @@
   }
 
   MOCK_METHOD(void,
-              DispatchEventToExtensionImpl,
-              (const std::string& extension_id,
-               const std::string& name,
-               const base::Value& event));
-  MOCK_METHOD(void,
               BroadcastEventImpl,
               (const std::string& name, const base::Value& event));
   MOCK_METHOD(bool, IsPathWatched, (const base::FilePath&));
@@ -128,14 +114,14 @@
   void Unmount() {
     EXPECT_CALL(
         mock(),
-        DispatchEventToExtensionImpl(
-            "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+        BroadcastEventImpl(
+            file_manager_private::OnFileTransfersUpdated::kEventName,
             MatchFileTransferStatus(
                 "", file_manager_private::TRANSFER_STATE_FAILED, 0, 0, 0)));
     EXPECT_CALL(
         mock(),
-        DispatchEventToExtensionImpl(
-            "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+        BroadcastEventImpl(
+            file_manager_private::OnPinTransfersUpdated::kEventName,
             MatchFileTransferStatus(
                 "", file_manager_private::TRANSFER_STATE_FAILED, 0, 0, 0)));
 
@@ -149,34 +135,30 @@
 };
 
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_Basic) {
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:a", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 50,
-              200, 2)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 50,
-              200, 2)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:c", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 25, 80,
-              2)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:d", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 25, 80,
-              2)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      50, 200, 2)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      50, 200, 2)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnPinTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:c", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      25, 80, 2)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnPinTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:d", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      25, 80, 2)));
 
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
@@ -197,14 +179,14 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_EmptyStatus) {
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
 
@@ -221,15 +203,13 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(4);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnPinTransfersUpdated::kEventName, _))
       .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -245,14 +225,14 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
 
@@ -261,17 +241,16 @@
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:c", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      60, 70, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:c", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 60, 70,
-              1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
 
@@ -288,15 +267,14 @@
       50, 100, drivefs::mojom::ItemEventReason::kPin);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)))
       .Times(2);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnPinTransfersUpdated::kEventName, _))
       .Times(2);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -310,17 +288,16 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
-          MatchFileTransferStatus("ext:a",
-                                  file_manager_private::TRANSFER_STATE_FAILED,
-                                  100, 100, 0)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnPinTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_FAILED, 100,
+                      100, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kFailed, -1,
@@ -333,15 +310,14 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(2);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)))
       .Times(2);
@@ -355,17 +331,16 @@
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                      100, 100, 0)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED, 100, 100,
-              0)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -384,39 +359,36 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(2);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                      110, 200, 1)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200,
-              1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110,
-              200, 1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -437,39 +409,36 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(2);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                      110, 200, 1)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200,
-              1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110,
-              200, 1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -488,39 +457,36 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(1);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED,
+                      110, 200, 1)));
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      110, 200, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:a", file_manager_private::TRANSFER_STATE_COMPLETED, 110, 200,
-              1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 110,
-              200, 1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -538,15 +504,14 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(2);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)))
       .Times(2);
@@ -562,14 +527,14 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -585,29 +550,27 @@
   syncing_status.item_events.emplace_back(
       base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _))
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _))
       .Times(1);
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   observer().OnSyncingStatusUpdate(syncing_status);
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName, _));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName, _));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -618,17 +581,16 @@
 
   testing::Mock::VerifyAndClearExpectations(&observer());
 
+  EXPECT_CALL(mock(),
+              BroadcastEventImpl(
+                  file_manager_private::OnFileTransfersUpdated::kEventName,
+                  MatchFileTransferStatus(
+                      "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS,
+                      10, 500, 1)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
-          MatchFileTransferStatus(
-              "ext:b", file_manager_private::TRANSFER_STATE_IN_PROGRESS, 10,
-              500, 1)));
-  EXPECT_CALL(
-      mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
@@ -648,14 +610,14 @@
 
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnFileTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnFileTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnPinTransfersUpdated::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnPinTransfersUpdated::kEventName,
           MatchFileTransferStatus(
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
 
@@ -771,8 +733,8 @@
   event.file_url = "ext:/a";
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnDriveSyncError::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnDriveSyncError::kEventName,
           testing::MakeMatcher(new ValueMatcher(base::Value(
               file_manager_private::OnDriveSyncError::Create(event))))));
 
@@ -786,8 +748,8 @@
   event.file_url = "ext:a";
   EXPECT_CALL(
       mock(),
-      DispatchEventToExtensionImpl(
-          "ext", file_manager_private::OnDriveSyncError::kEventName,
+      BroadcastEventImpl(
+          file_manager_private::OnDriveSyncError::kEventName,
           testing::MakeMatcher(new ValueMatcher(base::Value(
               file_manager_private::OnDriveSyncError::Create(event))))));
 
@@ -800,12 +762,12 @@
   expected_event.type =
       file_manager_private::DRIVE_CONFIRM_DIALOG_TYPE_ENABLE_DOCS_OFFLINE;
   expected_event.file_url = "ext:a";
-  EXPECT_CALL(mock(),
-              DispatchEventToExtensionImpl(
-                  "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ValueMatcher(base::Value(
-                      file_manager_private::OnDriveConfirmDialog::Create(
-                          expected_event))))));
+  EXPECT_CALL(
+      mock(),
+      BroadcastEventImpl(file_manager_private::OnDriveConfirmDialog::kEventName,
+                         testing::MakeMatcher(new ValueMatcher(base::Value(
+                             file_manager_private::OnDriveConfirmDialog::Create(
+                                 expected_event))))));
 
   drivefs::mojom::DialogReason reason;
   reason.type = drivefs::mojom::DialogReason::Type::kEnableDocsOffline;
@@ -827,12 +789,12 @@
   expected_event.type =
       file_manager_private::DRIVE_CONFIRM_DIALOG_TYPE_ENABLE_DOCS_OFFLINE;
   expected_event.file_url = "ext:a";
-  EXPECT_CALL(mock(),
-              DispatchEventToExtensionImpl(
-                  "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ValueMatcher(base::Value(
-                      file_manager_private::OnDriveConfirmDialog::Create(
-                          expected_event))))));
+  EXPECT_CALL(
+      mock(),
+      BroadcastEventImpl(file_manager_private::OnDriveConfirmDialog::kEventName,
+                         testing::MakeMatcher(new ValueMatcher(base::Value(
+                             file_manager_private::OnDriveConfirmDialog::Create(
+                                 expected_event))))));
 
   drivefs::mojom::DialogReason reason;
   reason.type = drivefs::mojom::DialogReason::Type::kEnableDocsOffline;
@@ -863,12 +825,12 @@
   expected_event.type =
       file_manager_private::DRIVE_CONFIRM_DIALOG_TYPE_ENABLE_DOCS_OFFLINE;
   expected_event.file_url = "ext:a";
-  EXPECT_CALL(mock(),
-              DispatchEventToExtensionImpl(
-                  "ext", file_manager_private::OnDriveConfirmDialog::kEventName,
-                  testing::MakeMatcher(new ValueMatcher(base::Value(
-                      file_manager_private::OnDriveConfirmDialog::Create(
-                          expected_event))))))
+  EXPECT_CALL(
+      mock(),
+      BroadcastEventImpl(file_manager_private::OnDriveConfirmDialog::kEventName,
+                         testing::MakeMatcher(new ValueMatcher(base::Value(
+                             file_manager_private::OnDriveConfirmDialog::Create(
+                                 expected_event))))))
       .Times(2);
 
   drivefs::mojom::DialogReason reason;
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index e0c5150..3436b504 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -266,7 +266,7 @@
   // the screen is locked or running in kiosk app mode and make sure the file
   // manager is opened only for the active user.
   if (ash::LoginDisplayHost::default_host() ||
-      chromeos::ScreenLocker::default_screen_locker() ||
+      ash::ScreenLocker::default_screen_locker() ||
       chrome::IsRunningInForcedAppMode() ||
       profile != ProfileManager::GetActiveUserProfile()) {
     return false;
@@ -359,6 +359,7 @@
 
 class DriveFsEventRouterImpl : public DriveFsEventRouter {
  public:
+  DriveFsEventRouterImpl(const DriveFsEventRouterImpl&) = delete;
   DriveFsEventRouterImpl(
       SystemNotificationManager* notification_manager,
       Profile* profile,
@@ -368,6 +369,8 @@
         profile_(profile),
         file_watchers_(file_watchers) {}
 
+  DriveFsEventRouterImpl& operator=(const DriveFsEventRouterImpl&) = delete;
+
  private:
   std::set<GURL> GetEventListenerURLs(const std::string& event_name) override {
     const extensions::EventListenerMap::ListenerList& listeners =
@@ -414,19 +417,6 @@
            base::Contains(*file_watchers_, absolute_path);
   }
 
-  void DispatchEventToExtension(
-      const std::string& extension_id,
-      extensions::events::HistogramValue histogram_value,
-      const std::string& event_name,
-      std::vector<base::Value> event_args) override {
-    std::unique_ptr<extensions::Event> event =
-        std::make_unique<extensions::Event>(histogram_value, event_name,
-                                            std::move(event_args));
-    system_notification_manager()->HandleEvent(*event.get());
-    extensions::EventRouter::Get(profile_)->DispatchEventToExtension(
-        extension_id, std::move(event));
-  }
-
   void BroadcastEvent(extensions::events::HistogramValue histogram_value,
                       const std::string& event_name,
                       std::vector<base::Value> event_args) override {
@@ -440,8 +430,6 @@
   Profile* const profile_;
   const std::map<base::FilePath, std::unique_ptr<FileWatcher>>* const
       file_watchers_;
-
-  DISALLOW_COPY_AND_ASSIGN(DriveFsEventRouterImpl);
 };
 
 }  // namespace
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
index ee5b848a..49ea195 100644
--- a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager.cc
@@ -217,7 +217,7 @@
       required_copy_space_.erase(copy_id);
       break;
     default:
-      NOTREACHED();
+      DLOG(WARNING) << "Unhandled copy event for type " << status.type;
       break;
   }
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc
new file mode 100644
index 0000000..c35d3777
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/system_notification_manager_unittest.cc
@@ -0,0 +1,25 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/file_manager/system_notification_manager.h"
+
+#include "ash/constants/ash_features.h"
+#include "base/test/scoped_feature_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace file_manager {
+
+namespace file_manager_private = extensions::api::file_manager_private;
+
+TEST(SystemNotificationManagerTest, TestCopyEvents) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(ash::features::kFilesSWA);
+  SystemNotificationManager notification_manager(nullptr);
+  file_manager_private::CopyOrMoveProgressStatus status;
+
+  // Check: an uninitialized status.source_url doesn't crash copy event handler.
+  notification_manager.HandleCopyEvent(0, status);
+}
+
+}  // namespace file_manager
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.cc b/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.cc
index ce679e6..eb5db909 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.cc
@@ -46,7 +46,7 @@
     base::OnceCallback<void(bool auth_success)> callback) {
   unlock_in_progress_ = true;
   callback_ = std::move(callback);
-  chromeos::ScreenLocker::default_screen_locker()->Authenticate(
+  ScreenLocker::default_screen_locker()->Authenticate(
       user_context, base::BindOnce(&LoginApiLockHandler::AuthenticateCallback,
                                    weak_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.h b/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.h
index 36dc0e39..8bf700f 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.h
+++ b/chrome/browser/chromeos/extensions/login_screen/login/login_api_lock_handler.h
@@ -13,7 +13,7 @@
 class UserContext;
 
 // A thin wrapper around |SessionControllerClientImpl| and
-// |chromeos::ScreenLocker| to allow easier mocking for tests. Also manages the
+// |ScreenLocker| to allow easier mocking for tests. Also manages the
 // |unlock_in_progress| state.
 class LoginApiLockHandler {
  public:
diff --git a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
index 70db3fb0..4dea2a3 100644
--- a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
@@ -636,7 +636,7 @@
     extensions::api_test_utils::RunFunction(func.get(), std::move(params),
                                             profile(), std::move(dispatcher),
                                             extensions::api_test_utils::NONE);
-    EXPECT_TRUE(func->GetResultList()->empty());
+    EXPECT_TRUE(func->GetResultList()->GetList().empty());
     base::RunLoop().RunUntilIdle();
     return func->GetError();
   }
diff --git a/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc b/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc
index 4d93232..20113ea 100644
--- a/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/users_private/users_private_apitest.cc
@@ -243,7 +243,7 @@
 
 // Screenlock - logged in, screen locked.
 IN_PROC_BROWSER_TEST_F(UsersPrivateApiLockStatusTest, ScreenLock) {
-  chromeos::ScreenLockerTester().Lock();
+  ash::ScreenLockerTester().Lock();
   EXPECT_TRUE(RunExtensionTest("users_private",
                                {.page_url = "main.html?getLoginStatus"},
                                {.load_as_component = true}))
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
index 89ebf86..0c49d8b 100644
--- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
+++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.cc
@@ -7,6 +7,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/callback.h"
 #include "base/containers/contains.h"
 #include "chrome/browser/apps/app_service/app_platform_metrics.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
@@ -16,6 +17,9 @@
 #include "chrome/browser/chromeos/full_restore/full_restore_app_launch_handler.h"
 #include "chrome/browser/chromeos/full_restore/full_restore_arc_task_handler.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chromeos/services/cros_healthd/public/cpp/service_connection.h"
+#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
+#include "components/full_restore/app_launch_info.h"
 #include "components/full_restore/full_restore_read_handler.h"
 #include "components/full_restore/restore_data.h"
 #include "components/services/app_service/public/cpp/types_util.h"
@@ -23,6 +27,14 @@
 namespace chromeos {
 namespace full_restore {
 
+namespace {
+
+constexpr int kCpuUsageRefreshIntervalInSeconds = 1;
+constexpr int kCpuUsageCountWindowLength =
+    6 * kCpuUsageRefreshIntervalInSeconds;
+
+}  // namespace
+
 ArcAppLaunchHandler::ArcAppLaunchHandler() = default;
 ArcAppLaunchHandler::~ArcAppLaunchHandler() = default;
 
@@ -90,10 +102,22 @@
   if (!HasRestoreData())
     return;
 
+  // Receive the memory pressure level.
   if (chromeos::ResourcedClient::Get() &&
       !resourced_client_observer_.IsObserving()) {
     resourced_client_observer_.Observe(chromeos::ResourcedClient::Get());
   }
+
+  // Receive the system CPU usage rate.
+  if (!probe_service_ || !probe_service_.is_connected()) {
+    cros_healthd::ServiceConnection::GetInstance()->GetProbeService(
+        probe_service_.BindNewPipeAndPassReceiver());
+    probe_service_.set_disconnect_handler(
+        base::BindOnce(&ArcAppLaunchHandler::OnProbeServiceDisconnect,
+                       weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  StartCpuUsageCount();
 }
 
 void ArcAppLaunchHandler::LoadRestoreData() {
@@ -224,5 +248,59 @@
     no_stack_windows_.erase(it);
 }
 
+int ArcAppLaunchHandler::GetCpuUsageRate() {
+  uint64_t idle = 0, sum = 0;
+  for (const auto& tick : cpu_tick_window_) {
+    idle += tick.idle_time;
+    sum += tick.idle_time + tick.used_time;
+  }
+
+  // Convert to xx% percentage.
+  return sum ? int(100 * (sum - idle) / sum) : 0;
+}
+
+void ArcAppLaunchHandler::StartCpuUsageCount() {
+  cpu_tick_count_timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromSeconds(kCpuUsageRefreshIntervalInSeconds),
+      base::BindRepeating(&ArcAppLaunchHandler::UpdateCpuUsage,
+                          base::Unretained(this)));
+}
+
+void ArcAppLaunchHandler::StopCpuUsageCount() {
+  cpu_tick_count_timer_.Stop();
+}
+
+void ArcAppLaunchHandler::UpdateCpuUsage() {
+  probe_service_->ProbeTelemetryInfo(
+      {chromeos::cros_healthd::mojom::ProbeCategoryEnum::kCpu},
+      base::BindOnce(&ArcAppLaunchHandler::OnCpuUsageUpdated,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ArcAppLaunchHandler::OnCpuUsageUpdated(
+    chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr) {
+  CpuTick tick;
+  // For simplicity, assume that device has only one physical CPU.
+  for (const auto& logical_cpu :
+       info_ptr->cpu_result->get_cpu_info()->physical_cpus[0]->logical_cpus) {
+    tick.idle_time += logical_cpu->idle_time_user_hz;
+    tick.used_time +=
+        logical_cpu->user_time_user_hz + logical_cpu->system_time_user_hz;
+  }
+
+  if (last_cpu_tick_.has_value())
+    cpu_tick_window_.push_back(tick - last_cpu_tick_.value());
+  last_cpu_tick_ = tick;
+
+  // Sliding window for CPU usage count.
+  while (cpu_tick_window_.size() > kCpuUsageCountWindowLength)
+    cpu_tick_window_.pop_front();
+}
+
+void ArcAppLaunchHandler::OnProbeServiceDisconnect() {
+  probe_service_.reset();
+}
+
 }  // namespace full_restore
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
index 403c158..a469cdf4 100644
--- a/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
+++ b/chrome/browser/chromeos/full_restore/arc_app_launch_handler.h
@@ -10,8 +10,12 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
+#include "base/timer/timer.h"
 #include "chromeos/dbus/resourced/resourced_client.h"
+#include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace apps {
 class AppUpdate;
@@ -24,6 +28,14 @@
 class ArcWindowHandler;
 class FullRestoreAppLaunchHandler;
 
+struct CpuTick {
+  uint64_t idle_time = 0;
+  uint64_t used_time = 0;
+  CpuTick operator-(const CpuTick& rhs) const {
+    return {idle_time - rhs.idle_time, used_time - rhs.used_time};
+  }
+};
+
 // The ArcAppLaunchHandler class restores ARC apps during the system startup
 // phase.
 //
@@ -80,6 +92,16 @@
   // Invoked when the app of the given `app_id` is removed.
   void RemoveApp(const std::string& app_id);
 
+  // Returns [0, 100] as percentage of device CPU usage rate.
+  int GetCpuUsageRate();
+
+  void StartCpuUsageCount();
+  void StopCpuUsageCount();
+  void UpdateCpuUsage();
+  void OnCpuUsageUpdated(
+      chromeos::cros_healthd::mojom::TelemetryInfoPtr info_ptr);
+  void OnProbeServiceDisconnect();
+
   FullRestoreAppLaunchHandler* handler_ = nullptr;
 
   // The app id list to be restored. When the ARC app is ready in
@@ -100,6 +122,13 @@
   chromeos::ResourcedClient::PressureLevel pressure_level_ =
       chromeos::ResourcedClient::PressureLevel::MODERATE;
 
+  mojo::Remote<cros_healthd::mojom::CrosHealthdProbeService> probe_service_;
+
+  // Cpu usage rate count window. It save the cpu usage in a time interval.
+  std::list<CpuTick> cpu_tick_window_;
+  absl::optional<CpuTick> last_cpu_tick_;
+  base::RepeatingTimer cpu_tick_count_timer_;
+
   base::ScopedObservation<apps::AppRegistryCache,
                           apps::AppRegistryCache::Observer>
       app_registry_cache_observer_{this};
diff --git a/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc b/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc
index 8d5997b..4fe06d02 100644
--- a/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc
+++ b/chrome/browser/chromeos/input_method/component_extension_ime_manager_delegate_impl.cc
@@ -281,7 +281,7 @@
   if (!dict.GetList(extensions::manifest_keys::kLayouts, &layouts))
     return false;
 
-  if (layouts->empty() || !layouts->GetString(0, &out->layout)) {
+  if (layouts->GetList().empty() || !layouts->GetString(0, &out->layout)) {
     out->layout = "us";
   }
 
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h b/chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h
index 4259f4c..93d9e587 100644
--- a/chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h
+++ b/chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h
@@ -101,4 +101,12 @@
 }  // namespace input_method
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+namespace input_method {
+using ::chromeos::input_method::MockInputMethodManagerImpl;
+}
+}  // namespace ash
+
 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_INPUT_METHOD_MANAGER_IMPL_H_
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine.cc b/chrome/browser/chromeos/input_method/native_input_method_engine.cc
index 116a42b..088a8d1 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine.cc
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine.cc
@@ -290,12 +290,17 @@
 // Returns nullptr if it's not convertible.
 // Not using a UnionTraits here because the mapping is not 1:1.
 mojom::DomKeyPtr DomKeyToMojom(const ui::DomKey& key) {
+  // `IsCharacter` may return true for named keys like Enter because they have a
+  // Unicode representation. Hence, try to convert the key into a named key
+  // first before trying to convert it to a character key.
+  absl::optional<mojom::NamedDomKey> named_key = NamedDomKeyToMojom(key);
+  if (named_key) {
+    return mojom::DomKey::NewNamedKey(*named_key);
+  }
   if (key.IsCharacter()) {
     return mojom::DomKey::NewCodepoint(key.ToCharacter());
   }
-
-  absl::optional<mojom::NamedDomKey> named_key = NamedDomKeyToMojom(key);
-  return named_key ? mojom::DomKey::NewNamedKey(*named_key) : nullptr;
+  return nullptr;
 }
 
 // Returns nullptr if it's not convertible.
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
index 113466c..ed1d4e5 100644
--- a/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/native_input_method_engine_unittest.cc
@@ -395,6 +395,61 @@
   InputMethodManager::Shutdown();
 }
 
+TEST_F(NativeInputMethodEngineTest, ProcessesNamedKeysCorrectly) {
+  TestingProfile testing_profile;
+  SetPhysicalTypingAutocorrectEnabled(testing_profile, true);
+
+  testing::StrictMock<MockInputMethod> mock_input_method;
+  input_method::InputMethodManager::Initialize(
+      new TestInputMethodManager(&mock_input_method));
+  ui::MockIMEInputContextHandler mock_handler;
+  ui::IMEBridge::Get()->SetInputContextHandler(&mock_handler);
+  NativeInputMethodEngine engine;
+  engine.Initialize(std::make_unique<StubInputMethodEngineObserver>(),
+                    /*extension_id=*/"", &testing_profile);
+
+  {
+    testing::InSequence seq;
+    EXPECT_CALL(mock_input_method, OnFocus(_));
+
+    // TODO(https://crbug.com/1187982): Expect the actual arguments to the call
+    // once the Mojo API is replaced with protos. GMock does not play well with
+    // move-only types like PhysicalKeyEvent.
+    EXPECT_CALL(mock_input_method, ProcessKeyEvent(_, _))
+        .Times(4)
+        .WillRepeatedly(::testing::Invoke(
+            [](ime::mojom::PhysicalKeyEventPtr event,
+               ime::mojom::InputMethod::ProcessKeyEventCallback callback) {
+              EXPECT_TRUE(event->key->is_named_key());
+              std::move(callback).Run(
+                  ime::mojom::KeyEventResult::kNeedsHandlingBySystem);
+            }));
+  }
+
+  engine.Enable(kEngineIdUs);
+  engine.FocusIn(ui::IMEEngineHandlerInterface::InputContext(
+      ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT,
+      ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_MOUSE,
+      /*should_do_learning=*/true));
+
+  // Enter and Backspace are named keys with Unicode representation.
+  engine.ProcessKeyEvent(
+      {ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::DomCode::ENTER, ui::EF_NONE,
+       ui::DomKey::ENTER, base::TimeTicks()},
+      base::DoNothing());
+  engine.ProcessKeyEvent({ui::ET_KEY_RELEASED, ui::VKEY_RETURN, ui::EF_NONE},
+                         base::DoNothing());
+  engine.ProcessKeyEvent(
+      {ui::ET_KEY_PRESSED, ui::VKEY_BACK, ui::DomCode::BACKSPACE, ui::EF_NONE,
+       ui::DomKey::BACKSPACE, base::TimeTicks()},
+      base::DoNothing());
+  engine.ProcessKeyEvent({ui::ET_KEY_RELEASED, ui::VKEY_BACK, ui::EF_NONE},
+                         base::DoNothing());
+  engine.FlushForTesting();
+
+  InputMethodManager::Shutdown();
+}
+
 // TODO(crbug.com/1148157): Refactor NativeInputMethodEngine etc. to avoid
 // hidden dependencies on globals such as ImeBridge.
 class NativeInputMethodEngineWithRenderViewHostTest
diff --git a/chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc b/chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc
index eb8c2ed..978b32e 100644
--- a/chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc
+++ b/chrome/browser/chromeos/policy/handlers/site_isolation_flag_handling_browsertest.cc
@@ -52,9 +52,6 @@
 
 namespace em = ::enterprise_management;
 
-// TODO(https://crbug.com/1164001): remove once this file is migrated.
-using ::ash::ChromeUserManagerImpl;
-
 struct Params {
   Params(std::string login_screen_isolate_origins,
          std::string user_policy_isolate_origins,
@@ -240,8 +237,8 @@
         std::make_unique<ash::SessionStateWaiter>();
   }
 
-  ChromeUserManagerImpl* GetChromeUserManager() const {
-    return static_cast<ChromeUserManagerImpl*>(
+  ash::ChromeUserManagerImpl* GetChromeUserManager() const {
+    return static_cast<ash::ChromeUserManagerImpl*>(
         user_manager::UserManager::Get());
   }
 
@@ -257,8 +254,9 @@
   bool attempt_restart_called_ = false;
 
   // This is important because ephemeral users only work on enrolled machines.
-  DeviceStateMixin device_state_{
-      &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
+  ash::DeviceStateMixin device_state_{
+      &mixin_host_,
+      ash::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
   ash::UserPolicyMixin user_policy_{
       &mixin_host_,
       AccountId::FromUserEmailGaiaId(kTestUserAccountId, kTestUserGaiaId)};
diff --git a/chrome/browser/chromeos/policy/networking/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/networking/network_configuration_updater_unittest.cc
index 685978d6..5fd1f1b2 100644
--- a/chrome/browser/chromeos/policy/networking/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/networking/network_configuration_updater_unittest.cc
@@ -326,7 +326,7 @@
 }
 
 MATCHER(IsListEmpty, std::string(negation ? "isn't" : "is") + " empty.") {
-  return arg.empty();
+  return arg.GetList().empty();
 }
 
 MATCHER(IsDictEmpty, std::string(negation ? "isn't" : "is") + " empty.") {
diff --git a/chrome/browser/chromeos/policy/reporting/extension_install_event_log_uploader.cc b/chrome/browser/chromeos/policy/reporting/extension_install_event_log_uploader.cc
index f9af74c3..6a9f2e6 100644
--- a/chrome/browser/chromeos/policy/reporting/extension_install_event_log_uploader.cc
+++ b/chrome/browser/chromeos/policy/reporting/extension_install_event_log_uploader.cc
@@ -276,7 +276,6 @@
                  std::unique_ptr<::reporting::ReportQueue> report_queue,
                  base::OnceCallback<void()> on_set_cb) {
                 uploader->SetReportQueue(std::move(report_queue));
-                std::move(on_set_cb);
               },
               std::move(uploader), std::move(report_queue),
               std::move(on_set_cb));
diff --git a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.cc b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.cc
index 397cc51..c625cb80 100644
--- a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.cc
+++ b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.cc
@@ -7,6 +7,7 @@
 #include <time.h>
 
 #include <algorithm>
+#include <memory>
 #include <utility>
 
 #include "base/bind.h"
@@ -16,6 +17,8 @@
 #include "base/memory/ptr_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_executor.h"
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/task_executor_with_retries.h"
 #include "chromeos/settings/cros_settings_names.h"
 #include "chromeos/settings/timezone_settings.h"
@@ -26,191 +29,16 @@
 
 namespace {
 
-// The tag associated to register |update_check_timer_|.
-constexpr char kUpdateCheckTimerTag[] = "DeviceScheduledUpdateChecker";
-
 // Reason associated to acquire |ScopedWakeLock|.
 constexpr char kWakeLockReason[] = "DeviceScheduledUpdateChecker";
 
-ScheduledTaskExecutor::Frequency GetFrequency(const std::string& frequency) {
-  if (frequency == "DAILY")
-    return ScheduledTaskExecutor::Frequency::kDaily;
-
-  if (frequency == "WEEKLY")
-    return ScheduledTaskExecutor::Frequency::kWeekly;
-
-  DCHECK_EQ(frequency, "MONTHLY");
-  return ScheduledTaskExecutor::Frequency::kMonthly;
-}
-
-// Convert the string day of week to UCalendarDaysOfWeek.
-UCalendarDaysOfWeek StringDayOfWeekToIcuDayOfWeek(
-    const std::string& day_of_week) {
-  if (day_of_week == "SUNDAY")
-    return UCAL_SUNDAY;
-  if (day_of_week == "MONDAY")
-    return UCAL_MONDAY;
-  if (day_of_week == "TUESDAY")
-    return UCAL_TUESDAY;
-  if (day_of_week == "WEDNESDAY")
-    return UCAL_WEDNESDAY;
-  if (day_of_week == "THURSDAY")
-    return UCAL_THURSDAY;
-  if (day_of_week == "FRIDAY")
-    return UCAL_FRIDAY;
-  DCHECK_EQ(day_of_week, "SATURDAY");
-  return UCAL_SATURDAY;
-}
-
-// Returns true iff a >= b.
-bool IsCalGreaterThanEqual(const icu::Calendar& a, const icu::Calendar& b) {
-  UErrorCode status = U_ZERO_ERROR;
-  if (a.after(b, status)) {
-    DCHECK(U_SUCCESS(status));
-    return true;
-  }
-
-  if (a.equals(b, status)) {
-    DCHECK(U_SUCCESS(status));
-    return true;
-  }
-
-  return false;
-}
-
-// Advances |time| based on the policy represented by
-// |scheduled_update_check_data|.
-//
-// For daily policy - Advances |time| by 1 day.
-// For weekly policy - Advances |time| by 1 week.
-// For monthly policy - Advances |time| by 1 month.
-//
-// Returns true on success and false if it failed to set a valid time.
-bool AdvanceTimeBasedOnPolicy(
-    const ScheduledTaskExecutor::ScheduledTaskData& scheduled_update_check_data,
-    icu::Calendar* time) {
-  UCalendarDateFields field = UCAL_MONTH;
-  switch (scheduled_update_check_data.frequency) {
-    case ScheduledTaskExecutor::Frequency::kDaily:
-      field = UCAL_DAY_OF_MONTH;
-      break;
-    case ScheduledTaskExecutor::Frequency::kWeekly:
-      field = UCAL_WEEK_OF_YEAR;
-      break;
-    case ScheduledTaskExecutor::Frequency::kMonthly:
-      break;
-  }
-  UErrorCode status = U_ZERO_ERROR;
-  time->add(field, 1, status);
-  return U_SUCCESS(status);
-}
-
-// Sets |time| based on the policy represented by |scheduled_update_check_data|.
-// Returns true on success and false if it failed to set a valid time.
-bool SetTimeBasedOnPolicy(
-    const ScheduledTaskExecutor::ScheduledTaskData& scheduled_update_check_data,
-    icu::Calendar* time) {
-  // Set the daily fields first as they will be common across different policy
-  // types.
-  time->set(UCAL_HOUR_OF_DAY, scheduled_update_check_data.hour);
-  time->set(UCAL_MINUTE, scheduled_update_check_data.minute);
-  time->set(UCAL_SECOND, 0);
-  time->set(UCAL_MILLISECOND, 0);
-
-  switch (scheduled_update_check_data.frequency) {
-    case ScheduledTaskExecutor::Frequency::kDaily:
-      return true;
-
-    case ScheduledTaskExecutor::Frequency::kWeekly:
-      DCHECK(scheduled_update_check_data.day_of_week);
-      time->set(UCAL_DAY_OF_WEEK,
-                scheduled_update_check_data.day_of_week.value());
-      return true;
-
-    case ScheduledTaskExecutor::Frequency::kMonthly: {
-      DCHECK(scheduled_update_check_data.day_of_month);
-      UErrorCode status = U_ZERO_ERROR;
-      // If policy's |day_of_month| is greater than the maximum days in |time|'s
-      // current month then it's set to the last day in the month.
-      int cur_max_days_in_month =
-          time->getActualMaximum(UCAL_DAY_OF_MONTH, status);
-      if (U_FAILURE(status)) {
-        LOG(ERROR) << "Failed to get max days in month";
-        return false;
-      }
-
-      time->set(UCAL_DAY_OF_MONTH,
-                std::min(scheduled_update_check_data.day_of_month.value(),
-                         cur_max_days_in_month));
-      return true;
-    }
-  }
-}
+// Task name used for parsing ScheduledTaskData.
+constexpr char kTaskTimeFieldName[] = "update_check_time";
 
 }  // namespace
 
 namespace update_checker_internal {
 
-absl::optional<ScheduledTaskExecutor::ScheduledTaskData> ParseScheduledUpdate(
-    const base::Value& value) {
-  ScheduledTaskExecutor::ScheduledTaskData result;
-  // Parse mandatory values first i.e. hour, minute and frequency of update
-  // check. These should always be present due to schema validation at higher
-  // layers.
-  const base::Value* hour_value = value.FindPathOfType(
-      {"update_check_time", "hour"}, base::Value::Type::INTEGER);
-  DCHECK(hour_value);
-  int hour = hour_value->GetInt();
-  // Validated by schema validation at higher layers.
-  DCHECK(hour >= 0 && hour <= 23);
-  result.hour = hour;
-
-  const base::Value* minute_value = value.FindPathOfType(
-      {"update_check_time", "minute"}, base::Value::Type::INTEGER);
-  DCHECK(minute_value);
-  int minute = minute_value->GetInt();
-  // Validated by schema validation at higher layers.
-  DCHECK(minute >= 0 && minute <= 59);
-  result.minute = minute;
-
-  // Validated by schema validation at higher layers.
-  const std::string* frequency = value.FindStringKey({"frequency"});
-  DCHECK(frequency);
-  result.frequency = GetFrequency(*frequency);
-
-  // Parse extra fields for weekly and monthly frequencies.
-  switch (result.frequency) {
-    case ScheduledTaskExecutor::Frequency::kDaily:
-      break;
-
-    case ScheduledTaskExecutor::Frequency::kWeekly: {
-      const std::string* day_of_week = value.FindStringKey({"day_of_week"});
-      if (!day_of_week) {
-        LOG(ERROR) << "Day of week missing";
-        return absl::nullopt;
-      }
-
-      // Validated by schema validation at higher layers.
-      result.day_of_week = StringDayOfWeekToIcuDayOfWeek(*day_of_week);
-      break;
-    }
-
-    case ScheduledTaskExecutor::Frequency::kMonthly: {
-      absl::optional<int> day_of_month = value.FindIntKey({"day_of_month"});
-      if (!day_of_month) {
-        LOG(ERROR) << "Day of month missing";
-        return absl::nullopt;
-      }
-
-      // Validated by schema validation at higher layers.
-      result.day_of_month = day_of_month.value();
-      break;
-    }
-  }
-
-  return result;
-}
-
 // Converts an icu::Calendar to base::Time. Assumes |time| is a valid time.
 base::Time IcuToBaseTime(const icu::Calendar& time) {
   UErrorCode status = U_ZERO_ERROR;
@@ -232,7 +60,8 @@
 // so it's safe to use "this" with any callbacks.
 DeviceScheduledUpdateChecker::DeviceScheduledUpdateChecker(
     ash::CrosSettings* cros_settings,
-    chromeos::NetworkStateHandler* network_state_handler)
+    chromeos::NetworkStateHandler* network_state_handler,
+    std::unique_ptr<ScheduledTaskExecutor> update_check_executor)
     : cros_settings_(cros_settings),
       cros_settings_subscription_(cros_settings_->AddSettingsObserver(
           chromeos::kDeviceScheduledUpdateCheck,
@@ -242,7 +71,8 @@
       start_update_check_timer_task_executor_(
           update_checker_internal::kMaxStartUpdateCheckTimerRetryIterations,
           update_checker_internal::kStartUpdateCheckTimerRetryTime),
-      os_and_policies_update_checker_(network_state_handler) {
+      os_and_policies_update_checker_(network_state_handler),
+      update_check_executor_(std::move(update_check_executor)) {
   chromeos::system::TimezoneSettings::GetInstance()->AddObserver(this);
   // Check if policy already exists.
   OnScheduledUpdateCheckDataChanged();
@@ -314,7 +144,7 @@
   // be used to set a new timer.
   absl::optional<ScheduledTaskExecutor::ScheduledTaskData>
       scheduled_update_check_data =
-          update_checker_internal::ParseScheduledUpdate(*value);
+          scheduled_task_util::ParseScheduledTask(*value, kTaskTimeFieldName);
   if (!scheduled_update_check_data) {
     LOG(ERROR) << "Failed to parse policy";
     return;
@@ -328,58 +158,6 @@
       false /* is_retry */);
 }
 
-base::TimeDelta
-DeviceScheduledUpdateChecker::CalculateNextUpdateCheckTimerDelay(
-    base::Time cur_time) {
-  DCHECK(scheduled_update_check_data_);
-
-  const auto cur_cal =
-      scheduled_task_internal::ConvertUtcToTzIcuTime(cur_time, GetTimeZone());
-  if (!cur_cal) {
-    LOG(ERROR) << "Failed to get current ICU time";
-    return scheduled_task_internal::kInvalidDelay;
-  }
-
-  auto update_check_time = base::WrapUnique(cur_cal->clone());
-  DCHECK(update_check_time);
-
-  // Set update check time based on the policy in
-  // |scheduled_update_check_data_|.
-  if (!SetTimeBasedOnPolicy(scheduled_update_check_data_.value(),
-                            update_check_time.get())) {
-    LOG(ERROR) << "Failed to set time based on policy";
-    return scheduled_task_internal::kInvalidDelay;
-  }
-
-  // If the time has already passed it means that the update check needs to be
-  // advanced based on the policy i.e. by a day, week or month. The equal to
-  // case happens when the |OnUpdateCheckTimerExpired| runs and sets the next
-  // |update_check_timer_|. In this case |update_check_time| definitely needs to
-  // advance as per the policy. The |SetTimeBasedOnPolicy| is needed for the
-  // monthly frequency, it won't change the time after advancing for daily or
-  // weekly frequencies. For monthly, if the current time is Feb 28, 1970, 8PM
-  // and an update check needs to happen on 7PM every 31st, then setting time
-  // above and advancing time below gets us a time of Mar 28, 1970, 7PM. An
-  // extra call to |SetTimeBasedOnPolicy| is required to finally get Mar 31,
-  // 1970 7PM.
-  if (IsCalGreaterThanEqual(*cur_cal, *update_check_time)) {
-    if (!AdvanceTimeBasedOnPolicy(scheduled_update_check_data_.value(),
-                                  update_check_time.get())) {
-      LOG(ERROR) << "Failed to advance time";
-      return scheduled_task_internal::kInvalidDelay;
-    }
-
-    if (!SetTimeBasedOnPolicy(scheduled_update_check_data_.value(),
-                              update_check_time.get())) {
-      LOG(ERROR) << "Failed to set time based on policy";
-      return scheduled_task_internal::kInvalidDelay;
-    }
-  }
-  DCHECK(!IsCalGreaterThanEqual(*cur_cal, *update_check_time));
-
-  return scheduled_task_internal::GetDiff(*update_check_time, *cur_cal);
-}
-
 void DeviceScheduledUpdateChecker::StartUpdateCheckTimer(
     ScopedWakeLock scoped_wake_lock) {
   // The device shouldn't suspend while calculating time ticks and setting the
@@ -388,49 +166,16 @@
   // entire task. The wake lock could already be held at this
   // point due to |OnUpdateCheckTimerExpired|.
 
-  // Only one |StartUpdateCheckTimer| can be outstanding.
-  update_check_timer_.reset();
-
-  DCHECK(scheduled_update_check_data_);
-
-  // For accuracy of the next update check, capture current time as close to
-  // the start of this function as possible.
-  const base::TimeTicks cur_ticks = GetTicksSinceBoot();
-  const base::Time cur_time = GetCurrentTime();
-
-  // If this is a retry then |cur_ticks| could be >=
-  // |next_scheudled_task_time_ticks| i.e. the next timer schedule has already
-  // passed, recalculate it. Else respect the calculated time.
-  if (cur_ticks >=
-      scheduled_update_check_data_->next_scheduled_task_time_ticks) {
-    // Calculate the next update check time. In case there is an error while
-    // calculating, due to concurrent DST or Time Zone changes, then reschedule
-    // this function and try to schedule the update check again. There should
-    // only be one outstanding task to start the timer. If there is a failure
-    // the wake lock is released and acquired again when this task runs.
-    base::TimeDelta delay = CalculateNextUpdateCheckTimerDelay(cur_time);
-    if (delay <= scheduled_task_internal::kInvalidDelay) {
-      LOG(ERROR) << "Failed to calculate next update check time";
-      MaybeStartUpdateCheckTimer(std::move(scoped_wake_lock),
-                                 true /* is_retry */);
-      return;
-    }
-    scheduled_update_check_data_->next_scheduled_task_time_ticks =
-        cur_ticks + delay;
-  }
-
-  // |update_check_timer_| will be destroyed as part of this object and is
+  // |update_check_executor_| will be destroyed as part of this object and is
   // guaranteed to not run callbacks after its destruction. Therefore, it's
-  // safe to use "this" while starting the timer.
-  update_check_timer_ =
-      std::make_unique<chromeos::NativeTimer>(kUpdateCheckTimerTag);
-  update_check_timer_->Start(
-      scheduled_update_check_data_->next_scheduled_task_time_ticks,
-      base::BindOnce(&DeviceScheduledUpdateChecker::OnUpdateCheckTimerExpired,
-                     base::Unretained(this)),
+  // safe to use base::Unretained(this) when starting the executor.
+  update_check_executor_->Start(
+      &scheduled_update_check_data_.value(),
       base::BindOnce(
           &DeviceScheduledUpdateChecker::OnUpdateCheckTimerStartResult,
-          base::Unretained(this), std::move(scoped_wake_lock)));
+          base::Unretained(this), std::move(scoped_wake_lock)),
+      base::BindOnce(&DeviceScheduledUpdateChecker::OnUpdateCheckTimerExpired,
+                     base::Unretained(this)));
 }
 
 void DeviceScheduledUpdateChecker::OnUpdateCheckTimerStartResult(
@@ -495,25 +240,10 @@
 }
 
 void DeviceScheduledUpdateChecker::ResetState() {
-  update_check_timer_.reset();
+  update_check_executor_->Reset();
   scheduled_update_check_data_ = absl::nullopt;
   os_and_policies_update_checker_.Stop();
   start_update_check_timer_task_executor_.Stop();
 }
 
-base::Time DeviceScheduledUpdateChecker::GetCurrentTime() {
-  return base::Time::Now();
-}
-
-base::TimeTicks DeviceScheduledUpdateChecker::GetTicksSinceBoot() {
-  struct timespec ts = {};
-  int ret = clock_gettime(CLOCK_BOOTTIME, &ts);
-  DCHECK_EQ(ret, 0);
-  return base::TimeTicks() + base::TimeDelta::FromTimeSpec(ts);
-}
-
-const icu::TimeZone& DeviceScheduledUpdateChecker::GetTimeZone() {
-  return chromeos::system::TimezoneSettings::GetInstance()->GetTimezone();
-}
-
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h
index 61b2638..3d34b18 100644
--- a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h
+++ b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h
@@ -15,7 +15,6 @@
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_executor.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/scoped_wake_lock.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/task_executor_with_retries.h"
-#include "chromeos/dbus/power/native_timer.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/settings/timezone_settings.h"
 #include "services/device/public/mojom/wake_lock.mojom-forward.h"
@@ -32,7 +31,8 @@
  public:
   DeviceScheduledUpdateChecker(
       ash::CrosSettings* cros_settings,
-      chromeos::NetworkStateHandler* network_state_handler);
+      chromeos::NetworkStateHandler* network_state_handler,
+      std::unique_ptr<ScheduledTaskExecutor> update_check_executor);
   ~DeviceScheduledUpdateChecker() override;
 
   // chromeos::system::TimezoneSettings::Observer implementation.
@@ -43,12 +43,6 @@
   // schedules the next update check based on |scheduled_update_check_data_|.
   virtual void OnUpdateCheckTimerExpired();
 
-  // Calculates the delay from |cur_time| at which |update_check_timer_| should
-  // run next. Returns 0 delay if the calculation failed due to a concurrent DST
-  // or Time Zone change. Requires |scheduled_update_check_data_| to be set.
-  virtual base::TimeDelta CalculateNextUpdateCheckTimerDelay(
-      base::Time cur_time);
-
   // Called when |os_and_policies_update_checker_| has finished successfully or
   // unsuccessfully after retrying.
   virtual void OnUpdateCheckCompletion(ScopedWakeLock scoped_wake_lock,
@@ -83,15 +77,6 @@
   // Reset all state and cancel all pending tasks
   void ResetState();
 
-  // Returns current time.
-  virtual base::Time GetCurrentTime();
-
-  // Returns time ticks from boot including time ticks spent during sleeping.
-  virtual base::TimeTicks GetTicksSinceBoot();
-
-  // Returns the current time zone.
-  virtual const icu::TimeZone& GetTimeZone();
-
   // Used to retrieve Chrome OS settings. Not owned.
   ash::CrosSettings* const cros_settings_;
 
@@ -109,13 +94,16 @@
   OsAndPoliciesUpdateChecker os_and_policies_update_checker_;
 
   // Timer that is scheduled to check for updates.
-  std::unique_ptr<chromeos::NativeTimer> update_check_timer_;
+  std::unique_ptr<ScheduledTaskExecutor> update_check_executor_;
 
   DISALLOW_COPY_AND_ASSIGN(DeviceScheduledUpdateChecker);
 };
 
 namespace update_checker_internal {
 
+// The tag associated to register |update_check_executor_|.
+constexpr char kUpdateCheckTimerTag[] = "DeviceScheduledUpdateChecker";
+
 // The timeout after which an OS and policies update is aborted.
 constexpr base::TimeDelta kOsAndPoliciesUpdateCheckHardTimeout =
     base::TimeDelta::FromMinutes(40);
@@ -128,11 +116,6 @@
 constexpr base::TimeDelta kStartUpdateCheckTimerRetryTime =
     base::TimeDelta::FromMinutes(1);
 
-// Parses |value| into a |ScheduledUpdateCheckData|. Returns nullopt if there
-// is any error while parsing |value|.
-absl::optional<ScheduledTaskExecutor::ScheduledTaskData> ParseScheduledUpdate(
-    const base::Value& value);
-
 // Converts an icu::Calendar to base::Time. Assumes |time| is valid.
 base::Time IcuToBaseTime(const icu::Calendar& time);
 
diff --git a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker_unittest.cc b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker_unittest.cc
index 98e35b0..5e8be1e 100644
--- a/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker_unittest.cc
+++ b/chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/device_scheduled_update_checker.h"
 
 #include <algorithm>
+#include <memory>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -24,6 +25,7 @@
 #include "chrome/browser/ash/settings/stub_cros_settings_provider.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/os_and_policies_update_checker.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_executor.h"
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h"
 #include "chrome/browser/chromeos/policy/scheduled_task_handler/scoped_wake_lock.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -54,6 +56,12 @@
 constexpr char kISTTimeZoneID[] = "Asia/Kolkata";
 constexpr char kPSTTimeZoneID[] = "America/Los_Angeles";
 
+// The tag associated to register |update_check_timer_|.
+constexpr char kUpdateCheckTimerTagForTest[] =
+    "DeviceScheduledUpdateCheckerForTest";
+
+constexpr char kTaskTimeFieldName[] = "update_check_time";
+
 void DecodeJsonStringAndNormalize(const std::string& json_string,
                                   base::Value* value) {
   base::JSONReader::ValueWithError parsed_json =
@@ -218,15 +226,11 @@
 
 }  // namespace
 
-class DeviceScheduledUpdateCheckerForTest
-    : public DeviceScheduledUpdateChecker {
+class ScheduledTaskExecutorForTest : public ScheduledTaskExecutor {
  public:
-  DeviceScheduledUpdateCheckerForTest(
-      ash::CrosSettings* cros_settings,
-      chromeos::NetworkStateHandler* network_state_handler,
-      const base::Clock* clock,
-      const base::TickClock* tick_clock)
-      : DeviceScheduledUpdateChecker(cros_settings, network_state_handler),
+  ScheduledTaskExecutorForTest(const base::Clock* clock,
+                               const base::TickClock* tick_clock)
+      : ScheduledTaskExecutor(kUpdateCheckTimerTagForTest),
         clock_(clock),
         tick_clock_(tick_clock) {
     // Set time zone so that tests are deterministic across different
@@ -235,6 +239,61 @@
         icu::UnicodeString::fromUTF8(kESTTimeZoneID)));
   }
 
+  ScheduledTaskExecutorForTest(const ScheduledTaskExecutorForTest&) = delete;
+  ScheduledTaskExecutorForTest& operator=(const ScheduledTaskExecutorForTest&) =
+      delete;
+
+  ~ScheduledTaskExecutorForTest() override {}
+
+  void SetTimeZone(std::unique_ptr<icu::TimeZone> time_zone) {
+    time_zone_ = std::move(time_zone);
+  }
+
+  base::Time GetCurrentTime() override { return clock_->Now(); }
+
+  const icu::TimeZone& GetTimeZone() override { return *time_zone_; }
+
+  void SimulateCalculateNextUpdateCheckFailure(bool simulate) {
+    simulate_calculate_next_update_check_failure_ = simulate;
+  }
+
+  base::TimeDelta CalculateNextScheduledTaskTimerDelay(
+      base::Time cur_time,
+      ScheduledTaskData* scheduled_task_data) override {
+    if (simulate_calculate_next_update_check_failure_)
+      return scheduled_task_internal::kInvalidDelay;
+    return ScheduledTaskExecutor::CalculateNextScheduledTaskTimerDelay(
+        cur_time, scheduled_task_data);
+  }
+
+ private:
+  base::TimeTicks GetTicksSinceBoot() override {
+    return tick_clock_->NowTicks();
+  }
+  // Clock to use to get current time.
+  const base::Clock* const clock_;
+
+  // Clock to use to calculate time ticks.
+  const base::TickClock* const tick_clock_;
+
+  // The current time zone.
+  std::unique_ptr<icu::TimeZone> time_zone_;
+
+  // If set then |CalculateNextUpdateCheckTimerDelay| returns zero delay.
+  bool simulate_calculate_next_update_check_failure_ = false;
+};
+
+class DeviceScheduledUpdateCheckerForTest
+    : public DeviceScheduledUpdateChecker {
+ public:
+  DeviceScheduledUpdateCheckerForTest(
+      ash::CrosSettings* cros_settings,
+      chromeos::NetworkStateHandler* network_state_handler,
+      std::unique_ptr<ScheduledTaskExecutor> task_executor)
+      : DeviceScheduledUpdateChecker(cros_settings,
+                                     network_state_handler,
+                                     std::move(task_executor)) {}
+
   ~DeviceScheduledUpdateCheckerForTest() override {
     TestingBrowserProcess::GetGlobal()->ShutdownBrowserPolicyConnector();
   }
@@ -245,27 +304,6 @@
 
   int GetUpdateCheckCompletions() const { return update_check_completions_; }
 
-  void SimulateCalculateNextUpdateCheckFailure(bool simulate) {
-    simulate_calculate_next_update_check_failure_ = simulate;
-  }
-
-  void SetTimeZone(std::unique_ptr<icu::TimeZone> time_zone) {
-    time_zone_ = std::move(time_zone);
-    DeviceScheduledUpdateChecker::TimezoneChanged(*time_zone_);
-  }
-
-  base::Time GetCurrentTime() override { return clock_->Now(); }
-
-  const icu::TimeZone& GetTimeZone() override { return *time_zone_; }
-
-  base::TimeDelta CalculateNextUpdateCheckTimerDelay(
-      base::Time cur_time) override {
-    if (simulate_calculate_next_update_check_failure_)
-      return scheduled_task_internal::kInvalidDelay;
-    return DeviceScheduledUpdateChecker::CalculateNextUpdateCheckTimerDelay(
-        cur_time);
-  }
-
  private:
   void OnUpdateCheckTimerExpired() override {
     ++update_check_timer_expirations_;
@@ -280,28 +318,12 @@
         std::move(scoped_wake_lock), result);
   }
 
-  base::TimeTicks GetTicksSinceBoot() override {
-    return tick_clock_->NowTicks();
-  }
-
-  // Clock to use to get current time.
-  const base::Clock* const clock_;
-
-  // Clock to use to calculate time ticks.
-  const base::TickClock* const tick_clock_;
-
-  // The current time zone.
-  std::unique_ptr<icu::TimeZone> time_zone_;
-
   // Number of calls to |OnUpdateCheckTimerExpired|.
   int update_check_timer_expirations_ = 0;
 
   // Number of calls to |OnUpdateCheckCompletion| with |result| = true.
   int update_check_completions_ = 0;
 
-  // If set then |CalculateNextUpdateCheckTimerDelay| returns zero delay.
-  bool simulate_calculate_next_update_check_failure_ = false;
-
   DISALLOW_COPY_AND_ASSIGN(DeviceScheduledUpdateCheckerForTest);
 };
 
@@ -328,12 +350,14 @@
         std::make_unique<chromeos::NetworkStateTestHelper>(
             true /* use_default_devices_and_services */);
 
+    auto task_executor = std::make_unique<ScheduledTaskExecutorForTest>(
+        task_environment_.GetMockClock(), task_environment_.GetMockTickClock());
+    scheduled_task_executor_ = task_executor.get();
     device_scheduled_update_checker_ =
         std::make_unique<DeviceScheduledUpdateCheckerForTest>(
             ash::CrosSettings::Get(),
             network_state_test_helper_->network_state_handler(),
-            task_environment_.GetMockClock(),
-            task_environment_.GetMockTickClock());
+            std::move(task_executor));
   }
 
   ~DeviceScheduledUpdateCheckerTest() override {
@@ -464,9 +488,9 @@
     // Calculate time from one hour from now and set the update check policy to
     // happen daily at that time.
     base::Time update_check_time =
-        device_scheduled_update_checker_->GetCurrentTime() + delay;
+        scheduled_task_executor_->GetCurrentTime() + delay;
     auto update_check_icu_time = scheduled_task_internal::ConvertUtcToTzIcuTime(
-        update_check_time, device_scheduled_update_checker_->GetTimeZone());
+        update_check_time, scheduled_task_executor_->GetTimeZone());
 
     // Extracting fields from valid ICU time should always succeed.
     UErrorCode status = U_ZERO_ERROR;
@@ -515,9 +539,8 @@
   // update check timer. Returns false if |tz_id| is the same as the current
   // time zone or on a scheduling error.
   bool CheckRecalculationOnTimezoneChange(const std::string& new_tz_id) {
-    base::Time cur_time = device_scheduled_update_checker_->GetCurrentTime();
-    const icu::TimeZone& cur_tz =
-        device_scheduled_update_checker_->GetTimeZone();
+    base::Time cur_time = scheduled_task_executor_->GetCurrentTime();
+    const icu::TimeZone& cur_tz = scheduled_task_executor_->GetTimeZone();
     auto new_tz = base::WrapUnique(
         icu::TimeZone::createTimeZone(icu::UnicodeString::fromUTF8(new_tz_id)));
     if (cur_tz == *new_tz) {
@@ -553,7 +576,9 @@
 
     // Change the time zone. This should change the time at which the timer
     // should expire.
-    device_scheduled_update_checker_->SetTimeZone(std::move(new_tz));
+    scheduled_task_executor_->SetTimeZone(std::move(new_tz));
+    device_scheduled_update_checker_->TimezoneChanged(
+        scheduled_task_executor_->GetTimeZone());
 
     // Fast forward right before the new time zone's expected timer expiration
     // time and check if no new events happened.
@@ -586,6 +611,8 @@
   }
 
   base::test::TaskEnvironment task_environment_;
+  // Owned by |device_scheduled_update_checker_|
+  ScheduledTaskExecutorForTest* scheduled_task_executor_;
   std::unique_ptr<DeviceScheduledUpdateCheckerForTest>
       device_scheduled_update_checker_;
   ash::ScopedTestingCrosSettings cros_settings_;
@@ -655,9 +682,8 @@
   base::TimeDelta delay_from_now = base::TimeDelta::FromHours(1);
   auto policy_and_next_update_check_time =
       CreatePolicy(delay_from_now, ScheduledTaskExecutor::Frequency::kMonthly);
-  auto scheduled_update_check_data =
-      update_checker_internal::ParseScheduledUpdate(
-          policy_and_next_update_check_time.first);
+  auto scheduled_update_check_data = scheduled_task_util::ParseScheduledTask(
+      policy_and_next_update_check_time.first, kTaskTimeFieldName);
   ASSERT_TRUE(scheduled_update_check_data);
   ASSERT_TRUE(scheduled_update_check_data->day_of_month);
   auto first_update_check_icu_time =
@@ -697,8 +723,7 @@
   base::Time second_update_check_time =
       update_checker_internal::IcuToBaseTime(*first_update_check_icu_time);
   base::TimeDelta second_update_check_delay =
-      second_update_check_time -
-      device_scheduled_update_checker_->GetCurrentTime();
+      second_update_check_time - scheduled_task_executor_->GetCurrentTime();
   EXPECT_GT(second_update_check_delay, scheduled_task_internal::kInvalidDelay);
   task_environment_.FastForwardBy(second_update_check_delay);
   // Simulate update check succeeding.
@@ -718,9 +743,8 @@
   base::TimeDelta delay_from_now = base::TimeDelta::FromHours(1);
   auto policy_and_next_update_check_time =
       CreatePolicy(delay_from_now, ScheduledTaskExecutor::Frequency::kMonthly);
-  auto scheduled_update_check_data =
-      update_checker_internal::ParseScheduledUpdate(
-          policy_and_next_update_check_time.first);
+  auto scheduled_update_check_data = scheduled_task_util::ParseScheduledTask(
+      policy_and_next_update_check_time.first, kTaskTimeFieldName);
   ASSERT_TRUE(scheduled_update_check_data);
   ASSERT_TRUE(scheduled_update_check_data->day_of_month);
   auto update_check_icu_time =
@@ -749,7 +773,7 @@
         update_checker_internal::IcuToBaseTime(*update_check_icu_time);
     base::TimeDelta expected_next_update_check_delay =
         expected_next_update_check_time -
-        device_scheduled_update_checker_->GetCurrentTime();
+        scheduled_task_executor_->GetCurrentTime();
     // This should be always set in a virtual time environment.
     EXPECT_GT(expected_next_update_check_delay,
               scheduled_task_internal::kInvalidDelay);
@@ -777,8 +801,7 @@
 TEST_F(DeviceScheduledUpdateCheckerTest, CheckRetryLogicEventualSuccess) {
   // This will simulate an error while calculating the next update check time
   // and will result in no update checks happening till its set.
-  device_scheduled_update_checker_->SimulateCalculateNextUpdateCheckFailure(
-      true);
+  scheduled_task_executor_->SimulateCalculateNextUpdateCheckFailure(true);
 
   // Calculate time from one hour from now and set the update check policy to
   // happen daily at that time.
@@ -804,8 +827,7 @@
   // Reset failure mode and fast forward by the retry period. This time it
   // should succeed in setting an update check timer. No update checks should
   // happen yet but a check has just been scheduled.
-  device_scheduled_update_checker_->SimulateCalculateNextUpdateCheckFailure(
-      false);
+  scheduled_task_executor_->SimulateCalculateNextUpdateCheckFailure(false);
   task_environment_.FastForwardBy(
       update_checker_internal::kStartUpdateCheckTimerRetryTime);
   EXPECT_TRUE(CheckStats(expected_update_checks, expected_update_check_requests,
@@ -844,8 +866,7 @@
        CheckRetryLogicCapWithCalculationFailure) {
   // This will simulate an error while calculating the next update check time
   // and will result in no update checks happening till its set.
-  device_scheduled_update_checker_->SimulateCalculateNextUpdateCheckFailure(
-      true);
+  scheduled_task_executor_->SimulateCalculateNextUpdateCheckFailure(true);
   EXPECT_FALSE(CheckDailyUpdateCheck(1 /* hours_from_now */));
 
   // Fast forward by max retries * retry period and check that no update has
@@ -859,8 +880,7 @@
 
   // At this point all state has been reset. Reset failure mode and check if
   // daily update checks happen.
-  device_scheduled_update_checker_->SimulateCalculateNextUpdateCheckFailure(
-      false);
+  scheduled_task_executor_->SimulateCalculateNextUpdateCheckFailure(false);
   EXPECT_TRUE(CheckDailyUpdateCheck(1 /* hours_from_now */));
 }
 
diff --git a/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.cc b/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.cc
new file mode 100644
index 0000000..43db40c4
--- /dev/null
+++ b/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.cc
@@ -0,0 +1,105 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h"
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "third_party/icu/source/i18n/unicode/calendar.h"
+
+namespace policy {
+namespace {
+ScheduledTaskExecutor::Frequency GetFrequency(const std::string& frequency) {
+  if (frequency == "DAILY")
+    return ScheduledTaskExecutor::Frequency::kDaily;
+
+  if (frequency == "WEEKLY")
+    return ScheduledTaskExecutor::Frequency::kWeekly;
+
+  DCHECK_EQ(frequency, "MONTHLY");
+  return ScheduledTaskExecutor::Frequency::kMonthly;
+}
+
+// Convert the string day of week to UCalendarDaysOfWeek.
+UCalendarDaysOfWeek StringDayOfWeekToIcuDayOfWeek(
+    const std::string& day_of_week) {
+  if (day_of_week == "SUNDAY")
+    return UCAL_SUNDAY;
+  if (day_of_week == "MONDAY")
+    return UCAL_MONDAY;
+  if (day_of_week == "TUESDAY")
+    return UCAL_TUESDAY;
+  if (day_of_week == "WEDNESDAY")
+    return UCAL_WEDNESDAY;
+  if (day_of_week == "THURSDAY")
+    return UCAL_THURSDAY;
+  if (day_of_week == "FRIDAY")
+    return UCAL_FRIDAY;
+  DCHECK_EQ(day_of_week, "SATURDAY");
+  return UCAL_SATURDAY;
+}
+}  // namespace
+
+namespace scheduled_task_util {
+absl::optional<ScheduledTaskExecutor::ScheduledTaskData> ParseScheduledTask(
+    const base::Value& value,
+    const std::string& task_time_field_name) {
+  ScheduledTaskExecutor::ScheduledTaskData result;
+  // Parse mandatory values first i.e. hour, minute and frequency of update
+  // check. These should always be present due to schema validation at higher
+  // layers.
+  const base::Value* hour_value = value.FindPathOfType(
+      {task_time_field_name, "hour"}, base::Value::Type::INTEGER);
+  DCHECK(hour_value);
+  int hour = hour_value->GetInt();
+  // Validated by schema validation at higher layers.
+  DCHECK(hour >= 0 && hour <= 23);
+  result.hour = hour;
+
+  const base::Value* minute_value = value.FindPathOfType(
+      {task_time_field_name, "minute"}, base::Value::Type::INTEGER);
+  DCHECK(minute_value);
+  int minute = minute_value->GetInt();
+  // Validated by schema validation at higher layers.
+  DCHECK(minute >= 0 && minute <= 59);
+  result.minute = minute;
+
+  // Validated by schema validation at higher layers.
+  const std::string* frequency = value.FindStringKey({"frequency"});
+  DCHECK(frequency);
+  result.frequency = GetFrequency(*frequency);
+
+  // Parse extra fields for weekly and monthly frequencies.
+  switch (result.frequency) {
+    case ScheduledTaskExecutor::Frequency::kDaily:
+      break;
+
+    case ScheduledTaskExecutor::Frequency::kWeekly: {
+      const std::string* day_of_week = value.FindStringKey({"day_of_week"});
+      if (!day_of_week) {
+        LOG(ERROR) << "Day of week missing";
+        return absl::nullopt;
+      }
+
+      // Validated by schema validation at higher layers.
+      result.day_of_week = StringDayOfWeekToIcuDayOfWeek(*day_of_week);
+      break;
+    }
+
+    case ScheduledTaskExecutor::Frequency::kMonthly: {
+      absl::optional<int> day_of_month = value.FindIntKey({"day_of_month"});
+      if (!day_of_month) {
+        LOG(ERROR) << "Day of month missing";
+        return absl::nullopt;
+      }
+
+      // Validated by schema validation at higher layers.
+      result.day_of_month = day_of_month.value();
+      break;
+    }
+  }
+
+  return result;
+}
+}  // namespace scheduled_task_util
+}  // namespace policy
diff --git a/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h b/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h
new file mode 100644
index 0000000..6ac9be2c
--- /dev/null
+++ b/chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_util.h
@@ -0,0 +1,36 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_TASK_HANDLER_SCHEDULED_TASK_UTIL_H_
+#define CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_TASK_HANDLER_SCHEDULED_TASK_UTIL_H_
+
+#include <string>
+
+#include "base/values.h"
+#include "chrome/browser/chromeos/policy/scheduled_task_handler/scheduled_task_executor.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace policy {
+
+// Utility methods for scheduled device policies.
+namespace scheduled_task_util {
+
+// Parses |value| into a |ScheduledTaskData|. Returns nullopt if there
+// is any error while parsing |value|.
+//
+// It is expected that the value has the following fields:
+// |task_time_field_name| - time of the day when the task should occur. The name
+// of the field is passed as an argument to ParseScheduledTask method.
+// |frequency| - frequency of reccurring task. Can be daily, weekly or monthly.
+// |day_of_week| - optional field, used for policies that recurr weekly.
+// |day_of_month| - optional field, used for policies that recurr monthly.
+absl::optional<ScheduledTaskExecutor::ScheduledTaskData> ParseScheduledTask(
+    const base::Value& value,
+    const std::string& task_time_field_name);
+
+}  // namespace scheduled_task_util
+
+}  // namespace policy
+
+#endif  // CHROME_BROWSER_CHROMEOS_POLICY_SCHEDULED_TASK_HANDLER_SCHEDULED_TASK_UTIL_H_
diff --git a/chrome/browser/chromeos/shutdown_policy_browsertest.cc b/chrome/browser/chromeos/shutdown_policy_browsertest.cc
index a2d5dc1..882f3c4b 100644
--- a/chrome/browser/chromeos/shutdown_policy_browsertest.cc
+++ b/chrome/browser/chromeos/shutdown_policy_browsertest.cc
@@ -180,7 +180,7 @@
     ShutdownPolicyBaseTest::SetUpOnMainThread();
 
     // Bring up the locker screen.
-    chromeos::ScreenLockerTester().Lock();
+    ScreenLockerTester().Lock();
   }
 
   void TearDownOnMainThread() override {
diff --git a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.cc b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.cc
index cc4860f..7e57fb6 100644
--- a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.cc
+++ b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.cc
@@ -30,8 +30,12 @@
     base::Time end,
     bool success,
     MerchantSignals data) {
-  int deleted_items_count = 0;
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!HasValidDB()) {
+    return;
+  }
 
+  int deleted_items_count = 0;
   for (const auto& item : data) {
     MerchantSignalProto proto = std::move(item.second);
     base::Time time_created = base::Time::FromDoubleT(
@@ -51,8 +55,12 @@
     const base::flat_set<std::string>& deleted_hostnames,
     bool success,
     MerchantSignals data) {
-  int deleted_items_count = 0;
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!HasValidDB()) {
+    return;
+  }
 
+  int deleted_items_count = 0;
   for (const auto& item : data) {
     MerchantSignalProto proto = std::move(item.second);
 
@@ -70,7 +78,7 @@
 void MerchantViewerDataManager::OnLoadCallbackSingleEntry(
     bool success,
     MerchantSignals data) {
-  if (success && data.size() == 1) {
+  if (success && data.size() == 1 && HasValidDB()) {
     MerchantSignalProto proto = std::move(data.at(0).second);
     proto_db_->DeleteOneEntry(proto.key(), base::BindOnce(&OnUpdateCallback));
   }
@@ -78,6 +86,11 @@
 
 void MerchantViewerDataManager::DeleteMerchantViewerDataForOrigins(
     const base::flat_set<GURL>& deleted_origins) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!HasValidDB()) {
+    return;
+  }
+
   auto force_delete_all_merchants =
       commerce::kDeleteAllMerchantsOnClearBrowsingHistory.Get();
   if (force_delete_all_merchants) {
@@ -101,6 +114,11 @@
 void MerchantViewerDataManager::DeleteMerchantViewerDataForTimeRange(
     base::Time created_after,
     base::Time created_before) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!HasValidDB()) {
+    return;
+  }
+
   bool force_delete_all_merchants =
       commerce::kDeleteAllMerchantsOnClearBrowsingHistory.Get();
   if (force_delete_all_merchants) {
@@ -115,8 +133,14 @@
 }
 
 void MerchantViewerDataManager::ClearAllMerchants() {
-  DCHECK(proto_db_) << "Invalid protodb instance.";
-  proto_db_->DeleteAllContent(base::BindOnce(&OnUpdateCallback));
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (HasValidDB()) {
+    proto_db_->DeleteAllContent(base::BindOnce(&OnUpdateCallback));
+  }
+}
+
+bool MerchantViewerDataManager::HasValidDB() {
+  return proto_db_ != nullptr;
 }
 
 ProfileProtoDB<merchant_signal_db::MerchantSignalContentProto>*
diff --git a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.h b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.h
index baa873d..b296ce50 100644
--- a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.h
+++ b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager.h
@@ -7,6 +7,7 @@
 
 #include "base/containers/flat_set.h"
 #include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
 #include "chrome/browser/persisted_state_db/profile_proto_db.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/leveldb_proto/public/proto_database.h"
@@ -52,6 +53,8 @@
                                             MerchantSignals data);
 
   void ClearAllMerchants();
+  bool HasValidDB();
+  SEQUENCE_CHECKER(sequence_checker_);
   ProfileProtoDB<merchant_signal_db::MerchantSignalContentProto>* proto_db_;
   base::WeakPtrFactory<MerchantViewerDataManager> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc
index c6505348..ac3f46d 100644
--- a/chrome/browser/component_updater/sw_reporter_installer_win.cc
+++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -167,7 +167,7 @@
 
   // If there are no launch parameters, create a single invocation with default
   // behaviour.
-  if (!parameter_list || parameter_list->empty()) {
+  if (!parameter_list || parameter_list->GetList().empty()) {
     base::CommandLine command_line(exe_path);
     command_line.AppendSwitchASCII(chrome_cleaner::kSessionIdSwitch,
                                    session_id);
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 07b2be92..97a28d3a2 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -68,9 +68,9 @@
     "mac";
 #elif defined(OS_WIN)
     "win";
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
+#elif defined(OS_CHROMEOS)
     "cros";
-#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#elif defined(OS_LINUX)
     "linux";
 #else
 #error This file should only be included for supported platforms.
diff --git a/chrome/browser/content_creation/notes/internal/android/BUILD.gn b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
index 96f47d3..298bed0 100644
--- a/chrome/browser/content_creation/notes/internal/android/BUILD.gn
+++ b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
@@ -18,6 +18,7 @@
     "java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java",
     "java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java",
     "java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMediator.java",
+    "java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java",
     "java/src/org/chromium/chrome/browser/content_creation/notes/NoteProperties.java",
     "java/src/org/chromium/chrome/browser/content_creation/notes/NoteServiceFactory.java",
     "java/src/org/chromium/chrome/browser/content_creation/notes/fonts/GoogleFontService.java",
@@ -45,6 +46,7 @@
     "//components/url_formatter/android:url_formatter_java",
     "//content/public/android:content_java_resources",
     "//third_party/android_deps:android_support_v7_appcompat_java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
     "//ui/android:ui_java",
   ]
   resources_package = "org.chromium.chrome.browser.content_creation.internal"
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
index d753dec..1863c4d 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
+++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.content_creation.notes;
 
 import android.app.Activity;
+import android.content.ComponentName;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.os.Build;
@@ -81,6 +82,8 @@
 
     @Override
     public void showDialog() {
+        NoteCreationMetrics.recordNoteCreationSelected();
+
         FragmentActivity fragmentActivity = (FragmentActivity) mActivity;
         mDialog.show(fragmentActivity.getSupportFragmentManager(), null);
     }
@@ -90,6 +93,7 @@
      */
     @Override
     public void dismiss() {
+        NoteCreationMetrics.recordNoteCreationStatus(/*created=*/false);
         mDialog.dismiss();
     }
 
@@ -106,6 +110,9 @@
      */
     @Override
     public void executeAction() {
+        NoteCreationMetrics.recordNoteTemplateSelected();
+        NoteCreationMetrics.recordNoteCreationStatus(/*created=*/true);
+
         View noteView = mDialog.getNoteViewAt(mDialog.getSelectedItemIndex());
 
         assert noteView != null;
@@ -123,6 +130,17 @@
                                     .setFileUris(
                                             new ArrayList<>(Collections.singletonList(imageUri)))
                                     .setFileContentType(PNG_MIME_TYPE)
+                                    .setCallback(new ShareParams.TargetChosenCallback() {
+                                        @Override
+                                        public void onTargetChosen(ComponentName chosenComponent) {
+                                            NoteCreationMetrics.recordNoteShared();
+                                        }
+
+                                        @Override
+                                        public void onCancel() {
+                                            NoteCreationMetrics.recordNoteNotShared();
+                                        }
+                                    })
                                     .build();
 
                     long shareStartTime = System.currentTimeMillis();
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
index 8898eb6..e3ff2b8 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
+++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.content_creation.notes;
 
 import android.app.Dialog;
+import android.content.res.Configuration;
 import android.graphics.Typeface;
 import android.os.Bundle;
 import android.view.View;
@@ -88,6 +89,19 @@
         return builder.create();
     }
 
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        // Re-calculate the left/right paddings for first/last items.
+        if (getNoteViewAt(0) != null) setPadding(true, false, getNoteViewAt(0));
+
+        RecyclerView noteCarousel = mContentView.findViewById(R.id.note_carousel);
+        int lastIndex = noteCarousel.getAdapter().getItemCount() - 1;
+        if (getNoteViewAt(lastIndex) != null) setPadding(false, true, getNoteViewAt(lastIndex));
+        centerCurrentNote();
+    }
+
     /*
      * Creates a note carousel for the provided PropertyModels.
      *
@@ -188,7 +202,7 @@
     // set a smaller padding for the following items (except the last item which has more padding on
     // the right).
     private void setPadding(boolean isFirst, boolean isLast, View itemView) {
-        int dialogWidth = mContentView.getWidth();
+        int dialogWidth = getActivity().getResources().getDisplayMetrics().widthPixels;
         int templateWidth = getActivity().getResources().getDimensionPixelSize(R.dimen.note_width);
         int defaultPadding =
                 getActivity().getResources().getDimensionPixelSize(R.dimen.note_side_padding);
@@ -234,4 +248,13 @@
         View noteView = getNoteViewAt(index);
         noteView.setElevation(0);
     }
+
+    private void centerCurrentNote() {
+        RecyclerView noteCarousel = mContentView.findViewById(R.id.note_carousel);
+        LinearLayoutManager layoutManager = (LinearLayoutManager) noteCarousel.getLayoutManager();
+        int centerOfScreen = getActivity().getResources().getDisplayMetrics().widthPixels / 2
+                - getNoteViewAt(mSelectedItemIndex).getWidth() / 2
+                - getActivity().getResources().getDimensionPixelSize(R.dimen.note_side_padding);
+        layoutManager.scrollToPositionWithOffset(mSelectedItemIndex, centerOfScreen);
+    }
 }
\ No newline at end of file
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java
new file mode 100644
index 0000000..54fb5bb
--- /dev/null
+++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationMetrics.java
@@ -0,0 +1,55 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.content_creation.notes;
+
+import androidx.annotation.IntDef;
+
+import org.chromium.base.metrics.RecordHistogram;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Responsible for recording metrics related to note creation.
+ */
+public final class NoteCreationMetrics {
+    // Constants used to log the Note Creation Funnel enum histogram.
+    @IntDef({NoteCreationFunnel.NOTE_CREATION_SELECTED, NoteCreationFunnel.TEMPLATE_SELECTED,
+            NoteCreationFunnel.NOTE_SHARED})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface NoteCreationFunnel {
+        int NOTE_CREATION_SELECTED = 0;
+        int TEMPLATE_SELECTED = 1;
+        int NOTE_SHARED = 2;
+        int NUM_ENTRIES = 3;
+    }
+
+    public static void recordNoteCreationSelected() {
+        RecordHistogram.recordEnumeratedHistogram("NoteCreation.Funnel",
+                NoteCreationFunnel.NOTE_CREATION_SELECTED, NoteCreationFunnel.NUM_ENTRIES);
+    }
+
+    public static void recordNoteTemplateSelected() {
+        RecordHistogram.recordEnumeratedHistogram("NoteCreation.Funnel",
+                NoteCreationFunnel.TEMPLATE_SELECTED, NoteCreationFunnel.NUM_ENTRIES);
+    }
+
+    public static void recordNoteShared() {
+        RecordHistogram.recordEnumeratedHistogram("NoteCreation.Funnel",
+                NoteCreationFunnel.NOTE_SHARED, NoteCreationFunnel.NUM_ENTRIES);
+        RecordHistogram.recordBooleanHistogram("NoteCreation.NoteShared", true);
+    }
+
+    public static void recordNoteNotShared() {
+        RecordHistogram.recordBooleanHistogram("NoteCreation.NoteShared", false);
+    }
+
+    public static void recordNoteCreationStatus(boolean created) {
+        RecordHistogram.recordBooleanHistogram("NoteCreation.CreationStatus", created);
+    }
+
+    // Empty private constructor for the "static" class.
+    private NoteCreationMetrics() {}
+}
diff --git a/chrome/browser/content_settings/chrome_content_settings_utils.cc b/chrome/browser/content_settings/chrome_content_settings_utils.cc
index cc5c16ef..d70afb8 100644
--- a/chrome/browser/content_settings/chrome_content_settings_utils.cc
+++ b/chrome/browser/content_settings/chrome_content_settings_utils.cc
@@ -13,7 +13,9 @@
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/components/web_app_utils.h"
+#include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
+#include "ui/base/l10n/l10n_util.h"
 #endif
 
 namespace content_settings {
@@ -47,11 +49,22 @@
 std::u16string GetPermissionDetailString(Profile* profile,
                                          ContentSettingsType content_type,
                                          const GURL& url) {
-  if (content_type != ContentSettingsType::FILE_HANDLING || !url.is_valid())
+  if (!url.is_valid())
     return {};
 
-  return web_app::GetFileTypeAssociationsHandledByWebAppsForDisplay(profile,
-                                                                    url);
+  switch (content_type) {
+    case ContentSettingsType::FILE_HANDLING:
+      return web_app::GetFileTypeAssociationsHandledByWebAppsForDisplay(profile,
+                                                                        url);
+      break;
+    case ContentSettingsType::ADS:
+      return l10n_util::GetStringUTF16(IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE);
+      break;
+    default:
+      break;
+  }
+
+  return {};
 }
 #endif
 
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index 56d939d..87ee96b 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -1347,7 +1347,7 @@
   content::test::PrerenderTestHelper prerender_test_helper_;
 };
 
-// Disabled due to https://crbug.com/1225428
+// Flaky on all platforms, see https://crbug.com/1225428
 IN_PROC_BROWSER_TEST_F(ContentSettingsWithPrerenderingBrowserTest,
                        DISABLED_PrerenderingPageSetsCookie) {
   const GURL main_url = embedded_test_server()->GetURL("/empty.html");
@@ -1356,8 +1356,14 @@
 
   ui_test_utils::NavigateToURL(browser(), main_url);
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
+  auto* main_pscs = PageSpecificContentSettings::GetForFrame(
+      GetWebContents()->GetMainFrame());
+  ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
 
-  prerender_test_helper().AddPrerender(prerender_url);
+  CookieChangeObserver cookie_change_observer(GetWebContents());
+  prerender_test_helper().AddPrerenderAsync(prerender_url);
+  cookie_change_observer.Wait();
+  prerender_test_helper().WaitForPrerenderLoadCompletion(prerender_url);
   int host_id = prerender_test_helper().GetHostForUrl(prerender_url);
   content::RenderFrameHost* prerender_frame =
       prerender_test_helper().GetPrerenderedMainFrameHost(host_id);
@@ -1368,8 +1374,6 @@
   EXPECT_TRUE(prerender_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
   EXPECT_EQ(prerender_pscs->allowed_local_shared_objects().GetObjectCount(),
             1u);
-  auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
   EXPECT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
   EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 0u);
 
@@ -1381,15 +1385,8 @@
   EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 1u);
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1224129
-#define MAYBE_PrerenderingPageIframeSetsCookie \
-  DISABLED_PrerenderingPageIframeSetsCookie
-#else
-#define MAYBE_PrerenderingPageIframeSetsCookie PrerenderingPageIframeSetsCookie
-#endif
 IN_PROC_BROWSER_TEST_F(ContentSettingsWithPrerenderingBrowserTest,
-                       MAYBE_PrerenderingPageIframeSetsCookie) {
+                       PrerenderingPageIframeSetsCookie) {
   const GURL main_url = embedded_test_server()->GetURL("/empty.html");
   const GURL prerender_url = embedded_test_server()->GetURL("/title1.html");
   const GURL iframe_url =
@@ -1398,6 +1395,10 @@
   ui_test_utils::NavigateToURL(browser(), main_url);
   ASSERT_EQ(GetWebContents()->GetLastCommittedURL(), main_url);
 
+  auto* main_pscs = PageSpecificContentSettings::GetForFrame(
+      GetWebContents()->GetMainFrame());
+  ASSERT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
+
   prerender_test_helper().AddPrerender(prerender_url);
   int host_id = prerender_test_helper().GetHostForUrl(prerender_url);
   content::RenderFrameHost* prerender_frame =
@@ -1406,12 +1407,16 @@
 
   content::TestNavigationManager navigation_manager(GetWebContents(),
                                                     iframe_url);
+  CookieChangeObserver cookie_observer(GetWebContents());
   EXPECT_TRUE(content::ExecJs(
       prerender_frame,
       content::JsReplace("const iframe = document.createElement('iframe');"
                          "iframe.src = $1;"
                          "document.body.appendChild(iframe);",
                          iframe_url)));
+  EXPECT_TRUE(navigation_manager.WaitForRequestStart());
+  navigation_manager.ResumeNavigation();
+  cookie_observer.Wait();
   navigation_manager.WaitForNavigationFinished();
 
   auto* prerender_pscs =
@@ -1419,8 +1424,6 @@
   EXPECT_TRUE(prerender_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
   EXPECT_EQ(prerender_pscs->allowed_local_shared_objects().GetObjectCount(),
             1u);
-  auto* main_pscs = PageSpecificContentSettings::GetForFrame(
-      GetWebContents()->GetMainFrame());
   EXPECT_FALSE(main_pscs->IsContentAllowed(ContentSettingsType::COOKIES));
   EXPECT_EQ(main_pscs->allowed_local_shared_objects().GetObjectCount(), 0u);
 }
diff --git a/chrome/browser/content_settings/one_time_geolocation_permission_provider.h b/chrome/browser/content_settings/one_time_geolocation_permission_provider.h
index 032205d..f6bee7de 100644
--- a/chrome/browser/content_settings/one_time_geolocation_permission_provider.h
+++ b/chrome/browser/content_settings/one_time_geolocation_permission_provider.h
@@ -20,6 +20,8 @@
 // Stores one-time per-origin geolocation permissions grants that expire as
 // soon as the last tab from an origin is closed but after one day at the
 // latest.
+// TODO(crbug.com/1226750): Use PermissionUtil::CanPermissionBeAllowedOnce to
+// decide which permissions can have one-time grants.
 class OneTimeGeolocationPermissionProvider
     : public content_settings::UserModifiableProvider,
       LastTabStandingTrackerObserver {
diff --git a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducer.java b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducer.java
index a79fb891..159ed3d 100644
--- a/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducer.java
+++ b/chrome/browser/continuous_search/internal/android/java/src/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducer.java
@@ -101,7 +101,11 @@
         int urlCount = 0;
         List<PageGroup> groups = new ArrayList<PageGroup>();
         for (int i = 0; i < groupLabel.length; i++) {
-            if (isAdGroup[i]) continue;
+            if (isAdGroup[i]) {
+                // Account for the resulting group offset to ensure proper indexing.
+                groupOffset += groupSize[i];
+                continue;
+            }
 
             List<PageItem> results = new ArrayList<PageItem>();
             Set<GURL> groupUrls = new HashSet<>();
@@ -112,8 +116,8 @@
                 results.add(new PageItem(urls[groupOffset + j], titles[groupOffset + j]));
                 urlCount++;
             }
-            groupOffset += groupSize[i];
 
+            groupOffset += groupSize[i];
             groups.add(new PageGroup(groupLabel[i], isAdGroup[i], results));
         }
 
diff --git a/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducerTest.java b/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducerTest.java
index f9e39e1..8168f826 100644
--- a/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducerTest.java
+++ b/chrome/browser/continuous_search/internal/android/junit/org/chromium/chrome/browser/continuous_search/SearchResultExtractorProducerTest.java
@@ -95,7 +95,7 @@
         GURL url5 = JUnitTestGURLs.getGURL(JUnitTestGURLs.EXAMPLE_URL);
 
         mSearchResultProducer.onResultsAvailable(mTestUrl, TEST_QUERY, TEST_RESULT_TYPE,
-                new String[] {"Foo", "Bar", "Baz"}, new boolean[] {false, false, true},
+                new String[] {"Foo", "Bar", "Baz"}, new boolean[] {true, false, false},
                 new int[] {1, 3, 1},
                 new String[] {"Foo.com 1", "Bar.com 1", "Bar.com 2", "Bar.com 3", "Baz.com 1"},
                 new GURL[] {url1, url2, url3, url4, url5});
@@ -106,14 +106,15 @@
         }
 
         List<PageGroup> groups = new ArrayList<PageGroup>();
-        List<PageItem> results1 = new ArrayList<PageItem>();
-        results1.add(new PageItem(url1, "Foo.com 1"));
-        groups.add(new PageGroup("Foo", false, results1));
+        // results1 would be an ad group and is skipped.
         List<PageItem> results2 = new ArrayList<PageItem>();
         results2.add(new PageItem(url2, "Bar.com 1"));
         results2.add(new PageItem(url3, "Bar.com 2"));
         results2.add(new PageItem(url4, "Bar.com 3"));
         groups.add(new PageGroup("Bar", false, results2));
+        List<PageItem> results3 = new ArrayList<PageItem>();
+        results3.add(new PageItem(url5, "Baz.com 1"));
+        groups.add(new PageGroup("Baz", false, results3));
 
         verify(mListenerMock, times(1))
                 .onResult(new ContinuousNavigationMetadata(
diff --git a/chrome/browser/dev_ui_browser_resources.grd b/chrome/browser/dev_ui_browser_resources.grd
index 7007638f..d98528209 100644
--- a/chrome/browser/dev_ui_browser_resources.grd
+++ b/chrome/browser/dev_ui_browser_resources.grd
@@ -79,8 +79,6 @@
       <include name="IDR_TRANSLATE_INTERNALS_HTML" file="../../components/translate/translate_internals/translate_internals.html" type="BINDATA" />
       <include name="IDR_TRANSLATE_INTERNALS_JS" file="../../components/translate/translate_internals/translate_internals.js" preprocess="true" type="BINDATA" />
       <include name="IDR_WEB_APP_INTERNALS_HTML" file="resources/web_app_internals/index.html" type="BINDATA" />
-      <include name="IDR_WEB_APP_INTERNALS_JS" file="${root_gen_dir}/chrome/browser/resources/web_app_internals/web_app_internals.js" use_base_dir="false" type="BINDATA" />
-      <include name="IDR_WEB_APP_INTERNALS_MOJOM_LITE_JS" file="${root_gen_dir}/chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_UKM_INTERNALS_HTML" file="../../components/ukm/debug/ukm_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
       <include name="IDR_UKM_INTERNALS_JS" file="../../components/ukm/debug/ukm_internals.js" type="BINDATA" />
       <include name="IDR_UKM_INTERNALS_CSS" file="../../components/ukm/debug/ukm_internals.css" type="BINDATA" />
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index b643135..913e1c8 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -320,7 +320,7 @@
 static std::set<net::HostPortPair> ParseTargetDiscoveryPreferenceValue(
     const base::ListValue* preferenceValue) {
   std::set<net::HostPortPair> targets;
-  if (!preferenceValue || preferenceValue->empty())
+  if (!preferenceValue || preferenceValue->GetList().empty())
     return targets;
   std::string address;
   for (size_t i = 0; i < preferenceValue->GetSize(); i++) {
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
index 810c754..15250a3 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc
@@ -73,9 +73,9 @@
 
 template <typename... Ts>
 struct ParamTuple {
-  bool Parse(const base::ListValue& list,
-             const base::ListValue::const_iterator& it) {
-    return it == list.GetList().end();
+  bool Parse(const std::vector<base::Value>& list,
+             const std::vector<base::Value>::const_iterator& it) {
+    return it == list.end();
   }
 
   template <typename H, typename... As>
@@ -86,10 +86,9 @@
 
 template <typename T, typename... Ts>
 struct ParamTuple<T, Ts...> {
-  bool Parse(const base::ListValue& list,
-             const base::ListValue::const_iterator& it) {
-    return it != list.GetList().end() && GetValue(*it, &head) &&
-           tail.Parse(list, it + 1);
+  bool Parse(const std::vector<base::Value>& list,
+             const std::vector<base::Value>::const_iterator& it) {
+    return it != list.end() && GetValue(*it, &head) && tail.Parse(list, it + 1);
   }
 
   template <typename H, typename... As>
@@ -104,9 +103,9 @@
 template <typename... As>
 bool ParseAndHandle(const base::RepeatingCallback<void(As...)>& handler,
                     DispatchCallback callback,
-                    const base::ListValue& list) {
+                    const std::vector<base::Value>& list) {
   ParamTuple<As...> tuple;
-  if (!tuple.Parse(list, list.GetList().begin()))
+  if (!tuple.Parse(list, list.begin()))
     return false;
   tuple.Apply(handler);
   return true;
@@ -116,9 +115,9 @@
 bool ParseAndHandleWithCallback(
     const base::RepeatingCallback<void(DispatchCallback, As...)>& handler,
     DispatchCallback callback,
-    const base::ListValue& list) {
+    const std::vector<base::Value>& list) {
   ParamTuple<As...> tuple;
-  if (!tuple.Parse(list, list.GetList().begin()))
+  if (!tuple.Parse(list, list.begin()))
     return false;
   tuple.Apply(handler, std::move(callback));
   return true;
@@ -140,10 +139,9 @@
 
   bool Dispatch(DispatchCallback callback,
                 const std::string& method,
-                const base::ListValue* params) override {
+                const std::vector<base::Value>& params) override {
     auto it = handlers_.find(method);
-    return it != handlers_.end() &&
-           it->second.Run(std::move(callback), *params);
+    return it != handlers_.end() && it->second.Run(std::move(callback), params);
   }
 
   template<typename... As>
@@ -167,7 +165,8 @@
 
  private:
   using Handler =
-      base::RepeatingCallback<bool(DispatchCallback, const base::ListValue&)>;
+      base::RepeatingCallback<bool(DispatchCallback,
+                                   const std::vector<base::Value>&)>;
   using HandlerMap = std::map<std::string, Handler>;
   HandlerMap handlers_;
 };
diff --git a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
index 9b36edc..12f8500b 100644
--- a/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
+++ b/chrome/browser/devtools/devtools_embedder_message_dispatcher.h
@@ -15,7 +15,6 @@
 #include "ui/gfx/geometry/size.h"
 
 namespace base {
-class ListValue;
 class Value;
 }
 
@@ -114,7 +113,7 @@
   virtual ~DevToolsEmbedderMessageDispatcher() = default;
   virtual bool Dispatch(DispatchCallback callback,
                         const std::string& method,
-                        const base::ListValue* params) = 0;
+                        const std::vector<base::Value>& params) = 0;
 
   static std::unique_ptr<DevToolsEmbedderMessageDispatcher>
   CreateForDevToolsFrontend(Delegate* delegate);
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 52b2d46..58ce94c 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -749,13 +749,10 @@
     LOG(ERROR) << "Invalid message was sent to embedder: " << message;
     return;
   }
-  base::Value empty_params(base::Value::Type::LIST);
-  if (!params) {
-    params = &empty_params;
-  }
   int id = message.FindIntKey(kFrontendHostId).value_or(0);
-  base::ListValue* params_list;
-  params->GetAsList(&params_list);
+  std::vector<base::Value> params_list;
+  if (params)
+    params_list = std::move(*params).TakeList();
   embedder_message_dispatcher_->Dispatch(
       base::BindOnce(&DevToolsUIBindings::SendMessageAck,
                      weak_factory_.GetWeakPtr(), id),
diff --git a/chrome/browser/devtools/serialize_host_descriptions.cc b/chrome/browser/devtools/serialize_host_descriptions.cc
index 054acd9..6bd8d13 100644
--- a/chrome/browser/devtools/serialize_host_descriptions.cc
+++ b/chrome/browser/devtools/serialize_host_descriptions.cc
@@ -31,7 +31,7 @@
     }
   }
 
-  if (!children_list->empty())
+  if (!children_list->GetList().empty())
     root->Set(child_key, std::move(children_list));
   return std::move(*root);
 }
diff --git a/chrome/browser/dom_distiller/tab_utils_browsertest.cc b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
index 389a3bf..9e038ff 100644
--- a/chrome/browser/dom_distiller/tab_utils_browsertest.cc
+++ b/chrome/browser/dom_distiller/tab_utils_browsertest.cc
@@ -363,8 +363,14 @@
   ASSERT_EQ(security_state::NONE, helper->GetSecurityLevel());
 }
 
+// TODO(crbug.com/1227141): Flaky on Mac.
+#if defined(OS_MAC)
+#define MAYBE_FaviconFromOriginalPage DISABLED_FaviconFromOriginalPage
+#else
+#define MAYBE_FaviconFromOriginalPage FaviconFromOriginalPage
+#endif
 IN_PROC_BROWSER_TEST_F(DomDistillerTabUtilsBrowserTest,
-                       FaviconFromOriginalPage) {
+                       MAYBE_FaviconFromOriginalPage) {
   content::WebContents* initial_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
diff --git a/chrome/browser/download/download_dir_policy_handler.cc b/chrome/browser/download/download_dir_policy_handler.cc
index 4305639..c009f441 100644
--- a/chrome/browser/download/download_dir_policy_handler.cc
+++ b/chrome/browser/download/download_dir_policy_handler.cc
@@ -92,8 +92,8 @@
   if (policies.Get(policy_name())->level == policy::POLICY_LEVEL_MANDATORY) {
     prefs->SetBoolean(prefs::kPromptForDownload, false);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-    // TODO(https://crbug.com/1148846): Sort out download directory policy for
-    // lacros.
+    // Drive is disabled only in Ash and not Lacros, because Lacros respects
+    // Drive availability status in Ash automatically.
     if (download_dir_util::DownloadToDrive(string_value, parameters)) {
       prefs->SetBoolean(drive::prefs::kDisableDrive, false);
     }
diff --git a/chrome/browser/download/download_dir_policy_handler_unittest.cc b/chrome/browser/download/download_dir_policy_handler_unittest.cc
index 228b0013..460dc8f 100644
--- a/chrome/browser/download/download_dir_policy_handler_unittest.cc
+++ b/chrome/browser/download/download_dir_policy_handler_unittest.cc
@@ -28,7 +28,7 @@
 
 const char* kUserIDHash = "deadbeef";
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 const char* kRelativeToDriveRoot = "/home/";
 #endif
 
@@ -55,7 +55,6 @@
   scoped_refptr<policy::ConfigurationPolicyPrefStore> recommended_store_;
 };
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(DownloadDirPolicyHandlerTest, SetDownloadDirectory) {
   policy::PolicyMap policy;
   EXPECT_FALSE(store_->GetValue(prefs::kPromptForDownload, NULL));
@@ -71,9 +70,8 @@
   ASSERT_TRUE(value->is_bool());
   EXPECT_FALSE(value->GetBool());
 }
-#endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 TEST_F(DownloadDirPolicyHandlerTest, SetDownloadToDrive) {
   EXPECT_FALSE(store_->GetValue(prefs::kPromptForDownload, NULL));
 
@@ -90,10 +88,12 @@
   ASSERT_TRUE(value->is_bool());
   EXPECT_FALSE(value->GetBool());
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   EXPECT_TRUE(store_->GetValue(drive::prefs::kDisableDrive, &value));
   ASSERT_TRUE(value);
   ASSERT_TRUE(value->is_bool());
   EXPECT_FALSE(value->GetBool());
+#endif
 
   std::string download_directory;
   EXPECT_TRUE(store_->GetValue(prefs::kDownloadDefaultDirectory, &value));
diff --git a/chrome/browser/download/download_dir_util.cc b/chrome/browser/download/download_dir_util.cc
index 9d478e17..a42157d 100644
--- a/chrome/browser/download/download_dir_util.cc
+++ b/chrome/browser/download/download_dir_util.cc
@@ -11,19 +11,21 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/drive/drive_integration_service.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chrome/common/chrome_paths_lacros.h"
+#endif
 
 namespace {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 // Drive root folder relative to its mount point.
 const base::FilePath::CharType* kRootRelativeToDriveMount =
     FILE_PATH_LITERAL("root");
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // defined(OS_CHROMEOS)
 }  // namespace
 
 namespace download_dir_util {
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 const char kDriveNamePolicyVariableName[] = "${google_drive}";
 
 bool DownloadToDrive(const base::FilePath::StringType& string_value,
@@ -36,25 +38,31 @@
 bool ExpandDrivePolicyVariable(Profile* profile,
                                const base::FilePath& old_path,
                                base::FilePath* new_path) {
-  auto* integration_service =
-      drive::DriveIntegrationServiceFactory::FindForProfile(profile);
-  if (!integration_service || !integration_service->is_enabled())
-    return false;
-
   size_t position = old_path.value().find(kDriveNamePolicyVariableName);
   if (position == base::FilePath::StringType::npos)
     return false;
 
+  base::FilePath google_drive;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  auto* integration_service =
+      drive::DriveIntegrationServiceFactory::FindForProfile(profile);
+  if (!integration_service || !integration_service->is_enabled())
+    return false;
+  google_drive = integration_service->GetMountPointPath();
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+  bool drivefs_mounted = chrome::GetDriveFsMountPointPath(&google_drive);
+  if (!drivefs_mounted)
+    return false;
+#endif
+
   base::FilePath::StringType google_drive_root =
-      integration_service->GetMountPointPath()
-          .Append(kRootRelativeToDriveMount)
-          .value();
+      google_drive.Append(kRootRelativeToDriveMount).value();
   std::string expanded_value = old_path.value();
   *new_path = base::FilePath(expanded_value.replace(
       position, strlen(kDriveNamePolicyVariableName), google_drive_root));
   return true;
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // defined(OS_CHROMEOS)
 
 base::FilePath::StringType ExpandDownloadDirectoryPath(
     const base::FilePath::StringType& string_value,
diff --git a/chrome/browser/download/download_dir_util.h b/chrome/browser/download/download_dir_util.h
index 7daba8e4..2937262 100644
--- a/chrome/browser/download/download_dir_util.h
+++ b/chrome/browser/download/download_dir_util.h
@@ -6,7 +6,6 @@
 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_DIR_UTIL_H_
 
 #include "base/files/file_path.h"
-#include "build/chromeos_buildflags.h"
 
 class Profile;
 
@@ -16,7 +15,7 @@
 
 namespace download_dir_util {
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if defined(OS_CHROMEOS)
 extern const char kDriveNamePolicyVariableName[];
 
 // Returns whether |string_value| points to a directory in Drive or not.
@@ -29,7 +28,7 @@
 bool ExpandDrivePolicyVariable(Profile* profile,
                                const base::FilePath& old_path,
                                base::FilePath* new_path);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // defined(OS_CHROMEOS)
 
 // Expands path variables in the download directory path |string_value|.
 base::FilePath::StringType ExpandDownloadDirectoryPath(
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index 3903f13..aa15d6e 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -52,7 +52,9 @@
 #include "chrome/browser/ash/drive/file_system_util.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chromeos/dbus/cros_disks_client.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chrome/common/chrome_paths_lacros.h"
+#endif
 
 #if defined(OS_WIN)
 #include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
@@ -555,6 +557,12 @@
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // TODO(https://crbug.com/1148848): Sort out path sanitization for Lacros.
   // This will require refactoring the ash-only code below so it can be shared.
+  base::FilePath migrated_drive_path;
+  if (download_dir_util::ExpandDrivePolicyVariable(profile_, path,
+                                                   &migrated_drive_path)) {
+    return SanitizeDownloadTargetPath(migrated_drive_path);
+  }
+
   const base::FilePath default_downloads_path =
       GetDefaultDownloadDirectoryForProfile();
   // Relative paths might be unsafe, so use the default path.
@@ -573,6 +581,12 @@
   if (documents_path == path || documents_path.IsParent(path))
     return path;
 
+  // Allow paths under the drive mount point.
+  base::FilePath drivefs;
+  bool drivefs_mounted = chrome::GetDriveFsMountPointPath(&drivefs);
+  if (drivefs_mounted && drivefs.IsParent(path))
+    return path;
+
   // Otherwise, return the safe default.
   return default_downloads_path;
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/download/download_prefs_unittest.cc b/chrome/browser/download/download_prefs_unittest.cc
index 1b8c2d9..222f82cb 100644
--- a/chrome/browser/download/download_prefs_unittest.cc
+++ b/chrome/browser/download/download_prefs_unittest.cc
@@ -27,8 +27,11 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "base/hash/md5.h"
 #include "base/path_service.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_paths_lacros.h"
+#include "components/account_id/account_id.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
 using safe_browsing::FileTypePolicies;
@@ -407,7 +410,7 @@
             download_prefs.GetDefaultDownloadDirectory());
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if defined(OS_CHROMEOS)
 void ExpectValidDownloadDir(Profile* profile,
                             DownloadPrefs* prefs,
                             base::FilePath path) {
@@ -437,7 +440,7 @@
                          documents_path.AppendASCII("testdir"));
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
-  // Test with an invalid path outside the download directory.
+  // Test with an invalid path outside the download directory or drivefs.
   profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
                                 "/home/chronos");
   EXPECT_EQ(prefs.DownloadPath(), default_dir);
@@ -465,24 +468,38 @@
       &profile, &prefs,
       base::FilePath(
           "/media/fuse/crostini_0123456789abcdef_termina_penguin/testdir"));
-
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   // DriveFS
   {
     // Create new profile for enabled feature to work.
     TestingProfile profile2(base::FilePath("/home/chronos/u-0123456789abcdef"));
-    ash::FakeChromeUserManager user_manager;
     DownloadPrefs prefs2(&profile2);
     AccountId account_id =
         AccountId::FromUserEmailGaiaId(profile2.GetProfileUserName(), "12345");
+    const std::string drivefs_profile_salt = "a";
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    ash::FakeChromeUserManager user_manager;
     const auto* user = user_manager.AddUser(account_id);
     chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
         user, &profile2);
     chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(
         const_cast<user_manager::User*>(user));
-    profile2.GetPrefs()->SetString(drive::prefs::kDriveFsProfileSalt, "a");
+    profile2.GetPrefs()->SetString(drive::prefs::kDriveFsProfileSalt,
+                                   drivefs_profile_salt);
     auto* integration_service =
         drive::DriveIntegrationServiceFactory::GetForProfile(&profile2);
     integration_service->SetEnabled(true);
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+    base::FilePath documents_dir;
+    base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &documents_dir);
+    base::FilePath downloads_dir;
+    base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_dir);
+    const base::FilePath drivefs = base::FilePath(
+        "/media/fuse/drivefs-" + base::MD5String(drivefs_profile_salt + "-" +
+                                                 account_id.GetAccountIdKey()));
+    chrome::SetLacrosDefaultPaths(/*documents_dir=*/documents_dir,
+                                  /*downloads_dir=*/downloads_dir, drivefs);
+#endif
 
     // My Drive root.
     ExpectValidDownloadDir(
@@ -505,9 +522,8 @@
                                    "/media/fuse/drivefs-something-else/root");
     EXPECT_EQ(prefs2.DownloadPath(), default_dir2);
   }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // defined(OS_CHROMEOS)
 
 #ifdef OS_ANDROID
 TEST(DownloadPrefsTest, DownloadLaterPrefs) {
diff --git a/chrome/browser/download/download_query.cc b/chrome/browser/download/download_query.cc
index 4ab3d0f..7705f8d 100644
--- a/chrome/browser/download/download_query.cc
+++ b/chrome/browser/download/download_query.cc
@@ -46,7 +46,13 @@
 }
 template <>
 bool GetAs(const base::Value& in, double* out) {
-  return in.GetAsDouble(out);
+  // `GetIfDouble()` incapsulates type verification logic.
+  const absl::optional<double> maybe_value = in.GetIfDouble();
+  if (maybe_value.has_value()) {
+    *out = maybe_value.value();
+    return true;
+  }
+  return false;
 }
 template<> bool GetAs(const base::Value& in, std::string* out) {
   return in.GetAsString(out);
diff --git a/chrome/browser/enterprise/DEPS b/chrome/browser/enterprise/DEPS
index 5ae2fc8c..735bfa0 100644
--- a/chrome/browser/enterprise/DEPS
+++ b/chrome/browser/enterprise/DEPS
@@ -1,5 +1,3 @@
 include_rules = [
-  "+chrome/browser/ui/views",
   "+components/enterprise",
 ]
-
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
index 3d78708..979f9b8 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
index c14da402..d76f2d3 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
index 19fc1a25..a0d8913b 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "cc/paint/paint_flags.h"
 #include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h"
-#include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
index 669034b..aa9e89b 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_dialog.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc
index 12b59ba1..fd075782 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc
+++ b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h
index 4c24fbb5..e2bbcbe 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h
+++ b/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc
index 2344ec6c..0e53e7f 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc
@@ -36,8 +36,10 @@
 }
 
 bool DeviceTrustService::IsEnabled() const {
-  return (prefs_->HasPrefPath(kContextAwareAccessSignalsAllowlistPref) &&
-          !prefs_->GetList(kContextAwareAccessSignalsAllowlistPref)->empty());
+  return prefs_->HasPrefPath(kContextAwareAccessSignalsAllowlistPref) &&
+         !prefs_->GetList(kContextAwareAccessSignalsAllowlistPref)
+              ->GetList()
+              .empty();
 }
 
 base::RepeatingCallback<bool()> DeviceTrustService::MakePolicyCheck() {
diff --git a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc
index f485eedb..4aeccd1e 100644
--- a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc
@@ -41,7 +41,9 @@
   // TODO(b/183690432): Check if the browser or device is being managed
   // to create the throttle.
   if (!prefs_->HasPrefPath(kContextAwareAccessSignalsAllowlistPref) ||
-      prefs_->GetList(kContextAwareAccessSignalsAllowlistPref)->empty())
+      prefs_->GetList(kContextAwareAccessSignalsAllowlistPref)
+          ->GetList()
+          .empty())
     return nullptr;
 
   return std::make_unique<DeviceTrustNavigationThrottle>(navigation_handle);
diff --git a/chrome/browser/enterprise/connectors/device_trust/signal_reporter.cc b/chrome/browser/enterprise/connectors/device_trust/signal_reporter.cc
index df1e85f..a0167e6 100644
--- a/chrome/browser/enterprise/connectors/device_trust/signal_reporter.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/signal_reporter.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/signal_reporter.h"
 
+#include "build/chromeos_buildflags.h"
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 
 namespace {
@@ -125,7 +126,11 @@
 }
 
 policy::DMToken DeviceTrustSignalReporter::GetDmToken() const {
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   return policy::BrowserDMTokenStorage::Get()->RetrieveDMToken();
+#else
+  return policy::DMToken();
+#endif
 }
 
 DeviceTrustSignalReporter::QueueConfigStatusOr
diff --git a/chrome/browser/enterprise/connectors/device_trust/signal_reporter_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/signal_reporter_unittest.cc
index a955282..5c3815f 100644
--- a/chrome/browser/enterprise/connectors/device_trust/signal_reporter_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/signal_reporter_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/json/json_writer.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_feature_list.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/enterprise/connectors/device_trust/mock_signal_reporter.h"
 #include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
 #include "components/policy/core/common/cloud/dm_token.h"
@@ -112,7 +113,9 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<base::RunLoop> run_loop_;
   base::OnceClosure quit_closure_;
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::FakeBrowserDMTokenStorage dm_token_storage_;
+#endif
   content::BrowserTaskEnvironment task_environment_;
 };
 
diff --git a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
index 1b6e44c8c..c3225303 100644
--- a/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
+++ b/chrome/browser/enterprise/reporting/browser_report_generator_desktop.cc
@@ -80,10 +80,9 @@
   base::flat_set<base::FilePath> extension_request_profile_paths =
       throttler->GetProfiles();
 
-  for (const auto* entry :
-       g_browser_process->profile_manager()
-           ->GetProfileAttributesStorage()
-           .GetAllProfilesAttributes(/*include_guest_profile=*/false)) {
+  for (const auto* entry : g_browser_process->profile_manager()
+                               ->GetProfileAttributesStorage()
+                               .GetAllProfilesAttributes()) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     // Skip sign-in and lock screen app profile on Chrome OS.
     if (!chromeos::ProfileHelper::IsRegularProfilePath(
diff --git a/chrome/browser/enterprise/reporting/report_scheduler_desktop_unittest.cc b/chrome/browser/enterprise/reporting/report_scheduler_desktop_unittest.cc
index c39515c..f9ce3e3 100644
--- a/chrome/browser/enterprise/reporting/report_scheduler_desktop_unittest.cc
+++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop_unittest.cc
@@ -155,8 +155,10 @@
             const std::string& dm_token,
             const std::string& client_id) {
     ToggleCloudReport(policy_enabled);
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
     storage_.SetDMToken(dm_token);
     storage_.SetClientId(client_id);
+#endif
   }
 
   void CreateScheduler() {
@@ -247,7 +249,9 @@
   MockReportUploader* uploader_;
   MockRealTimeReportGenerator* real_time_generator_;
   MockRealTimeUploader* extension_request_uploader_;
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::FakeBrowserDMTokenStorage storage_;
+#endif
   base::Time previous_set_last_upload_timestamp_;
   base::HistogramTester histogram_tester_;
 
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 662e2c3..9348bc9c 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -807,6 +807,7 @@
     "//chrome/browser/safe_browsing:metrics_collector",
     "//chrome/browser/web_applications",
     "//chrome/browser/web_applications/components",
+    "//components/safe_browsing/content/browser",
     "//components/site_engagement/core/mojom:mojo_bindings",
     "//components/webapps/browser",
 
diff --git a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
index 93df4436..6060eed 100644
--- a/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
+++ b/chrome/browser/extensions/api/braille_display_private/braille_display_private_apitest.cc
@@ -328,7 +328,7 @@
 };
 
 IN_PROC_BROWSER_TEST_F(BrailleDisplayPrivateAPIUserTest, KeyEventOnLockScreen) {
-  chromeos::ScreenLockerTester tester;
+  ash::ScreenLockerTester tester;
 
   // Make sure the signin profile and active profile are different.
   Profile* signin_profile = chromeos::ProfileHelper::GetSigninProfile();
diff --git a/chrome/browser/extensions/api/commands/command_service.cc b/chrome/browser/extensions/api/commands/command_service.cc
index 74dcb19..79ca4e2 100644
--- a/chrome/browser/extensions/api/commands/command_service.cc
+++ b/chrome/browser/extensions/api/commands/command_service.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "chrome/browser/extensions/api/commands/commands.h"
 #include "chrome/browser/extensions/extension_commands_global_registry.h"
 #include "chrome/browser/extensions/extension_keybinding_registry.h"
@@ -584,17 +585,17 @@
         if (!browser_action_command ||
             browser_action_command->accelerator().key_code() ==
                 ui::VKEY_UNKNOWN) {
-          suggested_key_prefs->Remove(it.key(), NULL);
+          suggested_key_prefs->RemoveKey(it.key());
         }
       } else if (it.key() == manifest_values::kPageActionCommandEvent) {
         if (!CommandsInfo::GetPageActionCommand(extension))
-          suggested_key_prefs->Remove(it.key(), NULL);
+          suggested_key_prefs->RemoveKey(it.key());
       } else if (it.key() == manifest_values::kActionCommandEvent) {
         if (!CommandsInfo::GetActionCommand(extension))
-          suggested_key_prefs->Remove(it.key(), nullptr);
+          suggested_key_prefs->RemoveKey(it.key());
       } else if (named_commands) {
         if (named_commands->find(it.key()) == named_commands->end())
-          suggested_key_prefs->Remove(it.key(), NULL);
+          suggested_key_prefs->RemoveKey(it.key());
       }
     }
 
@@ -671,7 +672,7 @@
   for (KeysToRemove::const_iterator it = keys_to_remove.begin();
        it != keys_to_remove.end(); ++it) {
     std::string key = *it;
-    bindings->Remove(key, NULL);
+    bindings->RemoveKey(key);
   }
 
   for (const Command& removed_command : removed_commands) {
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index 0f90fcc..2276d379c 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -6163,6 +6163,7 @@
     feature_list_.InitWithFeaturesAndParameters(
         {{features::kBackForwardCache,
           {{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
+           {"ignore_outstanding_network_request_for_testing", "true"},
            {"all_extensions_allowed", "true"}}}},
         {features::kBackForwardCacheMemoryControls});
   }
@@ -6196,17 +6197,9 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223379
-#define MAYBE_BackForwardCacheClearedOnAddingDynamicRules \
-  DISABLED_BackForwardCacheClearedOnAddingDynamicRules
-#else
-#define MAYBE_BackForwardCacheClearedOnAddingDynamicRules \
-  BackForwardCacheClearedOnAddingDynamicRules
-#endif
 // Ensure that Back Forward is cleared on adding dynamic rules.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBackForwardCacheBrowserTest,
-                       MAYBE_BackForwardCacheClearedOnAddingDynamicRules) {
+                       BackForwardCacheClearedOnAddingDynamicRules) {
   set_config_flags(ConfigFlag::kConfig_HasBackgroundScript);
 
   // Now block requests to script.js.
@@ -6226,17 +6219,9 @@
   bfcache_rfh_delete_observer->WaitUntilDeleted();
 }
 
-#if defined(OS_MAC)
-// https://crbug.com/1223379
-#define MAYBE_BackForwardCacheClearedOnUpdatingSessionRules \
-  DISABLED_BackForwardCacheClearedOnUpdatingSessionRules
-#else
-#define MAYBE_BackForwardCacheClearedOnUpdatingSessionRules \
-  BackForwardCacheClearedOnUpdatingSessionRules
-#endif
 // Ensure that Back Forward is cleared on updating session rules.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBackForwardCacheBrowserTest,
-                       MAYBE_BackForwardCacheClearedOnUpdatingSessionRules) {
+                       BackForwardCacheClearedOnUpdatingSessionRules) {
   set_config_flags(ConfigFlag::kConfig_HasBackgroundScript);
 
   // Now block requests to script.js.
@@ -6256,17 +6241,9 @@
   bfcache_rfh_delete_observer->WaitUntilDeleted();
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223379
-#define MAYBE_BackForwardCacheClearedOnUpdatingEnabledRulesets \
-  DISABLED_BackForwardCacheClearedOnUpdatingEnabledRulesets
-#else
-#define MAYBE_BackForwardCacheClearedOnUpdatingEnabledRulesets \
-  BackForwardCacheClearedOnUpdatingEnabledRulesets
-#endif
 // Ensure that Back Forward is cleared on updating enabled rulesets.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBackForwardCacheBrowserTest,
-                       MAYBE_BackForwardCacheClearedOnUpdatingEnabledRulesets) {
+                       BackForwardCacheClearedOnUpdatingEnabledRulesets) {
   set_config_flags(ConfigFlag::kConfig_HasBackgroundScript);
 
   std::vector<TestRulesetInfo> rulesets;
@@ -6289,17 +6266,9 @@
   bfcache_rfh_delete_observer->WaitUntilDeleted();
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223379
-#define MAYBE_BackForwardCacheClearedOnAddExtension \
-  DISABLED_BackForwardCacheClearedOnAddExtension
-#else
-#define MAYBE_BackForwardCacheClearedOnAddExtension \
-  BackForwardCacheClearedOnAddExtension
-#endif
 // Ensure that Back Forward is cleared on new extension.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBackForwardCacheBrowserTest,
-                       MAYBE_BackForwardCacheClearedOnAddExtension) {
+                       BackForwardCacheClearedOnAddExtension) {
   set_config_flags(ConfigFlag::kConfig_HasBackgroundScript);
 
   auto bfcache_rfh_delete_observer = NavigateForBackForwardCache();
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
index bd036019..e1c936f 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc
@@ -323,7 +323,7 @@
 
 ExtensionFunction::ResponseAction
 EnterprisePlatformKeysInternalGetTokensFunction::Run() {
-  EXTENSION_FUNCTION_VALIDATE(args_->empty());
+  EXTENSION_FUNCTION_VALIDATE(args_->GetList().empty());
 
   std::string error = ValidateCrosapi(KeystoreService::kGetKeyStoresMinVersion,
                                       browser_context());
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/keychain_data_helper_mac.mm b/chrome/browser/extensions/api/enterprise_reporting_private/keychain_data_helper_mac.mm
index 9378c37..b8421cc 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/keychain_data_helper_mac.mm
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/keychain_data_helper_mac.mm
@@ -7,10 +7,10 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <Foundation/Foundation.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 
 namespace extensions {
diff --git a/chrome/browser/extensions/api/force_installed_affiliated_extension_apitest.cc b/chrome/browser/extensions/api/force_installed_affiliated_extension_apitest.cc
index 6dfee2e1..46e8cd7 100644
--- a/chrome/browser/extensions/api/force_installed_affiliated_extension_apitest.cc
+++ b/chrome/browser/extensions/api/force_installed_affiliated_extension_apitest.cc
@@ -76,7 +76,7 @@
   // policy::AffiliationTestHelper::PreLoginUser() in the PRE_ test.
   const base::ListValue* users =
       g_browser_process->local_state()->GetList("LoggedInUsers");
-  if (!users->empty()) {
+  if (!users->GetList().empty()) {
     policy::AffiliationTestHelper::LoginUser(affiliation_mixin_.account_id());
   }
 
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api_unittest.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api_unittest.cc
index 4ac863f..4d1276a 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api_unittest.cc
@@ -50,7 +50,7 @@
       ImageWriterPrivateListRemovableStorageDevicesFunction>();
   std::unique_ptr<base::ListValue> devices =
       RunFunctionAndReturnList(function.get(), "[]");
-  ASSERT_TRUE(devices.get() ? devices.get()->empty() : false)
+  ASSERT_TRUE(devices.get() && devices.get()->GetList().empty())
       << "Under policy ListDevices should return an empty list.";
 }
 
@@ -68,4 +68,4 @@
 
 #endif  // if BUILDFLAG(IS_CHROMEOS_ASH)
 
-}  // namespace extensions
\ No newline at end of file
+}  // namespace extensions
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
index fccd967..a8ad698f 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/common/extensions/api/safe_browsing_private.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_function.h"
@@ -54,7 +55,8 @@
   }
 
   Profile* profile = Profile::FromBrowserContext(browser_context());
-  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(profile))
+  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(
+          profile->GetPrefs(), g_browser_process->safe_browsing_service()))
     return RespondNow(NoArguments());
 
   SafeBrowsingNavigationObserverManager* navigation_observer_manager =
@@ -72,7 +74,7 @@
   // Scout reporting. Otherwise, |CountOfRecentNavigationsToAppend| returns 0.
   int recent_navigations_to_collect =
       SafeBrowsingNavigationObserverManager::CountOfRecentNavigationsToAppend(
-          *profile, result);
+          profile, profile->GetPrefs(), result);
   if (recent_navigations_to_collect > 0) {
     navigation_observer_manager->AppendRecentNavigations(
         recent_navigations_to_collect, &referrer_chain);
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index 5167de4a..64d2fbf 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -1052,9 +1052,11 @@
       // Otherwise if the number is a whole number like 2.0, it will
       // automatically be of type INTEGER causing type mismatches in
       // PrefService::SetUserPrefValue for doubles, and vice versa.
-      double double_value;
-      if (!value->GetAsDouble(&double_value))
+      if (!value->is_double() && !value->is_int())
         return settings_private::SetPrefResult::PREF_TYPE_MISMATCH;
+      double double_value;
+      double_value = value->GetDouble();
+
       if (pref->GetType() == base::Value::Type::DOUBLE)
         pref_service->SetDouble(pref_name, double_value);
       else
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
index 964883d..ddca992 100644
--- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
+++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -514,8 +514,8 @@
     change_list.push_back(
         settings_sync_util::CreateDelete("s2", "foo", model_type));
     GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
-    expected1.Remove("foo", NULL);
-    expected2.Remove("foo", NULL);
+    expected1.RemoveKey("foo");
+    expected2.RemoveKey("foo");
 
     EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
     EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc
index d7c55ac..a094128 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc
@@ -123,8 +123,7 @@
       }
     }
 
-    TabStripModel* tab_strip =
-        ExtensionTabUtil::GetEditableTabStripModel(browser);
+    TabStripModel* tab_strip = browser->tab_strip_model();
     if (!tab_strip)
       return RespondNow(Error(tabs_constants::kTabStripNotEditableQueryError));
     for (const tab_groups::TabGroupId& id :
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc
index c6226d4..7693e94 100644
--- a/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc
+++ b/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc
@@ -550,17 +550,31 @@
   const std::string args =
       base::StringPrintf(R"([%d, {"index": %d}])", group_id, 1);
 
-  // Succeed moving group in normal case.
+  EXPECT_TRUE(browser_window()->IsTabStripEditable());
+
+  // Succeed moving group when tab strip is editable.
   {
     auto function = base::MakeRefCounted<TabGroupsMoveFunction>();
     function->set_extension(extension);
-    ASSERT_TRUE(extension_function_test_utils::RunFunction(
+    EXPECT_TRUE(extension_function_test_utils::RunFunction(
         function.get(), args, browser(), api_test_utils::NONE));
   }
 
+  // Make tab strip uneditable.
+  browser_window()->SetIsTabStripEditable(false);
+  EXPECT_FALSE(browser_window()->IsTabStripEditable());
+
+  // Succeed querying group when tab strip is not editable.
+  {
+    const char* query_args = R"([{"title": "Sample title"}])";
+    auto function = base::MakeRefCounted<TabGroupsQueryFunction>();
+    function->set_extension(extension);
+    EXPECT_TRUE(extension_function_test_utils::RunFunction(
+        function.get(), query_args, browser(), api_test_utils::NONE));
+  }
+
   // Gracefully cancel group tab drag if tab strip isn't editable.
   {
-    browser_window()->SetIsTabStripEditable(false);
     auto function = base::MakeRefCounted<TabGroupsMoveFunction>();
     function->set_extension(extension);
     std::string error =
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 85376cc06..aa0fe0aa 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1167,6 +1167,8 @@
   std::unique_ptr<tabs::Create::Params> params(
       tabs::Create::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
+  if (!ExtensionTabUtil::IsTabStripEditable())
+    return RespondNow(Error(tabs_constants::kTabStripNotEditableError));
 
   ExtensionTabUtil::OpenTabParams options;
   AssignOptionalValue(params->create_properties.window_id, &options.window_id);
@@ -1196,6 +1198,8 @@
   std::unique_ptr<tabs::Duplicate::Params> params(
       tabs::Duplicate::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params.get());
+  if (!ExtensionTabUtil::IsTabStripEditable())
+    return RespondNow(Error(tabs_constants::kTabStripNotEditableError));
   int tab_id = params->tab_id;
 
   Browser* browser = NULL;
diff --git a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
index 5db9d6f..94e5324 100644
--- a/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
+++ b/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc
@@ -415,8 +415,8 @@
 bool ChromeVirtualKeyboardDelegate::IsSettingsEnabled() {
   return (user_manager::UserManager::Get()->IsUserLoggedIn() &&
           !chromeos::UserAddingScreen::Get()->IsRunning() &&
-          !(chromeos::ScreenLocker::default_screen_locker() &&
-            chromeos::ScreenLocker::default_screen_locker()->locked()));
+          !(ash::ScreenLocker::default_screen_locker() &&
+            ash::ScreenLocker::default_screen_locker()->locked()));
 }
 
 void ChromeVirtualKeyboardDelegate::OnClipboardHistoryItemListAddedOrRemoved() {
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index a1eedc7..e5ae528d2 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -32,10 +32,10 @@
 #include "chrome/browser/extensions/install_tracker.h"
 #include "chrome/browser/extensions/scoped_active_install.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/app_list/app_list_util.h"
 #include "chrome/browser/ui/browser_dialogs.h"
@@ -45,6 +45,7 @@
 #include "components/crx_file/id_util.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "content/public/browser/gpu_feature_checker.h"
 #include "content/public/browser/storage_partition.h"
@@ -1151,7 +1152,8 @@
 ExtensionFunction::ResponseAction
 WebstorePrivateGetReferrerChainFunction::Run() {
   Profile* profile = Profile::FromBrowserContext(browser_context());
-  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(profile))
+  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(
+          profile->GetPrefs(), g_browser_process->safe_browsing_service()))
     return RespondNow(ArgumentList(
         api::webstore_private::GetReferrerChain::Results::Create("")));
 
@@ -1177,7 +1179,7 @@
   // Scout reporting. Otherwise, |CountOfRecentNavigationsToAppend| returns 0.
   int recent_navigations_to_collect =
       SafeBrowsingNavigationObserverManager::CountOfRecentNavigationsToAppend(
-          *profile, result);
+          profile, profile->GetPrefs(), result);
   if (recent_navigations_to_collect > 0) {
     navigation_observer_manager->AppendRecentNavigations(
         recent_navigations_to_collect, &referrer_chain);
diff --git a/chrome/browser/extensions/back_forward_cache_browsertest.cc b/chrome/browser/extensions/back_forward_cache_browsertest.cc
index bfd2918..cafd0851 100644
--- a/chrome/browser/extensions/back_forward_cache_browsertest.cc
+++ b/chrome/browser/extensions/back_forward_cache_browsertest.cc
@@ -2,15 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "chrome/browser/extensions/extension_action_runner.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/back_forward_cache/back_forward_cache_disable.h"
 #include "content/public/browser/back_forward_cache.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "extensions/browser/api/messaging/message_service.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/manifest_constants.h"
 #include "net/dns/mock_host_resolver.h"
 #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
 #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-shared.h"
@@ -118,6 +125,43 @@
               content::RenderFrameHost::LifecycleState::kInBackForwardCache);
   }
 
+  void ExpectTitleChangeSuccess(const Extension& extension, const char* title) {
+    const std::string script = base::StringPrintf(R"(
+          chrome.tabs.executeScript({
+            code: "document.title='%s'"
+          });
+        )",
+                                                  title);
+    ExecuteScriptInBackgroundPageNoWait(extension.id(), script);
+
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    std::u16string title16(base::UTF8ToUTF16(title));
+    content::TitleWatcher title_watcher(web_contents, title16);
+    EXPECT_EQ(title16, title_watcher.WaitAndGetTitle());
+  }
+
+  void ExpectTitleChangeFail(const Extension& extension) {
+    constexpr char kScript[] =
+        R"(
+          chrome.tabs.executeScript({code: "document.title='fail'"},
+            () => {
+              if (chrome.runtime.lastError) {
+                window.domAutomationController.send(
+                  chrome.runtime.lastError.message);
+              } else {
+                window.domAutomationController.send("Unexpected success");
+              }
+            });
+        )";
+    EXPECT_EQ(manifest_errors::kCannotAccessPage,
+              ExecuteScriptInBackgroundPage(extension.id(), kScript));
+
+    std::u16string title;
+    ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &title));
+    EXPECT_NE(u"fail", title);
+  }
+
  protected:
   base::HistogramTester histogram_tester_;
 
@@ -196,14 +240,7 @@
   delete_observer_rfh_a.WaitUntilDeleted();
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_ScriptAllowed DISABLED_ScriptAllowed
-#else
-#define MAYBE_ScriptAllowed ScriptAllowed
-#endif
-IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
-                       MAYBE_ScriptAllowed) {
+IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest, ScriptAllowed) {
   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
                                 .AppendASCII("content_script")));
 
@@ -249,13 +286,7 @@
   delete_observer_rfh_a.WaitUntilDeleted();
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_CSSAllowed DISABLED_CSSAllowed
-#else
-#define MAYBE_CSSAllowed CSSAllowed
-#endif
-IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest, MAYBE_CSSAllowed) {
+IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest, CSSAllowed) {
   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
                                 .AppendASCII("content_css")));
 
@@ -279,14 +310,8 @@
             content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_UnloadExtensionFlushCache DISABLED_UnloadExtensionFlushCache
-#else
-#define MAYBE_UnloadExtensionFlushCache UnloadExtensionFlushCache
-#endif
 IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
-                       MAYBE_UnloadExtensionFlushCache) {
+                       UnloadExtensionFlushCache) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
@@ -319,14 +344,8 @@
   delete_observer_rfh_a.WaitUntilDeleted();
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_LoadExtensionFlushCache DISABLED_LoadExtensionFlushCache
-#else
-#define MAYBE_LoadExtensionFlushCache LoadExtensionFlushCache
-#endif
 IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
-                       MAYBE_LoadExtensionFlushCache) {
+                       LoadExtensionFlushCache) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
@@ -616,19 +635,10 @@
           "BackForwardCache.HistoryNavigationOutcome.BlocklistedFeature",
           blink::scheduler::WebSchedulerTrackedFeature::kIsolatedWorldScript));
 }
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_MessageSentToAllFramesDoesNotSendToBackForwardCache \
-  DISABLED_MessageSentToAllFramesDoesNotSendToBackForwardCache
-#else
-#define MAYBE_MessageSentToAllFramesDoesNotSendToBackForwardCache \
-  MessageSentToAllFramesDoesNotSendToBackForwardCache
-#endif
 // Tests sending a message to all frames does not send it to back-forward
 // cached frames.
-IN_PROC_BROWSER_TEST_F(
-    ExtensionBackForwardCacheBrowserTest,
-    MAYBE_MessageSentToAllFramesDoesNotSendToBackForwardCache) {
+IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
+                       MessageSentToAllFramesDoesNotSendToBackForwardCache) {
   const Extension* extension = extension =
       LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
                         .AppendASCII("background_page"));
@@ -762,16 +772,10 @@
                 base::StringPrintf(kScript, iframe_frame_tree_node_id)));
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223240
-#define MAYBE_StorageCallbackEvicts DISABLED_StorageCallbackEvicts
-#else
-#define MAYBE_StorageCallbackEvicts StorageCallbackEvicts
-#endif
 // Test that running extensions message dispatching via a ScriptContext::ForEach
 // for back forward cached pages causes eviction of that RenderFrameHost.
 IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
-                       MAYBE_StorageCallbackEvicts) {
+                       StorageCallbackEvicts) {
   const Extension* extension = extension =
       LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
                         .AppendASCII("content_script_storage"));
@@ -843,6 +847,46 @@
   delete_observer_rfh_a.WaitUntilDeleted();
 }
 
+// Test that ensures the origin restriction declared on the extension
+// manifest.json is properly respected even when BFCache is involved.
+IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest, TabsOrigin) {
+  scoped_refptr<const Extension> extension =
+      LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
+                        .AppendASCII("correct_origin"));
+  ASSERT_TRUE(extension);
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  // 1) Navigate to A.
+  content::RenderFrameHostWrapper rfh_a(
+      ui_test_utils::NavigateToURL(browser(), url_a));
+
+  ExpectTitleChangeSuccess(*extension, "first nav");
+
+  // 2) Navigate to B.
+  ui_test_utils::NavigateToURL(browser(), url_b);
+
+  // Ensure that `rfh_a` is in the cache.
+  EXPECT_FALSE(rfh_a.IsDestroyed());
+  EXPECT_EQ(rfh_a->GetLifecycleState(),
+            content::RenderFrameHost::LifecycleState::kInBackForwardCache);
+
+  ExpectTitleChangeFail(*extension);
+
+  // 3) Go back to A.
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  web_contents->GetController().GoBack();
+  EXPECT_TRUE(WaitForLoadStop(web_contents));
+
+  std::u16string title;
+  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &title));
+  ASSERT_EQ(title, u"first nav");
+  ExpectTitleChangeSuccess(*extension, "restore nav");
+}
+
 // Test that ensures the content scripts only execute once on a back/forward
 // cached page.
 IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
@@ -893,4 +937,50 @@
       EvalJs(rfh_a, "document.getElementById('stage').value;"));
 }
 
+// Test that an activeTab permission temporarily granted to an extension for a
+// page does not revive when the BFCache entry is restored.
+IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBrowserTest,
+                       ActiveTabPermissionRevoked) {
+  scoped_refptr<const Extension> extension =
+      LoadExtension(test_data_dir_.AppendASCII("back_forward_cache")
+                        .AppendASCII("active_tab"));
+  ASSERT_TRUE(extension);
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+  // 1) Navigate to A.
+  content::RenderFrameHostWrapper rfh_a(
+      ui_test_utils::NavigateToURL(browser(), url_a));
+
+  // Grant the activeTab permission.
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ExtensionActionRunner::GetForWebContents(web_contents)
+      ->RunAction(extension.get(), /* grant_tab_permissions=*/true);
+
+  ExpectTitleChangeSuccess(*extension, "changed_title");
+
+  // 2) Navigate to B.
+  ui_test_utils::NavigateToURL(browser(), url_b);
+
+  // Ensure that `rfh_a` is in the cache.
+  EXPECT_FALSE(rfh_a.IsDestroyed());
+  EXPECT_EQ(rfh_a.get()->GetLifecycleState(),
+            content::RenderFrameHost::LifecycleState::kInBackForwardCache);
+
+  // Extension should no longer be able to change title, since the permission
+  // should be revoked with a cross-site navigation.
+  ExpectTitleChangeFail(*extension);
+
+  // 3) Go back to A.
+  web_contents->GetController().GoBack();
+  EXPECT_TRUE(WaitForLoadStop(web_contents));
+
+  // Extension should no longer be able to change title, since the permission
+  // should not revive with BFCache navigation to a.com.
+  ExpectTitleChangeFail(*extension);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/chrome_app_api_browsertest.cc b/chrome/browser/extensions/chrome_app_api_browsertest.cc
index 09fffe2..37e8dadf 100644
--- a/chrome/browser/extensions/chrome_app_api_browsertest.cc
+++ b/chrome/browser/extensions/chrome_app_api_browsertest.cc
@@ -148,7 +148,7 @@
       static_cast<base::DictionaryValue*>(
           base::JSONReader::ReadDeprecated(result).release()));
   // extension->manifest() does not contain the id.
-  app_details->Remove("id", NULL);
+  app_details->RemoveKey("id");
   EXPECT_TRUE(app_details.get());
   EXPECT_TRUE(app_details->Equals(extension->manifest()->value()));
 
diff --git a/chrome/browser/extensions/convert_web_app.cc b/chrome/browser/extensions/convert_web_app.cc
index 4899a037..10e94b2 100644
--- a/chrome/browser/extensions/convert_web_app.cc
+++ b/chrome/browser/extensions/convert_web_app.cc
@@ -366,7 +366,7 @@
     if (!shortcuts_icons->DictEmpty())
       root->Set(keys::kWebAppShortcutIcons, std::move(shortcuts_icons));
 
-    if (!linked_shortcut_items->empty()) {
+    if (!linked_shortcut_items->GetList().empty()) {
       root->Set(keys::kWebAppLinkedShortcutItems,
                 std::move(linked_shortcut_items));
     }
diff --git a/chrome/browser/extensions/extension_allowlist.cc b/chrome/browser/extensions/extension_allowlist.cc
index 9d6cdc37..143ee4d 100644
--- a/chrome/browser/extensions/extension_allowlist.cc
+++ b/chrome/browser/extensions/extension_allowlist.cc
@@ -7,8 +7,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "extensions/browser/allowlist_state.h"
 #include "extensions/browser/extension_registry.h"
diff --git a/chrome/browser/extensions/extension_function_test_utils.cc b/chrome/browser/extensions/extension_function_test_utils.cc
index a87d2e5e..2ec364aa 100644
--- a/chrome/browser/extensions/extension_function_test_utils.cc
+++ b/chrome/browser/extensions/extension_function_test_utils.cc
@@ -101,7 +101,7 @@
   // is no specified result.
   const base::ListValue* results = function->GetResultList();
   CHECK(results);
-  EXPECT_TRUE(results->empty()) << "Did not expect a result";
+  EXPECT_TRUE(results->GetList().empty()) << "Did not expect a result";
   CHECK(function->response_type());
   EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
   return function->GetError();
diff --git a/chrome/browser/extensions/extension_garbage_collector_unittest.cc b/chrome/browser/extensions/extension_garbage_collector_unittest.cc
index ecf7d3d..08491fe2 100644
--- a/chrome/browser/extensions/extension_garbage_collector_unittest.cc
+++ b/chrome/browser/extensions/extension_garbage_collector_unittest.cc
@@ -55,8 +55,8 @@
   {
     DictionaryPrefUpdate update(profile_->GetPrefs(), pref_names::kExtensions);
     base::DictionaryValue* dict = update.Get();
-    ASSERT_TRUE(dict != NULL);
-    dict->Remove(kExtensionId, NULL);
+    ASSERT_TRUE(dict != nullptr);
+    dict->RemoveKey(kExtensionId);
   }
 
   service_->Init();
@@ -90,8 +90,8 @@
   {
     DictionaryPrefUpdate update(profile_->GetPrefs(), pref_names::kExtensions);
     base::DictionaryValue* dict = update.Get();
-    ASSERT_TRUE(dict != NULL);
-    dict->Remove(kExtensionId, NULL);
+    ASSERT_TRUE(dict != nullptr);
+    dict->RemoveKey(kExtensionId);
   }
 
   service_->Init();
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc
index 8ebbfea3..65f78d3 100644
--- a/chrome/browser/extensions/extension_service_test_base.cc
+++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -29,8 +29,10 @@
 #include "chrome/browser/extensions/updater/extension_updater.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/buildflags.h"
 #include "chrome/common/chrome_constants.h"
@@ -103,6 +105,9 @@
         ManagedBookmarkServiceFactory::GetDefaultFactory());
   }
 
+  profile_builder.AddTestingFactory(
+      ChromeSigninClientFactory::GetInstance(),
+      base::BindRepeating(&signin::BuildTestSigninClient));
   profile_builder.AddTestingFactories(
       IdentityTestEnvironmentProfileAdaptor::
           GetIdentityTestEnvironmentFactories());
@@ -348,7 +353,10 @@
 
 void ExtensionServiceTestBase::TearDown() {
   if (profile_) {
-    auto* partition = profile_->GetDefaultStoragePartition();
+    content::StoragePartitionConfig default_storage_partition_config =
+        content::StoragePartitionConfig::CreateDefault(profile_.get());
+    auto* partition = profile_->GetStoragePartition(
+        default_storage_partition_config, /*can_create=*/false);
     if (partition)
       partition->WaitForDeletionTasksForTesting();
   }
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index b3aa21c..544162b 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -396,7 +396,7 @@
       EXPECT_EQ(crx_location_, location);
 
       // Remove it so we won't count it ever again.
-      prefs_->Remove(info.extension_id, nullptr);
+      prefs_->RemoveKey(info.extension_id);
     }
     return true;
   }
@@ -430,7 +430,7 @@
       EXPECT_EQ(parsed_install_parameter, info.install_parameter);
 
       // Remove it so we won't count it again.
-      prefs_->Remove(info.extension_id, nullptr);
+      prefs_->RemoveKey(info.extension_id);
     }
     return true;
   }
@@ -715,7 +715,7 @@
     base::DictionaryValue* pref = nullptr;
     ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
     EXPECT_TRUE(pref) << msg;
-    pref->Remove(pref_path, nullptr);
+    pref->RemovePath(pref_path);
   }
 
   void SetPrefStringSet(const std::string& extension_id,
@@ -6573,7 +6573,8 @@
   EXPECT_TRUE(pending->IsIdPending(kGoodId));
 }
 
-TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
+// TODO(crbug.com/1227104): This test fails when run by TSan buildbots.
+TEST_F(ExtensionServiceTest, DISABLED_ConcurrentExternalLocalFile) {
   base::Version kVersion123("1.2.3");
   base::Version kVersion124("1.2.4");
   base::Version kVersion125("1.2.5");
diff --git a/chrome/browser/extensions/extension_tabs_apitest.cc b/chrome/browser/extensions/extension_tabs_apitest.cc
index a51233d..29fb316 100644
--- a/chrome/browser/extensions/extension_tabs_apitest.cc
+++ b/chrome/browser/extensions/extension_tabs_apitest.cc
@@ -122,7 +122,8 @@
       << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(ExtensionApiTabTest, TabMove) {
+// TODO(crbug.com/1227134): Flaky test.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTabTest, DISABLED_TabMove) {
   ASSERT_TRUE(RunExtensionTest("tabs/basics", {.page_url = "move.html"}))
       << message_;
 }
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index fa5dc9b0..0260a49 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -337,7 +337,7 @@
     // user's prefs are mangled (by malware, user modification, hard drive
     // corruption, evil robots, etc), this will fail. Instead, delete the pref.
     if (!success) {
-      all_overrides->Remove(key, nullptr);
+      all_overrides->RemoveKey(key);
       continue;
     }
     callback.Run(list);
diff --git a/chrome/browser/extensions/external_provider_impl.cc b/chrome/browser/extensions/external_provider_impl.cc
index eeaf54df..bae99ef9 100644
--- a/chrome/browser/extensions/external_provider_impl.cc
+++ b/chrome/browser/extensions/external_provider_impl.cc
@@ -497,7 +497,7 @@
        it != unsupported_extensions.end(); ++it) {
     // Remove extension for the list of know external extensions. The extension
     // will be uninstalled later because provider doesn't provide it anymore.
-    prefs_->Remove(*it, nullptr);
+    prefs_->RemoveKey(*it);
   }
 }
 
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index 6bb554ed..fce838e9 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -26,6 +26,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/chrome_manifest_url_handlers.h"
 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
+#include "chrome/common/webui_url_constants.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/common/url_constants.h"
@@ -170,6 +171,60 @@
   }
 }
 
+// Returns the current access level for the given `extension`.
+HostPermissionsAccess GetHostPermissionAccessLevelForExtension(
+    const Extension& extension) {
+  if (!util::CanWithholdPermissionsFromExtension(extension))
+    return HostPermissionsAccess::kCannotAffect;
+
+  bool has_active_hosts = !extension.permissions_data()
+                               ->active_permissions()
+                               .effective_hosts()
+                               .is_empty();
+  size_t active_hosts_size = extension.permissions_data()
+                                 ->active_permissions()
+                                 .effective_hosts()
+                                 .size();
+  bool has_withheld_hosts = !extension.permissions_data()
+                                 ->withheld_permissions()
+                                 .effective_hosts()
+                                 .is_empty();
+
+  if (!has_active_hosts && !has_withheld_hosts) {
+    // No hosts are granted or withheld, so none were requested.
+    // Check if the extension is using activeTab.
+    return extension.permissions_data()->HasAPIPermission(
+               mojom::APIPermissionID::kActiveTab)
+               ? HostPermissionsAccess::kOnActiveTabOnly
+               : HostPermissionsAccess::kNotRequested;
+  }
+
+  if (!has_withheld_hosts) {
+    // No hosts were withheld; the extension is running all requested sites.
+    return HostPermissionsAccess::kOnAllRequestedSites;
+  }
+
+  // The extension is running automatically on some of the requested sites.
+  // <all_urls> (strangely) includes the chrome://favicon/ permission. Thus,
+  // we avoid counting the favicon pattern in the active hosts.
+  if (active_hosts_size > 1) {
+    return HostPermissionsAccess::kOnSpecificSites;
+  }
+  if (active_hosts_size == 1) {
+    const URLPattern& single_pattern = *extension.permissions_data()
+                                            ->active_permissions()
+                                            .effective_hosts()
+                                            .begin();
+    if (single_pattern.scheme() != content::kChromeUIScheme ||
+        single_pattern.host() != chrome::kChromeUIFaviconHost)
+      return HostPermissionsAccess::kOnSpecificSites;
+  }
+
+  // The extension is not running automatically anywhere. All its hosts were
+  // withheld.
+  return HostPermissionsAccess::kOnClick;
+}
+
 }  // namespace
 
 InstalledLoader::InstalledLoader(ExtensionService* extension_service)
@@ -609,6 +664,13 @@
       }
     }
 
+    HostPermissionsAccess access_level =
+        GetHostPermissionAccessLevelForExtension(*extension);
+    // Extensions.HostPermissions.GrantedAccess is emitted for every
+    // extension.
+    base::UmaHistogramEnumeration("Extensions.HostPermissions.GrantedAccess",
+                                  access_level);
+
     if (extension_service_->allowlist()->GetExtensionAllowlistState(
             extension->id()) == ALLOWLIST_NOT_ALLOWLISTED) {
       // Record the number of not allowlisted enabled extensions.
diff --git a/chrome/browser/extensions/installed_loader.h b/chrome/browser/extensions/installed_loader.h
index 6d2714f..fafed10 100644
--- a/chrome/browser/extensions/installed_loader.h
+++ b/chrome/browser/extensions/installed_loader.h
@@ -16,6 +16,20 @@
 class ExtensionService;
 struct ExtensionInfo;
 
+// Used in histogram Extensions.HostPermissions.GrantedAccess .
+// Entries should not be renumbered and numeric values should never be reused.
+// If you are adding to this enum, update HostPermissionAccess enum in
+// tools/metrics/histograms/enums.xml.
+enum class HostPermissionsAccess {
+  kCannotAffect = 0,
+  kNotRequested = 1,
+  kOnClick = 2,
+  kOnSpecificSites = 3,
+  kOnAllRequestedSites = 4,
+  kOnActiveTabOnly = 5,
+  kMaxValue = kOnActiveTabOnly,
+};
+
 // Loads installed extensions from the prefs.
 class InstalledLoader {
  public:
diff --git a/chrome/browser/extensions/installed_loader_unittest.cc b/chrome/browser/extensions/installed_loader_unittest.cc
index 3ec9b3b..056e7937 100644
--- a/chrome/browser/extensions/installed_loader_unittest.cc
+++ b/chrome/browser/extensions/installed_loader_unittest.cc
@@ -22,6 +22,14 @@
     "Extensions.RuntimeHostPermissions.ExtensionHasWithheldHosts";
 constexpr const char kGrantedHostCountHistogram[] =
     "Extensions.RuntimeHostPermissions.GrantedHostCount";
+constexpr const char kGrantedAccessHistogram[] =
+    "Extensions.HostPermissions.GrantedAccess";
+// Use an internal location for extensions since metrics aren't recorded for
+// unpacked extensions.
+constexpr mojom::ManifestLocation kManifestInternal =
+    mojom::ManifestLocation::kInternal;
+constexpr mojom::ManifestLocation kManifestExternalPolicy =
+    mojom::ManifestLocation::kExternalPolicy;
 
 }  // namespace
 
@@ -35,20 +43,19 @@
     InitializeEmptyExtensionService();
   }
 
-  const Extension* AddExtension();
+  const Extension* AddExtension(const std::vector<std::string>& permissions,
+                                mojom::ManifestLocation location);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(InstalledLoaderUnitTest);
 };
 
-const Extension* InstalledLoaderUnitTest::AddExtension() {
-  // Metrics aren't recorded for unpacked extensions, so we need to make sure
-  // the extension has an INTERNAL location.
-  constexpr mojom::ManifestLocation kManifestLocation =
-      mojom::ManifestLocation::kInternal;
+const Extension* InstalledLoaderUnitTest::AddExtension(
+    const std::vector<std::string>& permissions,
+    mojom::ManifestLocation location) {
   scoped_refptr<const Extension> extension = ExtensionBuilder("test")
-                                                 .AddPermissions({"<all_urls>"})
-                                                 .SetLocation(kManifestLocation)
+                                                 .AddPermissions(permissions)
+                                                 .SetLocation(location)
                                                  .Build();
   PermissionsUpdater updater(profile());
   updater.InitializePermissions(extension.get());
@@ -60,7 +67,7 @@
 
 TEST_F(InstalledLoaderUnitTest,
        RuntimeHostPermissions_Metrics_HasWithheldHosts_False) {
-  AddExtension();
+  AddExtension({"<all_urls>"}, kManifestInternal);
 
   base::HistogramTester histograms;
   InstalledLoader loader(service());
@@ -76,7 +83,7 @@
 
 TEST_F(InstalledLoaderUnitTest,
        RuntimeHostPermissions_Metrics_HasWithheldHosts_True) {
-  const Extension* extension = AddExtension();
+  const Extension* extension = AddExtension({"<all_urls>"}, kManifestInternal);
   ScriptingPermissionsModifier(profile(), extension)
       .SetWithholdHostPermissions(true);
 
@@ -96,7 +103,7 @@
 
 TEST_F(InstalledLoaderUnitTest,
        RuntimeHostPermissions_Metrics_GrantedHostCount) {
-  const Extension* extension = AddExtension();
+  const Extension* extension = AddExtension({"<all_urls>"}, kManifestInternal);
   ScriptingPermissionsModifier modifier(profile(), extension);
   modifier.SetWithholdHostPermissions(true);
   modifier.GrantHostPermission(GURL("https://example.com/"));
@@ -114,4 +121,112 @@
                                 kEmitCount);
 }
 
+TEST_F(InstalledLoaderUnitTest,
+       HostPermissions_Metrics_GrantedAccess_CannotAffect) {
+  // The extension is loaded from an external policy, so the user cannot
+  // configure the host permissions that affect the extension.
+  AddExtension({}, kManifestExternalPolicy);
+
+  base::HistogramTester histograms;
+  InstalledLoader loader(service());
+  loader.RecordExtensionsMetricsForTesting();
+
+  histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                HostPermissionsAccess::kCannotAffect, 1);
+}
+
+TEST_F(InstalledLoaderUnitTest,
+       HostPermissions_Metrics_GrantedAccess_NotRequested) {
+  // The extension has no host permissions, so host permissions cannot be
+  // requested.
+  AddExtension({}, kManifestInternal);
+
+  base::HistogramTester histograms;
+  InstalledLoader loader(service());
+  loader.RecordExtensionsMetricsForTesting();
+
+  histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                HostPermissionsAccess::kNotRequested, 1);
+}
+
+TEST_F(InstalledLoaderUnitTest, HostPermissions_Metrics_GrantedAccess_OnClick) {
+  const Extension* extension = AddExtension({"<all_urls>"}, kManifestInternal);
+
+  // The user withhelds all host permissions.
+  ScriptingPermissionsModifier modifier(profile(), extension);
+  modifier.SetWithholdHostPermissions(true);
+
+  base::HistogramTester histograms;
+  InstalledLoader loader(service());
+  loader.RecordExtensionsMetricsForTesting();
+
+  histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                HostPermissionsAccess::kOnClick, 1);
+}
+
+TEST_F(InstalledLoaderUnitTest,
+       HostPermissions_Metrics_GrantedAccess_OnSpecificSites) {
+  const Extension* extension = AddExtension({"<all_urls>"}, kManifestInternal);
+
+  // The user grants host permisions to one of all the urls requested.
+  ScriptingPermissionsModifier modifier(profile(), extension);
+  modifier.SetWithholdHostPermissions(true);
+  modifier.GrantHostPermission(GURL("https://example.com/"));
+
+  base::HistogramTester histograms;
+  InstalledLoader loader(service());
+  loader.RecordExtensionsMetricsForTesting();
+
+  histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                HostPermissionsAccess::kOnSpecificSites, 1);
+}
+
+TEST_F(InstalledLoaderUnitTest,
+       HostPermissions_Metrics_GrantedAccess_OnAllRequestedSites) {
+  {
+    AddExtension({"<all_urls>"}, kManifestInternal);
+
+    // The user doesn't withheld any host permissions.
+    base::HistogramTester histograms;
+    InstalledLoader loader(service());
+    loader.RecordExtensionsMetricsForTesting();
+
+    histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                  HostPermissionsAccess::kOnAllRequestedSites,
+                                  1);
+  }
+
+  {
+    const Extension* extension =
+        AddExtension({"https://example.com/"}, kManifestInternal);
+
+    // The user grants host permisions to all requested urls.
+    ScriptingPermissionsModifier modifier(profile(), extension);
+    modifier.SetWithholdHostPermissions(true);
+    modifier.GrantHostPermission(GURL("https://example.com/"));
+
+    base::HistogramTester histograms;
+    InstalledLoader loader(service());
+    loader.RecordExtensionsMetricsForTesting();
+
+    histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                  HostPermissionsAccess::kOnAllRequestedSites,
+                                  1);
+  }
+}
+
+TEST_F(InstalledLoaderUnitTest,
+       HostPermissions_Metrics_GrantedAccess_OnActiveTabOnly) {
+  // The extension has activeTab API permission and no host permissions, so host
+  // permission access is on active tab only.
+  AddExtension({"activeTab"}, kManifestInternal);
+
+  base::HistogramTester histograms;
+  InstalledLoader loader(service());
+  loader.RecordExtensionsMetricsForTesting();
+
+  histograms.ExpectUniqueSample(kGrantedAccessHistogram,
+                                HostPermissionsAccess::kOnActiveTabOnly, 1);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/extensions/preinstalled_apps.cc b/chrome/browser/extensions/preinstalled_apps.cc
index fcffa0c..81894cb 100644
--- a/chrome/browser/extensions/preinstalled_apps.cc
+++ b/chrome/browser/extensions/preinstalled_apps.cc
@@ -172,7 +172,7 @@
         keys_to_erase.insert(entry.first);
     }
     for (const auto& key : keys_to_erase)
-      prefs->Remove(key, nullptr);
+      prefs->RemoveKey(key);
   }
 
   // Next, the more fun case. It's possible that these apps were uninstalled
@@ -216,7 +216,7 @@
     }
 
     for (const auto& key : keys_to_erase) {
-      prefs->Remove(key, nullptr);
+      prefs->RemoveKey(key);
     }
   }
 
diff --git a/chrome/browser/extensions/printer_provider_apitest.cc b/chrome/browser/extensions/printer_provider_apitest.cc
index a1e34703..72dd3f7 100644
--- a/chrome/browser/extensions/printer_provider_apitest.cc
+++ b/chrome/browser/extensions/printer_provider_apitest.cc
@@ -719,7 +719,7 @@
 
   run_loop.Run();
 
-  EXPECT_TRUE(printers.empty());
+  EXPECT_TRUE(printers.GetList().empty());
 }
 
 // These tests are separate out from the main test class because the USB api
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index f8a2983e..742de38 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -831,8 +831,9 @@
   EXPECT_TRUE(WillRegisterServiceWorker());
 }
 
+// Flaky on all platforms (https://crbug.com/1169238).
 IN_PROC_BROWSER_TEST_F(ServiceWorkerRegistrationAtStartupTest,
-                       ExtensionActivationDoesNotReregister) {
+                       DISABLED_ExtensionActivationDoesNotReregister) {
   // Since the extension has onStartup listener, the Service Worker will run on
   // browser start and we'll see "WORKER_RUNNING" message from the worker.
   EXPECT_TRUE(WaitForMessage());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 5e1dcd11..05a4e33 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -208,6 +208,11 @@
     "expiry_milestone": 97
   },
   {
+    "name": "arc-keyboard-shortcut-helper-integration",
+    "owners": [ "tetsui" ],
+    "expiry_milestone": 97
+  },
+  {
     "name": "arc-native-bridge-64bit-support-experiment",
     "owners": [ "jhorwich" ],
     // Used on ChromeOS to experimentally enable 64-bit ARC native-bridge
@@ -3824,6 +3829,11 @@
     "expiry_milestone": 84
   },
   {
+    "name": "mute-notification-snooze-action",
+    "owners": [ "knollr@chromium.org", "peter@chromium.org" ],
+    "expiry_milestone": 96
+  },
+  {
     "name": "muting-compromised-credentials",
     "owners": [ "vsemeniuk", "vasilii" ],
     "expiry_milestone": 95
@@ -4347,6 +4357,11 @@
     "expiry_milestone": 93
   },
   {
+    "name": "permission-quiet-chip",
+    "owners": [ "elklm", "engedy"],
+    "expiry_milestone": 100
+  },
+  {
     "name": "photo-picker-video-support",
     "owners": [ "finnur" ],
     "expiry_milestone": 92
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 35157b1..bfd6b4d 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2070,6 +2070,13 @@
     "chrome://flags/#quiet-notification-prompts and `Safe Browsing Enhanced "
     "Protection` to be enabled.";
 
+const char kPermissionQuietChipName[] = "Quiet Permission Chip Experiment";
+const char kPermissionQuietChipDescription[] =
+    "Enables an experimental permission prompt that uses the quiet chip "
+    "instead of the right-hand side address bar icon for quiet permission "
+    "prompts. Requires chrome://flags/#quiet-notification-prompts to be "
+    "enabled.";
+
 const char kPlaybackSpeedButtonName[] = "Playback Speed Button";
 const char kPlaybackSpeedButtonDescription[] =
     "Enable the playback speed button on the media controls.";
@@ -2179,7 +2186,7 @@
 const char kRecordWebAppDebugInfoName[] = "Record web app debug info";
 const char kRecordWebAppDebugInfoDescription[] =
     "Enables recording additional web app related debugging data to be "
-    "displayed in: chrome://internals/web-app";
+    "displayed in: chrome://web-app-internals";
 
 const char kReduceUserAgentName[] = "Reduce User-Agent request header";
 const char kReduceUserAgentDescription[] =
@@ -3650,6 +3657,11 @@
     "Allows global media controls to control when a Cast session is started "
     "or stopped instead of relying on the Cast dialog.";
 
+const char kMuteNotificationSnoozeActionName[] =
+    "Snooze action for mute notifications";
+const char kMuteNotificationSnoozeActionDescription[] =
+    "Adds a Snooze action to mute notifications shown while sharing a screen.";
+
 const char kNtpCacheOneGoogleBarName[] = "Cache OneGoogleBar";
 const char kNtpCacheOneGoogleBarDescription[] =
     "Enables using the OneGoogleBar cached response in chrome://new-tab-page, "
@@ -4001,6 +4013,11 @@
     "Allows pasting of images to Android apps through commitContent API and "
     "share intent.";
 
+const char kArcKeyboardShortcutHelperIntegrationName[] =
+    "Enable keyboard shortcut helper integration for ARC";
+const char kArcKeyboardShortcutHelperIntegrationDescription[] =
+    "Shows keyboard shortcuts from Android apps in Chrome OS Shortcut Viewer";
+
 const char kArcNativeBridgeToggleName[] =
     "Toggle between native bridge implementations for ARC";
 const char kArcNativeBridgeToggleDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index bc06622..b1f093b 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1183,6 +1183,9 @@
 extern const char kPermissionPredictionsName[];
 extern const char kPermissionPredictionsDescription[];
 
+extern const char kPermissionQuietChipName[];
+extern const char kPermissionQuietChipDescription[];
+
 extern const char kPlaybackSpeedButtonName[];
 extern const char kPlaybackSpeedButtonDescription[];
 
@@ -2079,6 +2082,9 @@
 extern const char kGlobalMediaControlsCastStartStopName[];
 extern const char kGlobalMediaControlsCastStartStopDescription[];
 
+extern const char kMuteNotificationSnoozeActionName[];
+extern const char kMuteNotificationSnoozeActionDescription[];
+
 extern const char kNtpCacheOneGoogleBarName[];
 extern const char kNtpCacheOneGoogleBarDescription[];
 
@@ -2295,6 +2301,9 @@
 extern const char kArcImageCopyPasteCompatName[];
 extern const char kArcImageCopyPasteCompatDescription[];
 
+extern const char kArcKeyboardShortcutHelperIntegrationName[];
+extern const char kArcKeyboardShortcutHelperIntegrationDescription[];
+
 extern const char kArcNativeBridgeToggleName[];
 extern const char kArcNativeBridgeToggleDescription[];
 
diff --git a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
index 99b6dbd..ed39fd34 100644
--- a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
+++ b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
@@ -9,8 +9,8 @@
 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/macros.h"
-#include "base/stl_util.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/buildflags.h"
diff --git a/chrome/browser/installable/BUILD.gn b/chrome/browser/installable/BUILD.gn
new file mode 100644
index 0000000..3f033f4
--- /dev/null
+++ b/chrome/browser/installable/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/android/rules.gni")
+
+java_cpp_enum("browser_services_enums_srcjar") {
+  sources = [
+    "installed_webapp_geolocation_bridge.cc",
+    "quality_enforcer.cc",
+  ]
+}
diff --git a/chrome/browser/installable/installed_webapp_geolocation_bridge.cc b/chrome/browser/installable/installed_webapp_geolocation_bridge.cc
index 7f420e9..3098a588 100644
--- a/chrome/browser/installable/installed_webapp_geolocation_bridge.cc
+++ b/chrome/browser/installable/installed_webapp_geolocation_bridge.cc
@@ -22,7 +22,8 @@
 // Do not modify or reuse existing entries; they are used in a UMA histogram.
 // Please edit TrustedWebActivityLocationErrorCode in the enums.xml if a value
 // is added.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.browserservices
+// GENERATED_JAVA_ENUM_PACKAGE: (
+// org.chromium.chrome.browser.browserservices.constants)
 enum class LocationUpdateError {
   // There was no error.
   kNone = 0,
diff --git a/chrome/browser/installable/quality_enforcer.cc b/chrome/browser/installable/quality_enforcer.cc
index c2e8908..04c9831 100644
--- a/chrome/browser/installable/quality_enforcer.cc
+++ b/chrome/browser/installable/quality_enforcer.cc
@@ -22,7 +22,8 @@
 // Do not modify or reuse existing entries; they are used in a UMA histogram.
 // Please also edit TrustedWebActivityQualityEnforcementViolationType in the
 // enums.xml if adding new value.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.browserservices
+// GENERATED_JAVA_ENUM_PACKAGE: (
+// org.chromium.chrome.browser.browserservices.constants)
 enum class QualityEnforcementViolationType {
   kHttpError404 = 0,
   kHttpError5xx = 1,
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index 0bc46daf..b724126 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -13,6 +13,8 @@
 #include "base/no_destructor.h"
 #include "base/process/process.h"
 #include "base/process/process_handle.h"
+#include "base/threading/hang_watcher.h"
+#include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "base/types/strong_alias.h"
 #include "build/build_config.h"
@@ -36,6 +38,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/notification_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !defined(OS_ANDROID)
 #include "chrome/browser/lifetime/termination_notification.h"
@@ -110,7 +113,7 @@
   std::string login_screen_locale;
   if (cros_settings->GetList(chromeos::kDeviceLoginScreenLocales,
                              &login_screen_locales) &&
-      !login_screen_locales->empty() &&
+      !login_screen_locales->GetList().empty() &&
       login_screen_locales->GetString(0, &login_screen_locale)) {
     local_state->SetString(language::prefs::kApplicationLocale,
                            login_screen_locale);
@@ -377,11 +380,24 @@
   // to kill us soon. Either way we don't care about that here.
   base::ThreadRestrictions::ScopedAllowIO allow_io;
 
-  // Start watching for hang during shutdown, and crash it if takes too long.
-  // We disarm when |shutdown_watcher| object is destroyed, which is when we
-  // exit this function.
-  ShutdownWatcherHelper shutdown_watcher;
-  shutdown_watcher.Arm(base::TimeDelta::FromSeconds(90));
+  // Two different types of hang detection cannot attempt to upload crashes at
+  // the same time or they would interfere with each other.
+  absl::optional<ShutdownWatcherHelper> shutdown_watcher;
+  absl::optional<base::WatchHangsInScope> watch_hangs_scope;
+  constexpr base::TimeDelta kShutdownHangDelay{
+      base::TimeDelta::FromSeconds(90)};
+  if (base::HangWatcher::IsCrashReportingEnabled()) {
+    // Use ShutdownWatcherHelper logic to choose delay to get identical
+    // behavior.
+    watch_hangs_scope.emplace(
+        ShutdownWatcherHelper::GetPerChannelTimeout(kShutdownHangDelay));
+  } else {
+    // Start watching for hang during shutdown, and crash it if takes too long.
+    // We disarm when |shutdown_watcher| object is destroyed, which is when we
+    // exit this function.
+    shutdown_watcher.emplace();
+    shutdown_watcher->Arm(kShutdownHangDelay);
+  }
 
   browser_shutdown::OnShutdownStarting(
       browser_shutdown::ShutdownType::kEndSession);
diff --git a/chrome/browser/mac/exception_processor.mm b/chrome/browser/mac/exception_processor.mm
index da7bfae..8474792 100644
--- a/chrome/browser/mac/exception_processor.mm
+++ b/chrome/browser/mac/exception_processor.mm
@@ -12,11 +12,11 @@
 #include <type_traits>
 
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/debug/crash_logging.h"
 #include "base/debug/stack_trace.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/crash/core/common/crash_key.h"
 
diff --git a/chrome/browser/mac/install_from_dmg.mm b/chrome/browser/mac/install_from_dmg.mm
index 21965bf..5c10a4d 100644
--- a/chrome/browser/mac/install_from_dmg.mm
+++ b/chrome/browser/mac/install_from_dmg.mm
@@ -19,6 +19,7 @@
 
 #include "base/auto_reset.h"
 #include "base/command_line.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/mac/authorization_util.h"
@@ -31,7 +32,6 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_ioobject.h"
 #include "base/macros.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
diff --git a/chrome/browser/media/history/media_history_browsertest.cc b/chrome/browser/media/history/media_history_browsertest.cc
index a1635d0..70626ae 100644
--- a/chrome/browser/media/history/media_history_browsertest.cc
+++ b/chrome/browser/media/history/media_history_browsertest.cc
@@ -1081,8 +1081,15 @@
   EXPECT_TRUE(sessions.empty());
 }
 
+// TODO(crbug.com/1086828): Test is flaky on Linux and Windows.
+#if defined(OS_LINUX) || defined(OS_WIN)
+#define MAYBE_DoNotRecordWatchtime_Background \
+  DISABLED_DoNotRecordWatchtime_Background
+#else
+#define MAYBE_DoNotRecordWatchtime_Background DoNotRecordWatchtime_Background
+#endif
 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
-                       DoNotRecordWatchtime_Background) {
+                       MAYBE_DoNotRecordWatchtime_Background) {
   auto* browser = CreateBrowserFromParam();
   auto* service = GetMediaHistoryService(browser);
 
diff --git a/chrome/browser/media/history/media_history_table_base.cc b/chrome/browser/media/history/media_history_table_base.cc
index 52148c1e..febe0f2 100644
--- a/chrome/browser/media/history/media_history_table_base.cc
+++ b/chrome/browser/media/history/media_history_table_base.cc
@@ -56,7 +56,7 @@
     const google::protobuf::MessageLite& protobuf) {
   std::string out;
   CHECK(protobuf.SerializeToString(&out));
-  s.BindBlob(col, out.data(), out.size());
+  s.BindBlob(col, out);
 }
 
 bool MediaHistoryTableBase::GetProto(sql::Statement& s,
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
index 84583692..5d72a39ed 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -30,9 +30,10 @@
 constexpr char kLoggerComponent[] = "CastMediaRouteProvider";
 
 // List of origins allowed to use a PresentationRequest to initiate mirroring.
-constexpr std::array<base::StringPiece, 2> kPresentationApiAllowlist = {
+constexpr std::array<base::StringPiece, 3> kPresentationApiAllowlist = {
     "https://docs.google.com",
     "https://meet.google.com",
+    "https://music.youtube.com",
 };
 
 // Returns a list of origins that are valid for |source_id|. An empty list
diff --git a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
index c051088..e3335cff 100644
--- a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
@@ -84,7 +84,7 @@
 
     base::ListValue* values;
     ASSERT_TRUE(parsed_json.value->GetAsList(&values));
-    ASSERT_FALSE(values->empty());
+    ASSERT_FALSE(values->GetList().empty());
     bool found_audio_input = false;
     bool found_video_input = false;
 
diff --git a/chrome/browser/media/webrtc/window_icon_util_mac.mm b/chrome/browser/media/webrtc/window_icon_util_mac.mm
index 0f4b1226..3188ad8 100644
--- a/chrome/browser/media/webrtc/window_icon_util_mac.mm
+++ b/chrome/browser/media/webrtc/window_icon_util_mac.mm
@@ -6,9 +6,9 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "third_party/libyuv/include/libyuv/convert_argb.h"
 
 gfx::ImageSkia GetWindowIcon(content::DesktopMediaID id) {
diff --git a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc
index fc189370..2a37ca72 100644
--- a/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc
+++ b/chrome/browser/metrics/family_user_metrics_provider_browsertest.cc
@@ -225,8 +225,9 @@
         IdentityManagerFactory::GetForProfile(browser()->profile()));
   }
 
-  chromeos::DeviceStateMixin device_state_{
-      &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
+  ash::DeviceStateMixin device_state_{
+      &mixin_host_,
+      ash::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
 
   chromeos::LoggedInUserMixin logged_in_user_mixin_{
       &mixin_host_, chromeos::LoggedInUserMixin::LogInType::kRegular,
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc
index 05107ebf8..b6eda999 100644
--- a/chrome/browser/metrics/thread_watcher.cc
+++ b/chrome/browser/metrics/thread_watcher.cc
@@ -22,6 +22,7 @@
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/metrics/thread_watcher_report_hang.h"
@@ -904,6 +905,14 @@
 void ShutdownWatcherHelper::Arm(const base::TimeDelta& duration) {
   DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId());
   DCHECK(!shutdown_watchdog_);
+  shutdown_watchdog_ =
+      new ShutdownWatchDogThread(GetPerChannelTimeout(duration));
+  shutdown_watchdog_->Arm();
+}
+
+// static
+base::TimeDelta ShutdownWatcherHelper::GetPerChannelTimeout(
+    base::TimeDelta duration) {
   base::TimeDelta actual_duration = duration;
 
   version_info::Channel channel = chrome::GetChannel();
@@ -917,8 +926,7 @@
     actual_duration *= 2;
   }
 
-  shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration);
-  shutdown_watchdog_->Arm();
+  return actual_duration;
 }
 
 #endif  // !defined(OS_ANDROID)
diff --git a/chrome/browser/metrics/thread_watcher.h b/chrome/browser/metrics/thread_watcher.h
index 7819e399..93939935 100644
--- a/chrome/browser/metrics/thread_watcher.h
+++ b/chrome/browser/metrics/thread_watcher.h
@@ -511,6 +511,10 @@
   // |duration| specifies how long it will wait before it calls alarm.
   void Arm(const base::TimeDelta& duration);
 
+  // Get the timeout after which a shutdown hang is detected, for the current
+  // channel.
+  static base::TimeDelta GetPerChannelTimeout(base::TimeDelta duration);
+
  private:
   // shutdown_watchdog_ watches for hangs during shutdown.
   base::Watchdog* shutdown_watchdog_;
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.cc b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
index b0d5333..c3ec3208 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
@@ -10,6 +10,7 @@
 #include "base/files/file_util.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/task_traits.h"
@@ -19,6 +20,7 @@
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/image_decoder/image_decoder.h"
+#include "chrome/browser/nearby_sharing/common/nearby_share_features.h"
 #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
 #include "chrome/browser/nearby_sharing/logging/logging.h"
 #include "chrome/browser/nearby_sharing/nearby_sharing_service.h"
@@ -27,6 +29,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h"
+#include "chrome/browser/ui/settings_window_manager_chromeos.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_thread.h"
@@ -972,8 +975,16 @@
 
 void NearbyNotificationManager::OnOnboardingClicked() {
   CloseOnboarding();
-  // TODO(crbug.com/1102348): Start user onboarding or high visibility if user
-  // has been onboarded already.
+
+  if (base::FeatureList::IsEnabled(
+          features::kNearbySharingBackgroundScanning)) {
+    std::string timestamp_string = base::NumberToString(
+        base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
+    std::string sub_page =
+        "multidevice/nearbyshare?receive&timeout=300&time=" + timestamp_string;
+    chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(profile_,
+                                                                 sub_page);
+  }
 }
 
 void NearbyNotificationManager::OnOnboardingDismissed() {
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
index d1388d60..868a178 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -55,6 +55,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "crypto/random.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "url/gurl.h"
 
@@ -348,6 +349,10 @@
   observers_.Clear();
 
   StopAdvertising();
+  if (base::FeatureList::IsEnabled(
+          features::kNearbySharingBackgroundScanning)) {
+    StopBackgroundScanning();
+  }
   StopFastInitiationAdvertising();
   StopScanning();
   nearby_connections_manager_->Shutdown();
@@ -1272,6 +1277,46 @@
   InvalidateSurfaceState();
 }
 
+void NearbySharingServiceImpl::OnSessionStarted(
+    device::BluetoothLowEnergyScanSession* scan_session,
+    absl::optional<device::BluetoothLowEnergyScanSession::ErrorCode>
+        error_code) {
+  if (error_code) {
+    NS_LOG(WARNING) << __func__ << ": Error";
+    StopBackgroundScanning();
+    return;
+  }
+
+  NS_LOG(VERBOSE) << __func__ << ": Success";
+}
+
+void NearbySharingServiceImpl::OnDeviceFound(
+    device::BluetoothLowEnergyScanSession* scan_session,
+    device::BluetoothDevice* device) {
+  NS_LOG(VERBOSE) << __func__;
+
+  // This shows a notification indicating that a device nearby is attempting to
+  // share. When the notification is clicked it will take the user through the
+  // onboarding flow if needed and then enable high visibility mode.
+  nearby_notification_manager_->ShowOnboarding();
+}
+
+void NearbySharingServiceImpl::OnDeviceLost(
+    device::BluetoothLowEnergyScanSession* scan_session,
+    device::BluetoothDevice* device) {
+  NS_LOG(VERBOSE) << __func__;
+
+  // This will just dismiss the "onboarding" notification, it does not have any
+  // effect on the actual onboarding or high visibility UI.
+  nearby_notification_manager_->CloseOnboarding();
+}
+
+void NearbySharingServiceImpl::OnSessionInvalidated(
+    device::BluetoothLowEnergyScanSession* scan_session) {
+  NS_LOG(INFO) << __func__;
+  StopBackgroundScanning();
+}
+
 base::ObserverList<TransferUpdateCallback>&
 NearbySharingServiceImpl::GetReceiveCallbacksFromState(
     ReceiveSurfaceState state) {
@@ -2053,11 +2098,6 @@
 }
 
 void NearbySharingServiceImpl::InvalidateBackgroundScanning() {
-  // TODO(hansenmichael): This method is in a prototype state and essentially
-  // duplicates the checks from InvalidateAdvertisingState(). This should be
-  // vetted further and updated specifically for background scanning. This is
-  // not invoked unless the background scanning feature flag is enabled.
-
   // Nothing to do if we're shutting down the profile.
   if (!profile_)
     return;
@@ -2087,8 +2127,9 @@
     return;
   }
 
-  // Nearby Sharing is disabled. Don't scan.
-  if (!settings_.GetEnabled()) {
+  // User has explicitly disabled Nearby Sharing after onboarding. Don't
+  // background scan.
+  if (settings_.IsOnboardingComplete() && !settings_.GetEnabled()) {
     NS_LOG(VERBOSE)
         << __func__
         << ": Stopping background scanning because Nearby Sharing is disabled.";
@@ -2114,28 +2155,17 @@
     return;
   }
 
-  if (foreground_receive_callbacks_.empty() &&
-      background_receive_callbacks_.empty()) {
+  if (advertising_power_level_ == PowerLevel::kHighPower) {
     NS_LOG(VERBOSE) << __func__
-                    << ": Stopping background scanning because no receive "
-                       "surface is registered.";
-    StopBackgroundScanning();
-    return;
-  }
-
-  if (!IsVisibleInBackground(settings_.GetVisibility()) &&
-      foreground_receive_callbacks_.empty()) {
-    NS_LOG(VERBOSE) << __func__
-                    << ": Stopping background scanning because no high power "
-                       "receive surface "
-                       "is registered and device is visible to NO_ONE.";
+                    << ": Stopping background scanning because we're already "
+                       "in high visibility mode.";
     StopBackgroundScanning();
     return;
   }
 
   process_shutdown_pending_timer_.Stop();
 
-  if (is_background_scanning_) {
+  if (background_scan_session_) {
     NS_LOG(VERBOSE) << __func__ << ": Ignoring, already background scanning.";
     return;
   }
@@ -2144,17 +2174,27 @@
 }
 
 void NearbySharingServiceImpl::StartBackgroundScanning() {
-  // TODO(hansenmichael): This method is in a prototype state and unimplemented.
-  // This is not invoked unless the background scanning feature flag is enabled.
-  NS_LOG(INFO) << __func__ << ": Starting background scanning.";
-  is_background_scanning_ = true;
+  DCHECK(!background_scan_session_);
+  NS_LOG(VERBOSE) << __func__ << ": Starting background scanning.";
+  auto filter = std::make_unique<device::BluetoothLowEnergyScanFilter>(
+      /*device_found_threshold=*/-80, /*device_found_timeout=*/1,
+      /*device_lost_threshold=*/-100, /*device_lost_timeout=*/5);
+  filter->AddPattern(
+      /*start_position=*/0,
+      device::BluetoothLowEnergyScanFilter::AdvertisementDataType::kServiceData,
+      /*value=*/std::vector<uint8_t>{0x2c, 0xfe, 0xfc, 0x12, 0x8e});
+  background_scan_session_ = bluetooth_adapter_->StartLowEnergyScanSession(
+      std::move(filter), /*delegate=*/weak_ptr_factory_.GetWeakPtr());
 }
 
 void NearbySharingServiceImpl::StopBackgroundScanning() {
-  // TODO(hansenmichael): This method is in a prototype state and unimplemented.
-  // This is not invoked unless the background scanning feature flag is enabled.
-  NS_LOG(INFO) << __func__ << ": Stopping background scanning.";
-  is_background_scanning_ = false;
+  if (!background_scan_session_) {
+    NS_LOG(VERBOSE) << __func__ << ": Ignoring, not background scanning.";
+    return;
+  }
+
+  background_scan_session_.reset();
+  NS_LOG(VERBOSE) << __func__ << ": Stopped background scanning.";
 }
 
 void NearbySharingServiceImpl::ScheduleRotateBackgroundAdvertisementTimer() {
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
index ca026e18..0f3d021 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -45,6 +45,7 @@
 #include "chromeos/services/nearby/public/mojom/nearby_decoder_types.mojom.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "device/bluetooth/bluetooth_adapter.h"
+#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
 #include "net/base/network_change_notifier.h"
 
 class FastInitiationManager;
@@ -71,7 +72,8 @@
       public NearbyConnectionsManager::DiscoveryListener,
       public ash::SessionObserver,
       public PowerClient::Observer,
-      public net::NetworkChangeNotifier::NetworkChangeObserver {
+      public net::NetworkChangeNotifier::NetworkChangeObserver,
+      public device::BluetoothLowEnergyScanSession::Delegate {
  public:
   // The number of unexpected nearby process shutdowns that we allow during a
   // fixed window before deciding not to restart the process.
@@ -178,6 +180,18 @@
   void SuspendImminent() override;
   void SuspendDone() override;
 
+  // device::BluetoothLowEnergyScanSession::Delegate
+  void OnSessionStarted(
+      device::BluetoothLowEnergyScanSession* scan_session,
+      absl::optional<device::BluetoothLowEnergyScanSession::ErrorCode>
+          error_code) override;
+  void OnDeviceFound(device::BluetoothLowEnergyScanSession* scan_session,
+                     device::BluetoothDevice* device) override;
+  void OnDeviceLost(device::BluetoothLowEnergyScanSession* scan_session,
+                    device::BluetoothDevice* device) override;
+  void OnSessionInvalidated(
+      device::BluetoothLowEnergyScanSession* scan_session) override;
+
   base::ObserverList<TransferUpdateCallback>& GetReceiveCallbacksFromState(
       ReceiveSurfaceState state);
   bool IsVisibleInBackground(Visibility visibility);
@@ -493,9 +507,6 @@
   // The current advertising power level. PowerLevel::kUnknown while not
   // advertising.
   PowerLevel advertising_power_level_ = PowerLevel::kUnknown;
-  // True if we are background scanning for remote devices that are attempting
-  // to share.
-  bool is_background_scanning_ = false;
   // True if we are currently scanning for remote devices.
   bool is_scanning_ = false;
   // True if we're currently sending or receiving a file.
@@ -521,6 +532,10 @@
   // the time between an incoming share being accepted and the first payload
   // byte being processed.
   base::TimeTicks incoming_share_accepted_timestamp_;
+  // Scan session which is non-null when we are performing a background scan for
+  // remote devices that are attempting to share.
+  std::unique_ptr<device::BluetoothLowEnergyScanSession>
+      background_scan_session_ = nullptr;
 
   int recent_nearby_process_unexpected_shutdown_count_ = 0;
   base::OneShotTimer clear_recent_nearby_process_shutdown_count_timer_;
diff --git a/chrome/browser/net/log_net_log_browsertest.cc b/chrome/browser/net/log_net_log_browsertest.cc
index 68da510..62fda145 100644
--- a/chrome/browser/net/log_net_log_browsertest.cc
+++ b/chrome/browser/net/log_net_log_browsertest.cc
@@ -64,7 +64,7 @@
     // Ensure it has an "events" property.
     base::ListValue* events;
     ASSERT_TRUE(main->GetList("events", &events));
-    ASSERT_FALSE(events->empty());
+    ASSERT_FALSE(events->GetList().empty());
 
     // Verify that cookies were stripped when the --net-log-capture-mode flag
     // was omitted, and not stripped when it was given a value of
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc
index 1b5150e..3059f55 100644
--- a/chrome/browser/net/profile_network_context_service_browsertest.cc
+++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -306,7 +306,6 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-// Flaky on Linux and Mac: https://crbug.com/1041810
 // The first time we load, even if we're in an experiment there's no reset
 // from the unknown state.
 IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheChangeBrowsertest,
diff --git a/chrome/browser/net/stub_resolver_config_reader_browsertest.cc b/chrome/browser/net/stub_resolver_config_reader_browsertest.cc
new file mode 100644
index 0000000..aa5d3615
--- /dev/null
+++ b/chrome/browser/net/stub_resolver_config_reader_browsertest.cc
@@ -0,0 +1,197 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/stub_resolver_config_reader.h"
+
+#include <string>
+
+#include "base/feature_list.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/secure_dns_config.h"
+#include "chrome/browser/net/system_network_context_manager.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/test/browser_test.h"
+#include "net/dns/public/secure_dns_mode.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_WIN)
+#include "base/win/win_util.h"
+#endif
+
+namespace {
+
+SecureDnsConfig GetSecureDnsConfiguration(
+    bool force_check_parental_controls_for_automatic_mode) {
+  return SystemNetworkContextManager::GetStubResolverConfigReader()
+      ->GetSecureDnsConfiguration(
+          force_check_parental_controls_for_automatic_mode);
+}
+
+bool GetInsecureStubResolverEnabled() {
+  return SystemNetworkContextManager::GetStubResolverConfigReader()
+      ->GetInsecureStubResolverEnabled();
+}
+
+// A custom matcher to validate a DnsOverHttpsServerConfig instance.
+MATCHER_P2(DnsOverHttpsServerConfigMatcher, server_template, use_post, "") {
+  return testing::ExplainMatchResult(
+      testing::AllOf(
+          testing::Field(&net::DnsOverHttpsServerConfig::server_template,
+                         server_template),
+          testing::Field(&net::DnsOverHttpsServerConfig::use_post, use_post)),
+      arg, result_listener);
+}
+
+class StubResolverConfigReaderBrowsertest
+    : public InProcessBrowserTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  StubResolverConfigReaderBrowsertest() {
+    scoped_feature_list_.InitWithFeatureState(features::kAsyncDns, GetParam());
+  }
+  ~StubResolverConfigReaderBrowsertest() override = default;
+
+  void SetUpOnMainThread() override {}
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// TODO(https://crbug.com/1225151): flaky
+#if defined(OS_WIN)
+#define MAYBE_StubResolverConfig DISABLED_StubResolverConfig
+#else
+#define MAYBE_StubResolverConfig StubResolverConfig
+#endif
+
+// Checks that the values returned by GetStubResolverConfigForTesting() match
+// `features::kAsyncDns` (With empty DNS over HTTPS prefs). Then sets various
+// DoH modes and DoH template strings and makes sure the settings are respected.
+IN_PROC_BROWSER_TEST_P(StubResolverConfigReaderBrowsertest,
+                       MAYBE_StubResolverConfig) {
+  bool async_dns_feature_enabled = GetParam();
+
+  // Mark as not enterprise managed.
+#if defined(OS_WIN)
+  base::win::ScopedDomainStateForTesting scoped_domain(false);
+#endif
+
+  // Check initial state.
+  SecureDnsConfig secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
+    EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
+  } else {
+    EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
+  }
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+
+  std::string good_post_template = "https://foo.test/";
+  std::string good_get_template = "https://bar.test/dns-query{?dns}";
+  std::string bad_template = "dns-query{?dns}";
+  std::string good_then_bad_template = good_get_template + " " + bad_template;
+  std::string bad_then_good_template = bad_template + " " + good_get_template;
+  std::string multiple_good_templates =
+      "  " + good_get_template + "   " + good_post_template + "  ";
+
+  PrefService* local_state = g_browser_process->local_state();
+  local_state->SetString(prefs::kDnsOverHttpsMode,
+                         SecureDnsConfig::kModeSecure);
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(),
+              testing::ElementsAreArray({
+                  DnsOverHttpsServerConfigMatcher(good_post_template, true),
+              }));
+
+  local_state->SetString(prefs::kDnsOverHttpsMode,
+                         SecureDnsConfig::kModeAutomatic);
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_then_bad_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(),
+              testing::ElementsAreArray({
+                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
+              }));
+
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_then_good_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(),
+              testing::ElementsAreArray({
+                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
+              }));
+
+  local_state->SetString(prefs::kDnsOverHttpsTemplates,
+                         multiple_good_templates);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(),
+              testing::ElementsAreArray({
+                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
+                  DnsOverHttpsServerConfigMatcher(good_post_template, true),
+              }));
+
+  local_state->SetString(prefs::kDnsOverHttpsMode, SecureDnsConfig::kModeOff);
+  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_get_template);
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+
+  local_state->SetString(prefs::kDnsOverHttpsMode, "no_match");
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+
+  // Test case with policy BuiltInDnsClientEnabled enabled. The DoH fields
+  // should be unaffected.
+  local_state->Set(prefs::kBuiltInDnsClientEnabled,
+                   base::Value(!async_dns_feature_enabled));
+  secure_dns_config = GetSecureDnsConfiguration(
+      false /* force_check_parental_controls_for_automatic_mode */);
+  EXPECT_EQ(!async_dns_feature_enabled, GetInsecureStubResolverEnabled());
+  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
+  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         StubResolverConfigReaderBrowsertest,
+                         ::testing::Bool());
+
+}  // namespace
diff --git a/chrome/browser/net/system_network_context_manager_browsertest.cc b/chrome/browser/net/system_network_context_manager_browsertest.cc
index 4b9ad74e..49726c02 100644
--- a/chrome/browser/net/system_network_context_manager_browsertest.cc
+++ b/chrome/browser/net/system_network_context_manager_browsertest.cc
@@ -7,13 +7,11 @@
 #include <string>
 #include <vector>
 
-#include "base/feature_list.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/net/secure_dns_config.h"
 #include "chrome/browser/net/stub_resolver_config_reader.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_features.h"
@@ -25,7 +23,6 @@
 #include "content/public/common/user_agent.h"
 #include "content/public/test/browser_test.h"
 #include "net/dns/public/dns_over_https_server_config.h"
-#include "net/dns/public/secure_dns_mode.h"
 #include "net/net_buildflags.h"
 #include "services/cert_verifier/test_cert_verifier_service_factory.h"
 #include "services/network/public/cpp/features.h"
@@ -45,164 +42,8 @@
 #include "net/base/features.h"
 #endif
 
-#if defined(OS_WIN)
-#include "base/win/win_util.h"
-#endif
-
-namespace {
-
-SecureDnsConfig GetSecureDnsConfiguration(
-    bool force_check_parental_controls_for_automatic_mode) {
-  return SystemNetworkContextManager::GetStubResolverConfigReader()
-      ->GetSecureDnsConfiguration(
-          force_check_parental_controls_for_automatic_mode);
-}
-
-bool GetInsecureStubResolverEnabled() {
-  return SystemNetworkContextManager::GetStubResolverConfigReader()
-      ->GetInsecureStubResolverEnabled();
-}
-
-// A custom matcher to validate a DnsOverHttpsServerConfig instance.
-MATCHER_P2(DnsOverHttpsServerConfigMatcher, server_template, use_post, "") {
-  return testing::ExplainMatchResult(
-      testing::AllOf(
-          testing::Field(&net::DnsOverHttpsServerConfig::server_template,
-                         server_template),
-          testing::Field(&net::DnsOverHttpsServerConfig::use_post, use_post)),
-      arg, result_listener);
-}
-
-// Checks that the values returned by GetStubResolverConfigForTesting() match
-// |async_dns_feature_enabled| (With empty DNS over HTTPS prefs). Then sets
-// various DoH modes and DoH template strings and makes sure the settings are
-// respected.
-void RunStubResolverConfigTests(bool async_dns_feature_enabled) {
-  // Mark as not enterprise managed.
-#if defined(OS_WIN)
-  base::win::ScopedDomainStateForTesting scoped_domain(false);
-#endif
-  // Check initial state.
-  SecureDnsConfig secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
-    EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
-  } else {
-    EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
-  }
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-
-  std::string good_post_template = "https://foo.test/";
-  std::string good_get_template = "https://bar.test/dns-query{?dns}";
-  std::string bad_template = "dns-query{?dns}";
-  std::string good_then_bad_template = good_get_template + " " + bad_template;
-  std::string bad_then_good_template = bad_template + " " + good_get_template;
-  std::string multiple_good_templates =
-      "  " + good_get_template + "   " + good_post_template + "  ";
-
-  PrefService* local_state = g_browser_process->local_state();
-  local_state->SetString(prefs::kDnsOverHttpsMode,
-                         SecureDnsConfig::kModeSecure);
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kSecure, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(),
-              testing::ElementsAreArray({
-                  DnsOverHttpsServerConfigMatcher(good_post_template, true),
-              }));
-
-  local_state->SetString(prefs::kDnsOverHttpsMode,
-                         SecureDnsConfig::kModeAutomatic);
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_then_bad_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(),
-              testing::ElementsAreArray({
-                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
-              }));
-
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_then_good_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(),
-              testing::ElementsAreArray({
-                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
-              }));
-
-  local_state->SetString(prefs::kDnsOverHttpsTemplates,
-                         multiple_good_templates);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kAutomatic, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(),
-              testing::ElementsAreArray({
-                  DnsOverHttpsServerConfigMatcher(good_get_template, false),
-                  DnsOverHttpsServerConfigMatcher(good_post_template, true),
-              }));
-
-  local_state->SetString(prefs::kDnsOverHttpsMode, SecureDnsConfig::kModeOff);
-  local_state->SetString(prefs::kDnsOverHttpsTemplates, good_get_template);
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-
-  local_state->SetString(prefs::kDnsOverHttpsMode, "no_match");
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-
-  // Test case with policy BuiltInDnsClientEnabled enabled. The DoH fields
-  // should be unaffected.
-  local_state->Set(prefs::kBuiltInDnsClientEnabled,
-                   base::Value(!async_dns_feature_enabled));
-  secure_dns_config = GetSecureDnsConfiguration(
-      false /* force_check_parental_controls_for_automatic_mode */);
-  EXPECT_EQ(!async_dns_feature_enabled, GetInsecureStubResolverEnabled());
-  EXPECT_EQ(net::SecureDnsMode::kOff, secure_dns_config.mode());
-  EXPECT_THAT(secure_dns_config.servers(), testing::IsEmpty());
-}
-
-}  // namespace
-
 using SystemNetworkContextManagerBrowsertest = InProcessBrowserTest;
 
-// TODO(crbug.com/1226023): Test is flaky.
-#if defined(OS_WIN)
-#define MAYBE_StubResolverDefaultConfig DISABLED_StubResolverDefaultConfig
-#else
-#define MAYBE_StubResolverDefaultConfig StubResolverDefaultConfig
-#endif
-IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest,
-                       MAYBE_StubResolverDefaultConfig) {
-  RunStubResolverConfigTests(base::FeatureList::IsEnabled(features::kAsyncDns));
-}
-
 IN_PROC_BROWSER_TEST_F(SystemNetworkContextManagerBrowsertest,
                        StaticAuthParams) {
   // Test defaults.
@@ -318,36 +159,6 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-class SystemNetworkContextManagerStubResolverBrowsertest
-    : public SystemNetworkContextManagerBrowsertest,
-      public testing::WithParamInterface<bool> {
- public:
-  SystemNetworkContextManagerStubResolverBrowsertest() {
-    scoped_feature_list_.InitWithFeatureState(features::kAsyncDns, GetParam());
-  }
-  ~SystemNetworkContextManagerStubResolverBrowsertest() override {}
-
-  void SetUpOnMainThread() override {}
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// TODO(https://crbug.com/1225151): flaky
-#if defined(OS_WIN)
-#define MAYBE_StubResolverConfig DISABLED_StubResolverConfig
-#else
-#define MAYBE_StubResolverConfig StubResolverConfig
-#endif
-IN_PROC_BROWSER_TEST_P(SystemNetworkContextManagerStubResolverBrowsertest,
-                       MAYBE_StubResolverConfig) {
-  RunStubResolverConfigTests(GetParam());
-}
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         SystemNetworkContextManagerStubResolverBrowsertest,
-                         ::testing::Bool());
-
 class SystemNetworkContextManagerReferrersFeatureBrowsertest
     : public SystemNetworkContextManagerBrowsertest,
       public testing::WithParamInterface<bool> {
diff --git a/chrome/browser/notifications/muted_notification_handler.cc b/chrome/browser/notifications/muted_notification_handler.cc
index fb816bb1..a43ac48 100644
--- a/chrome/browser/notifications/muted_notification_handler.cc
+++ b/chrome/browser/notifications/muted_notification_handler.cc
@@ -7,15 +7,14 @@
 #include <utility>
 
 #include "base/callback.h"
+#include "base/callback_helpers.h"
+#include "base/feature_list.h"
 #include "base/notreached.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/browser/notifications/notification_display_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 
-namespace {
-constexpr int kShowActionIndex = 0;
-}  // namespace
-
 MutedNotificationHandler::MutedNotificationHandler(Delegate* delegate)
     : delegate_(delegate) {
   DCHECK(delegate_);
@@ -30,14 +29,27 @@
     const absl::optional<int>& action_index,
     const absl::optional<std::u16string>& reply,
     base::OnceClosure completed_closure) {
-  if (!action_index)
-    delegate_->OnAction(Action::kBodyClick);
-  else if (*action_index == kShowActionIndex)
-    delegate_->OnAction(Action::kShowClick);
-  else
-    NOTREACHED();
+  base::ScopedClosureRunner runner(std::move(completed_closure));
 
-  std::move(completed_closure).Run();
+  if (!action_index) {
+    delegate_->OnAction(Action::kBodyClick);
+    return;
+  }
+
+  // Indices of actions on the "Notifications Muted" notification must match the
+  // order in which we add the action buttons to the notification in
+  // ScreenCaptureNotificationBlocker::DisplayMuteNotification().
+
+  if (base::FeatureList::IsEnabled(features::kMuteNotificationSnoozeAction)) {
+    if (*action_index == 0)
+      delegate_->OnAction(Action::kSnoozeClick);
+    else if (*action_index == 1)
+      delegate_->OnAction(Action::kShowClick);
+    return;
+  }
+
+  if (*action_index == 0)
+    delegate_->OnAction(Action::kShowClick);
 }
 
 void MutedNotificationHandler::OnClose(Profile* profile,
diff --git a/chrome/browser/notifications/muted_notification_handler.h b/chrome/browser/notifications/muted_notification_handler.h
index 28ac4e9..f1bdc4e 100644
--- a/chrome/browser/notifications/muted_notification_handler.h
+++ b/chrome/browser/notifications/muted_notification_handler.h
@@ -25,6 +25,8 @@
     kBodyClick,
     // The user clicked on the "Show" action button.
     kShowClick,
+    // The user clicked on the "Snooze" action button.
+    kSnoozeClick,
   };
 
   // Delegate for handling muted notification actions.
@@ -55,6 +57,8 @@
                base::OnceClosure completed_closure) override;
   void OpenSettings(Profile* profile, const GURL& origin) override;
 
+  Delegate* get_delegate_for_testing() const { return delegate_; }
+
  private:
   Delegate* delegate_;
 };
diff --git a/chrome/browser/notifications/muted_notification_handler_unittest.cc b/chrome/browser/notifications/muted_notification_handler_unittest.cc
index f5f91b0..09f133b 100644
--- a/chrome/browser/notifications/muted_notification_handler_unittest.cc
+++ b/chrome/browser/notifications/muted_notification_handler_unittest.cc
@@ -8,6 +8,8 @@
 
 #include "base/callback.h"
 #include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/browser_features.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -27,9 +29,18 @@
   MOCK_METHOD(void, OnAction, (MutedNotificationHandler::Action), (override));
 };
 
-class MutedNotificationHandlerTest : public testing::Test {
+class MutedNotificationHandlerTest : public testing::TestWithParam<bool> {
  public:
-  MutedNotificationHandlerTest() = default;
+  MutedNotificationHandlerTest() {
+    if (GetParam()) {
+      feature_list_.InitAndEnableFeature(
+          features::kMuteNotificationSnoozeAction);
+    } else {
+      feature_list_.InitAndDisableFeature(
+          features::kMuteNotificationSnoozeAction);
+    }
+  }
+
   ~MutedNotificationHandlerTest() override = default;
 
   MockMutedNotificationHandlerDelegate& delegate() { return delegate_; }
@@ -37,11 +48,12 @@
   MutedNotificationHandler& handler() { return handler_; }
 
  private:
+  base::test::ScopedFeatureList feature_list_;
   MockMutedNotificationHandlerDelegate delegate_;
   MutedNotificationHandler handler_{&delegate_};
 };
 
-TEST_F(MutedNotificationHandlerTest, OnUserClose) {
+TEST_P(MutedNotificationHandlerTest, OnUserClose) {
   base::MockCallback<base::OnceClosure> callback;
   EXPECT_CALL(callback, Run());
   EXPECT_CALL(delegate(),
@@ -51,7 +63,7 @@
                     callback.Get());
 }
 
-TEST_F(MutedNotificationHandlerTest, OnNonUserClose) {
+TEST_P(MutedNotificationHandlerTest, OnNonUserClose) {
   base::MockCallback<base::OnceClosure> callback;
   EXPECT_CALL(callback, Run());
   EXPECT_CALL(delegate(), OnAction).Times(0);
@@ -60,7 +72,7 @@
                     callback.Get());
 }
 
-TEST_F(MutedNotificationHandlerTest, OnClickBody) {
+TEST_P(MutedNotificationHandlerTest, OnClickBody) {
   base::MockCallback<base::OnceClosure> callback;
   EXPECT_CALL(callback, Run());
   EXPECT_CALL(delegate(),
@@ -70,12 +82,28 @@
       /*action_index=*/absl::nullopt, /*reply=*/absl::nullopt, callback.Get());
 }
 
-TEST_F(MutedNotificationHandlerTest, OnClickShow) {
+TEST_P(MutedNotificationHandlerTest, OnClickSnooze) {
+  if (!GetParam())
+    return;
+
+  base::MockCallback<base::OnceClosure> callback;
+  EXPECT_CALL(callback, Run());
+  EXPECT_CALL(delegate(),
+              OnAction(MutedNotificationHandler::Action::kSnoozeClick));
+  handler().OnClick(
+      /*profile=*/nullptr, GURL(), /*notification_id=*/std::string(),
+      /*action_index=*/0, /*reply=*/absl::nullopt, callback.Get());
+}
+
+TEST_P(MutedNotificationHandlerTest, OnClickShow) {
   base::MockCallback<base::OnceClosure> callback;
   EXPECT_CALL(callback, Run());
   EXPECT_CALL(delegate(),
               OnAction(MutedNotificationHandler::Action::kShowClick));
   handler().OnClick(
       /*profile=*/nullptr, GURL(), /*notification_id=*/std::string(),
-      /*action_index=*/0, /*reply=*/absl::nullopt, callback.Get());
+      /*action_index=*/GetParam() ? 1 : 0, /*reply=*/absl::nullopt,
+      callback.Get());
 }
+
+INSTANTIATE_TEST_SUITE_P(, MutedNotificationHandlerTest, testing::Bool());
diff --git a/chrome/browser/notifications/notification_display_service_impl_unittest.cc b/chrome/browser/notifications/notification_display_service_impl_unittest.cc
index ce04a49..f9cde02 100644
--- a/chrome/browser/notifications/notification_display_service_impl_unittest.cc
+++ b/chrome/browser/notifications/notification_display_service_impl_unittest.cc
@@ -11,13 +11,19 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/notifications/notification_blocker.h"
 #include "chrome/browser/notifications/notification_display_queue.h"
 #include "chrome/browser/notifications/notification_display_service_impl.h"
 #include "chrome/browser/notifications/notification_platform_bridge_delegator.h"
 #include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_contents_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
@@ -28,6 +34,11 @@
 #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 #endif
 
+#if !defined(OS_ANDROID)
+#include "chrome/browser/notifications/muted_notification_handler.h"
+#include "chrome/browser/notifications/screen_capture_notification_blocker.h"
+#endif
+
 namespace {
 
 class FakeNotificationBlocker : public NotificationBlocker {
@@ -89,12 +100,12 @@
 
 }  // namespace
 
-class NotificationDisplayServiceImplTest : public testing::Test {
+class BaseNotificationDisplayServiceImplTest : public testing::Test {
  protected:
-  NotificationDisplayServiceImplTest() = default;
-  ~NotificationDisplayServiceImplTest() override = default;
+  BaseNotificationDisplayServiceImplTest() = default;
+  ~BaseNotificationDisplayServiceImplTest() override = default;
 
-  // BrowserWithTestWindowTest:
+  // testing::Test:
   void SetUp() override {
     service_ = std::make_unique<NotificationDisplayServiceImpl>(&profile_);
 
@@ -104,23 +115,12 @@
 
     service_->SetNotificationPlatformBridgeDelegatorForTesting(
         std::move(notification_delegator));
-
-    auto blocker = std::make_unique<FakeNotificationBlocker>();
-    notification_blocker_ = blocker.get();
-
-    NotificationDisplayQueue::NotificationBlockers blockers;
-    blockers.push_back(std::move(blocker));
-    service_->SetBlockersForTesting(std::move(blockers));
   }
 
   Profile* profile() { return &profile_; }
 
   NotificationDisplayServiceImpl& service() { return *service_; }
 
-  FakeNotificationBlocker& notification_blocker() {
-    return *notification_blocker_;
-  }
-
  protected:
   std::set<std::string> GetDisplayedServiceSync() {
     std::set<std::string> displayed_ids;
@@ -162,6 +162,32 @@
   TestingProfile profile_;
   std::unique_ptr<NotificationDisplayServiceImpl> service_;
   TestNotificationPlatformBridgeDelegator* notification_delegator_ = nullptr;
+};
+
+// Test class that uses a FakeNotificationBlocker instead of the real ones.
+class NotificationDisplayServiceImplTest
+    : public BaseNotificationDisplayServiceImplTest {
+ protected:
+  NotificationDisplayServiceImplTest() = default;
+  ~NotificationDisplayServiceImplTest() override = default;
+
+  // BaseNotificationDisplayServiceImplTest:
+  void SetUp() override {
+    BaseNotificationDisplayServiceImplTest::SetUp();
+
+    auto blocker = std::make_unique<FakeNotificationBlocker>();
+    notification_blocker_ = blocker.get();
+
+    NotificationDisplayQueue::NotificationBlockers blockers;
+    blockers.push_back(std::move(blocker));
+    service().SetBlockersForTesting(std::move(blockers));
+  }
+
+  FakeNotificationBlocker& notification_blocker() {
+    return *notification_blocker_;
+  }
+
+ private:
   FakeNotificationBlocker* notification_blocker_ = nullptr;
 };
 
@@ -245,3 +271,79 @@
   }
 }
 #endif
+
+#if !defined(OS_ANDROID)
+
+// Desktop specific test class that uses the default NotificationBlockers.
+class DesktopNotificationDisplayServiceImplTest
+    : public BaseNotificationDisplayServiceImplTest {
+ protected:
+  DesktopNotificationDisplayServiceImplTest() = default;
+  ~DesktopNotificationDisplayServiceImplTest() override = default;
+
+  // BaseNotificationDisplayServiceImplTest:
+  void SetUp() override {
+    BaseNotificationDisplayServiceImplTest::SetUp();
+
+    auto* muted_handler =
+        static_cast<MutedNotificationHandler*>(service().GetNotificationHandler(
+            NotificationHandler::Type::NOTIFICATIONS_MUTED));
+    ASSERT_TRUE(muted_handler);
+    screen_capture_blocker_ = static_cast<ScreenCaptureNotificationBlocker*>(
+        muted_handler->get_delegate_for_testing());
+    ASSERT_TRUE(screen_capture_blocker_);
+  }
+
+  ScreenCaptureNotificationBlocker* screen_capture_notification_blocker() {
+    return screen_capture_blocker_;
+  }
+
+ private:
+  ScreenCaptureNotificationBlocker* screen_capture_blocker_ = nullptr;
+};
+
+TEST_F(DesktopNotificationDisplayServiceImplTest, SnoozeDuringScreenCapture) {
+  base::test::ScopedFeatureList list;
+  list.InitAndEnableFeature(features::kMuteNotificationSnoozeAction);
+
+  content::TestWebContentsFactory web_contents_factory;
+  content::WebContents* contents =
+      web_contents_factory.CreateWebContents(profile());
+  EXPECT_TRUE(GetDisplayedPlatformSync().empty());
+
+  // Start a screen capture session.
+  screen_capture_notification_blocker()->OnIsCapturingDisplayChanged(
+      contents, /*is_capturing_display=*/true);
+
+  // Displaying a notification should show the "Notifications Muted" generic
+  // notification instead of the real notification content.
+  std::string notification_id_1 = "id1";
+  DisplayNotification(notification_id_1);
+  EXPECT_EQ(1u, GetDisplayedPlatformSync().size());
+  EXPECT_EQ(1u, GetDisplayedPlatformSync().count(kMuteNotificationId));
+
+  // Emulate the user clicking on the "Snooze" action button.
+  service().ProcessNotificationOperation(
+      NotificationCommon::OPERATION_CLICK,
+      NotificationHandler::Type::NOTIFICATIONS_MUTED, /*origin=*/GURL(),
+      kMuteNotificationId, /*action_index=*/0, /*reply=*/absl::nullopt,
+      /*by_user=*/true);
+
+  // Clicking "Snooze" should remove the "Notifications Muted" notification.
+  EXPECT_TRUE(GetDisplayedPlatformSync().empty());
+
+  // Showing another notification should not trigger any visible notification.
+  std::string notification_id_2 = "id2";
+  DisplayNotification(notification_id_2);
+  EXPECT_TRUE(GetDisplayedPlatformSync().empty());
+
+  // Stopping the screen sharing session should re-display all previously muted
+  // notifications.
+  screen_capture_notification_blocker()->OnIsCapturingDisplayChanged(
+      contents, /*is_capturing_display=*/false);
+  EXPECT_EQ(2u, GetDisplayedPlatformSync().size());
+  EXPECT_EQ(1u, GetDisplayedPlatformSync().count(notification_id_1));
+  EXPECT_EQ(1u, GetDisplayedPlatformSync().count(notification_id_2));
+}
+
+#endif  // !defined(OS_ANDROID)
diff --git a/chrome/browser/notifications/screen_capture_notification_blocker.cc b/chrome/browser/notifications/screen_capture_notification_blocker.cc
index aee0bae..c038daf 100644
--- a/chrome/browser/notifications/screen_capture_notification_blocker.cc
+++ b/chrome/browser/notifications/screen_capture_notification_blocker.cc
@@ -6,8 +6,10 @@
 
 #include <algorithm>
 
+#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/grit/generated_resources.h"
@@ -19,10 +21,9 @@
 
 namespace {
 
-const char kMuteNotificationId[] = "notifications_muted";
-
-// Suffix for a mute notification action. Should match suffix
-// NotificationMuteAction in histogram_suffixes_list.xml.
+// Suffix for a mute notification action. Should match suffixes of the
+// Notifications.Blocker.ScreenCapture.* metrics in
+// histograms_xml/notifications/histograms.xml
 std::string MutedActionSuffix(MutedNotificationHandler::Action action) {
   switch (action) {
     case MutedNotificationHandler::Action::kUserClose:
@@ -31,6 +32,8 @@
       return "Body";
     case MutedNotificationHandler::Action::kShowClick:
       return "Show";
+    case MutedNotificationHandler::Action::kSnoozeClick:
+      return "Snooze";
   }
 }
 
@@ -41,6 +44,8 @@
 
 }  // namespace
 
+const char kMuteNotificationId[] = "notifications_muted";
+
 ScreenCaptureNotificationBlocker::ScreenCaptureNotificationBlocker(
     NotificationDisplayService* notification_display_service)
     : notification_display_service_(notification_display_service) {
@@ -79,6 +84,9 @@
   else
     ++muted_notification_count_;
 
+  if (state_ == NotifyState::kSnooze)
+    ++snoozed_notification_count_;
+
   if (state_ == NotifyState::kNotifyMuted)
     DisplayMuteNotification();
 }
@@ -104,6 +112,9 @@
       NotifyBlockingStateChanged();
       ReportSessionMetrics(/*revealed=*/true);
       break;
+    case MutedNotificationHandler::Action::kSnoozeClick:
+      state_ = NotifyState::kSnooze;
+      break;
   }
 }
 
@@ -120,6 +131,7 @@
     muted_notification_count_ = 0;
     replaced_notification_count_ = 0;
     closed_notification_count_ = 0;
+    snoozed_notification_count_ = 0;
     reported_session_metrics_ = false;
     state_ = NotifyState::kNotifyMuted;
     last_screen_capture_session_start_time_ = base::TimeTicks();
@@ -145,6 +157,7 @@
   RecordScreenCaptureCount("MutedCount", muted_notification_count_);
   RecordScreenCaptureCount("ReplacedCount", replaced_notification_count_);
   RecordScreenCaptureCount("ClosedCount", closed_notification_count_);
+  RecordScreenCaptureCount("SnoozedCount", snoozed_notification_count_);
 
   reported_session_metrics_ = true;
 }
@@ -169,6 +182,11 @@
 
   message_center::RichNotificationData rich_notification_data;
   rich_notification_data.renotify = true;
+
+  if (base::FeatureList::IsEnabled(features::kMuteNotificationSnoozeAction)) {
+    rich_notification_data.buttons.emplace_back(
+        l10n_util::GetStringUTF16(IDS_NOTIFICATION_MUTED_ACTION_SNOOZE));
+  }
   rich_notification_data.buttons.emplace_back(l10n_util::GetPluralStringFUTF16(
       IDS_NOTIFICATION_MUTED_ACTION_SHOW, total_notification_count));
 
diff --git a/chrome/browser/notifications/screen_capture_notification_blocker.h b/chrome/browser/notifications/screen_capture_notification_blocker.h
index 7cec98c..7a75086 100644
--- a/chrome/browser/notifications/screen_capture_notification_blocker.h
+++ b/chrome/browser/notifications/screen_capture_notification_blocker.h
@@ -19,6 +19,9 @@
 
 class NotificationDisplayService;
 
+// To share with unit tests.
+extern const char kMuteNotificationId[];
+
 // This notification blocker listens to the events when the user starts
 // capturing a display. It will block notifications while such a capture is
 // ongoing. Note that this does not include casting the whole display and only
@@ -66,6 +69,8 @@
     kNotifyMuted,
     // The user clicked on "Show" and we show all notifications as usual.
     kShowAll,
+    // The user clicked on "Snooze" to snooze all notifications in this session.
+    kSnooze,
   };
 
   NotifyState state_ = NotifyState::kNotifyMuted;
@@ -76,6 +81,8 @@
   int replaced_notification_count_ = 0;
   // Number of notifications closed during the current screen capture session.
   int closed_notification_count_ = 0;
+  // Number of notifications prevented from showing while we're snoozing.
+  int snoozed_notification_count_ = 0;
   // Flag if metrics have been reported for the current screen capture session.
   bool reported_session_metrics_ = false;
   // Timestamp of when the last "muted" notification got shown.
diff --git a/chrome/browser/notifications/screen_capture_notification_blocker_unittest.cc b/chrome/browser/notifications/screen_capture_notification_blocker_unittest.cc
index b7039e0..8063f35 100644
--- a/chrome/browser/notifications/screen_capture_notification_blocker_unittest.cc
+++ b/chrome/browser/notifications/screen_capture_notification_blocker_unittest.cc
@@ -6,6 +6,8 @@
 
 #include "base/scoped_observation.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
 #include "chrome/browser/notifications/muted_notification_handler.h"
@@ -42,10 +44,6 @@
 
 }  // namespace
 
-namespace {
-constexpr int kShowActionIndex = 0;
-}  // namespace
-
 class MockNotificationBlockerObserver : public NotificationBlocker::Observer {
  public:
   MockNotificationBlockerObserver() = default;
@@ -59,9 +57,18 @@
   MOCK_METHOD(void, OnBlockingStateChanged, (), (override));
 };
 
-class ScreenCaptureNotificationBlockerTest : public testing::Test {
+class ScreenCaptureNotificationBlockerTest
+    : public testing::TestWithParam<bool> {
  public:
   ScreenCaptureNotificationBlockerTest() {
+    if (GetParam()) {
+      feature_list_.InitAndEnableFeature(
+          features::kMuteNotificationSnoozeAction);
+    } else {
+      feature_list_.InitAndDisableFeature(
+          features::kMuteNotificationSnoozeAction);
+    }
+
     notification_service_ =
         std::make_unique<StubNotificationDisplayService>(&profile_);
     auto blocker = std::make_unique<ScreenCaptureNotificationBlocker>(
@@ -124,18 +131,19 @@
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
  private:
+  base::test::ScopedFeatureList feature_list_;
   TestingProfile profile_;
   content::TestWebContentsFactory web_contents_factory_;
   std::unique_ptr<StubNotificationDisplayService> notification_service_;
   ScreenCaptureNotificationBlocker* blocker_;
 };
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShouldNotBlockWhenNotCapturing) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShouldNotBlockWhenNotCapturing) {
   EXPECT_FALSE(blocker().ShouldBlockNotification(
       CreateNotification(GURL("https://example.com"))));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShouldNotBlockCapturingOrigin) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShouldNotBlockCapturingOrigin) {
   GURL origin1("https://example1.com");
   GURL origin2("https://example2.com");
   GURL origin3("https://example3.com");
@@ -149,14 +157,14 @@
   EXPECT_TRUE(blocker().ShouldBlockNotification(CreateNotification(origin3)));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShouldBlockWhenCapturing) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShouldBlockWhenCapturing) {
   blocker().OnIsCapturingDisplayChanged(
       CreateWebContents(GURL("https://example1.com")), true);
   EXPECT_TRUE(blocker().ShouldBlockNotification(
       CreateNotification(GURL("https://example2.com"))));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShouldBlockWhenCapturingMutliple) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShouldBlockWhenCapturingMutliple) {
   content::WebContents* contents_1 =
       CreateWebContents(GURL("https://example1.com"));
   content::WebContents* contents_2 =
@@ -176,7 +184,7 @@
       CreateNotification(GURL("https://example3.com"))));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, CapturingTwice) {
+TEST_P(ScreenCaptureNotificationBlockerTest, CapturingTwice) {
   content::WebContents* contents =
       CreateWebContents(GURL("https://example1.com"));
 
@@ -191,7 +199,7 @@
       CreateNotification(GURL("https://example2.com"))));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, StopUnknownContents) {
+TEST_P(ScreenCaptureNotificationBlockerTest, StopUnknownContents) {
   content::WebContents* contents =
       CreateWebContents(GURL("https://example1.com"));
   blocker().OnIsCapturingDisplayChanged(contents, false);
@@ -199,7 +207,7 @@
       CreateNotification(GURL("https://example2.com"))));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest,
+TEST_P(ScreenCaptureNotificationBlockerTest,
        ObservesMediaStreamCaptureIndicator) {
   MediaStreamCaptureIndicator* indicator =
       MediaCaptureDevicesDispatcher::GetInstance()
@@ -208,7 +216,7 @@
   EXPECT_TRUE(blocker().observation_.IsObservingSource(indicator));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShowsMutedNotification) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShowsMutedNotification) {
   EXPECT_FALSE(GetMutedNotification());
 
   blocker().OnIsCapturingDisplayChanged(
@@ -227,13 +235,24 @@
             notification->title());
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NOTIFICATION_MUTED_MESSAGE),
             notification->message());
-  ASSERT_EQ(1u, notification->buttons().size());
-  EXPECT_EQ(l10n_util::GetPluralStringFUTF16(IDS_NOTIFICATION_MUTED_ACTION_SHOW,
-                                             /*count=*/1),
-            notification->buttons()[0].title);
+  if (GetParam()) {
+    ASSERT_EQ(2u, notification->buttons().size());
+    EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NOTIFICATION_MUTED_ACTION_SNOOZE),
+              notification->buttons()[0].title);
+    EXPECT_EQ(
+        l10n_util::GetPluralStringFUTF16(IDS_NOTIFICATION_MUTED_ACTION_SHOW,
+                                         /*count=*/1),
+        notification->buttons()[1].title);
+  } else {
+    ASSERT_EQ(1u, notification->buttons().size());
+    EXPECT_EQ(
+        l10n_util::GetPluralStringFUTF16(IDS_NOTIFICATION_MUTED_ACTION_SHOW,
+                                         /*count=*/1),
+        notification->buttons()[0].title);
+  }
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, UpdatesMutedNotification) {
+TEST_P(ScreenCaptureNotificationBlockerTest, UpdatesMutedNotification) {
   constexpr int kCount = 10;
   blocker().OnIsCapturingDisplayChanged(
       CreateWebContents(GURL("https://example1.com")), true);
@@ -252,13 +271,9 @@
       notification->title());
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NOTIFICATION_MUTED_MESSAGE),
             notification->message());
-  ASSERT_EQ(1u, notification->buttons().size());
-  EXPECT_EQ(l10n_util::GetPluralStringFUTF16(IDS_NOTIFICATION_MUTED_ACTION_SHOW,
-                                             kCount),
-            notification->buttons()[0].title);
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ClosesMutedNotification) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ClosesMutedNotification) {
   content::WebContents* contents =
       CreateWebContents(GURL("https://example1.com"));
   // No notification initially.
@@ -275,7 +290,7 @@
   EXPECT_FALSE(GetMutedNotification());
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest,
+TEST_P(ScreenCaptureNotificationBlockerTest,
        ClosesMutedNotificationOnBodyClick) {
   blocker().OnIsCapturingDisplayChanged(
       CreateWebContents(GURL("https://example1.com")), true);
@@ -287,7 +302,7 @@
   EXPECT_FALSE(GetMutedNotification());
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShowsMutedNotificationAfterClose) {
+TEST_P(ScreenCaptureNotificationBlockerTest, ShowsMutedNotificationAfterClose) {
   blocker().OnIsCapturingDisplayChanged(
       CreateWebContents(GURL("https://example1.com")), true);
   blocker().OnBlockedNotification(
@@ -307,7 +322,47 @@
             notification->title());
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShowAction) {
+TEST_P(ScreenCaptureNotificationBlockerTest, SnoozeAction) {
+  if (!GetParam())
+    return;
+
+  blocker().OnIsCapturingDisplayChanged(
+      CreateWebContents(GURL("https://example1.com")), true);
+  blocker().OnBlockedNotification(
+      CreateNotification(GURL("https://example2.com")), /*replaced*/ false);
+
+  // "Snooze" should close and prevent any future notification.
+  SimulateClick(0);
+  EXPECT_FALSE(GetMutedNotification());
+
+  blocker().OnBlockedNotification(
+      CreateNotification(GURL("https://example2.com")), /*replaced*/ false);
+  EXPECT_FALSE(GetMutedNotification());
+}
+
+TEST_P(ScreenCaptureNotificationBlockerTest, SnoozeActionShowOnNextSession) {
+  if (!GetParam())
+    return;
+
+  content::WebContents* contents =
+      CreateWebContents(GURL("https://example1.com"));
+  blocker().OnIsCapturingDisplayChanged(contents, true);
+  blocker().OnBlockedNotification(
+      CreateNotification(GURL("https://example2.com")), /*replaced*/ false);
+  SimulateClick(0);
+  EXPECT_FALSE(GetMutedNotification());
+
+  // After hiding all notifications and stopping and starting capture we should
+  // see notifications again.
+  blocker().OnIsCapturingDisplayChanged(contents, false);
+  blocker().OnIsCapturingDisplayChanged(contents, true);
+
+  blocker().OnBlockedNotification(
+      CreateNotification(GURL("https://example2.com")), /*replaced*/ false);
+  EXPECT_TRUE(GetMutedNotification());
+}
+
+TEST_P(ScreenCaptureNotificationBlockerTest, ShowAction) {
   MockNotificationBlockerObserver observer;
   base::ScopedObservation<NotificationBlocker, NotificationBlocker::Observer>
       scoped_observer(&observer);
@@ -326,14 +381,14 @@
   // Showing should close the "Notifications muted" notification and allow
   // showing future web notifications.
   EXPECT_CALL(observer, OnBlockingStateChanged);
-  SimulateClick(kShowActionIndex);
+  SimulateClick(GetParam() ? 1 : 0);
   testing::Mock::VerifyAndClearExpectations(&observer);
 
   EXPECT_FALSE(GetMutedNotification());
   EXPECT_FALSE(blocker().ShouldBlockNotification(notification));
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, CloseHistogram) {
+TEST_P(ScreenCaptureNotificationBlockerTest, CloseHistogram) {
   base::HistogramTester histogram_tester;
   const char kHistogram[] = "Notifications.Blocker.ScreenCapture.Action.Close";
 
@@ -364,7 +419,7 @@
   histogram_tester.ExpectTotalCount(kHistogram, /*count=*/2);
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, BodyClickHistogram) {
+TEST_P(ScreenCaptureNotificationBlockerTest, BodyClickHistogram) {
   base::HistogramTester histogram_tester;
   const char kHistogram[] = "Notifications.Blocker.ScreenCapture.Action.Body";
 
@@ -391,7 +446,41 @@
   histogram_tester.ExpectTotalCount(kHistogram, /*count=*/2);
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, ShowClickHistogram) {
+TEST_P(ScreenCaptureNotificationBlockerTest, SnoozeClickHistogram) {
+  if (!GetParam())
+    return;
+
+  base::HistogramTester histogram_tester;
+
+  content::WebContents* contents =
+      CreateWebContents(GURL("https://example1.com"));
+  blocker().OnIsCapturingDisplayChanged(contents, true);
+  message_center::Notification notification =
+      CreateNotification(GURL("https://example2.com"));
+
+  blocker().OnBlockedNotification(notification, /*replaced*/ false);
+
+  auto action_delay = base::TimeDelta::FromSeconds(5);
+  task_environment_.FastForwardBy(action_delay);
+  SimulateClick(0);
+
+  histogram_tester.ExpectUniqueSample(
+      "Notifications.Blocker.ScreenCapture.Action.Snooze", /*sample=*/1,
+      /*count=*/1);
+  histogram_tester.ExpectUniqueTimeSample(
+      "Notifications.Blocker.ScreenCapture.ActionTiming.Snooze", action_delay,
+      /*count=*/1);
+
+  // Test showing another notification while snoozing.
+  blocker().OnBlockedNotification(notification, /*replaced*/ false);
+  blocker().OnIsCapturingDisplayChanged(contents, false);
+
+  histogram_tester.ExpectUniqueSample(
+      "Notifications.Blocker.ScreenCapture.SnoozedCount", /*sample=*/1,
+      /*count=*/1);
+}
+
+TEST_P(ScreenCaptureNotificationBlockerTest, ShowClickHistogram) {
   base::HistogramTester histogram_tester;
 
   blocker().OnIsCapturingDisplayChanged(
@@ -403,7 +492,7 @@
 
   auto action_delay = base::TimeDelta::FromSeconds(5);
   task_environment_.FastForwardBy(action_delay);
-  SimulateClick(kShowActionIndex);
+  SimulateClick(GetParam() ? 1 : 0);
 
   histogram_tester.ExpectUniqueSample(
       "Notifications.Blocker.ScreenCapture.Action.Show", /*sample=*/1,
@@ -413,7 +502,7 @@
       /*count=*/1);
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, SessionEndHistograms) {
+TEST_P(ScreenCaptureNotificationBlockerTest, SessionEndHistograms) {
   base::HistogramTester histogram_tester;
 
   content::WebContents* contents =
@@ -449,9 +538,14 @@
   histogram_tester.ExpectUniqueSample(
       "Notifications.Blocker.ScreenCapture.ClosedCount", /*sample=*/1,
       /*count=*/1);
+  if (GetParam()) {
+    histogram_tester.ExpectUniqueSample(
+        "Notifications.Blocker.ScreenCapture.SnoozedCount", /*sample=*/0,
+        /*count=*/1);
+  }
 }
 
-TEST_F(ScreenCaptureNotificationBlockerTest, SessionTimingHistograms) {
+TEST_P(ScreenCaptureNotificationBlockerTest, SessionTimingHistograms) {
   base::HistogramTester histogram_tester;
 
   content::WebContents* contents =
@@ -465,7 +559,7 @@
   auto click_delay = base::TimeDelta::FromSeconds(3);
   task_environment_.FastForwardBy(click_delay);
 
-  SimulateClick(kShowActionIndex);
+  SimulateClick(GetParam() ? 1 : 0);
 
   auto session_delay = base::TimeDelta::FromSeconds(5);
   task_environment_.FastForwardBy(session_delay);
@@ -480,3 +574,7 @@
       click_delay + session_delay,
       /*count=*/1);
 }
+
+INSTANTIATE_TEST_SUITE_P(,
+                         ScreenCaptureNotificationBlockerTest,
+                         testing::Bool());
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html b/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html
index 71db767..facce65d 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/full_size_image.html
@@ -1,14 +1,13 @@
-<iframe width="96" height="96" src="iframe_with_image.html"></iframe>
 <script>
   const lcpPromise = new Promise(resolve => {
     window.addEventListener("message", event => {
       iframeLCP = event.data.startTime;
       timeOriginDelta = event.data.timeOrigin - performance.timeOrigin;
-      lcpTime = iframeLCP + timeOriginDelta;
-      resolve();
+      resolve(iframeLCP + timeOriginDelta);
     });
   });
-  async function waitForLCP() {
-    await lcpPromise;
+  function waitForLCP() {
+    return lcpPromise;
   }
 </script>
+<iframe width="96" height="96" src="iframe_with_image.html"></iframe>
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html b/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html
index fa995b323..05f5ff30 100644
--- a/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html
+++ b/chrome/browser/page_load_metrics/integration_tests/data/iframe_with_image.html
@@ -6,8 +6,12 @@
 <img src="images/blue96x96.png" />
 <script>
   new PerformanceObserver(e => {
-    const entries = e.getEntries();
-    const entry = entries[entries.length - 1];
+    // We only care about entry with url, i.e. for images, not any spurrious
+    // text entry.
+    const entries = e.getEntries().filter(e => e.url != '');
+    if (entries.length === 0)
+      return;
+    const entry = entries[0];
     window.parent.postMessage({
       startTime: entry.startTime, timeOrigin: performance.timeOrigin
     }, '*');
diff --git a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
index ccb71e345..834eaab8b 100644
--- a/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/largest_contentful_paint_browsertest.cc
@@ -166,12 +166,11 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(PageViewportInLCPTest, DISABLED_FullSizeImageInIframe) {
+IN_PROC_BROWSER_TEST_F(PageViewportInLCPTest, FullSizeImageInIframe) {
   Start();
   StartTracing({"loading"});
   Load("/full_size_image.html");
-  content::EvalJsResult result = EvalJs(web_contents(), "waitForLCP()");
-  double lcpTime = EvalJs(web_contents(), "lcpTime").ExtractDouble();
+  double lcpTime = EvalJs(web_contents(), "waitForLCP()").ExtractDouble();
 
   // Navigate away to force metrics recording.
   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
diff --git a/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
index 024a0eb..6e7e378 100644
--- a/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/back_forward_cache_page_load_metrics_observer_browsertest.cc
@@ -33,7 +33,8 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     feature_list_.InitWithFeaturesAndParameters(
         {{features::kBackForwardCache,
-          {{"TimeToLiveInBackForwardCacheInSeconds", "3600"}}},
+          {{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
+           {"ignore_outstanding_network_request_for_testing", "true"}}},
          {internal::kBackForwardCacheEmitZeroSamplesForKeyMetrics, {{}}}},
         // Allow BackForwardCache for all devices regardless of their memory.
         {features::kBackForwardCacheMemoryControls});
@@ -97,23 +98,15 @@
 
 }  // namespace
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223445
-#define MAYBE_FirstPaintAfterBackForwardCacheRestore \
-  DISABLED_FirstPaintAfterBackForwardCacheRestore
-#else
-#define MAYBE_FirstPaintAfterBackForwardCacheRestore \
-  FirstPaintAfterBackForwardCacheRestore
-#endif
 IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
-                       MAYBE_FirstPaintAfterBackForwardCacheRestore) {
+                       FirstPaintAfterBackForwardCacheRestore) {
   Start();
   GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
 
   // Navigate to A.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHost* rfh_a = top_frame_host();
+  content::RenderFrameHostWrapper rfh_a(top_frame_host());
 
   // Navigate to B.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
@@ -128,7 +121,7 @@
             kFirstPaintAfterBackForwardCacheRestore);
     web_contents()->GetController().GoBack();
     EXPECT_TRUE(WaitForLoadStop(web_contents()));
-    EXPECT_EQ(rfh_a, top_frame_host());
+    EXPECT_EQ(rfh_a.get(), top_frame_host());
     EXPECT_NE(rfh_a->GetLifecycleState(),
               content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
@@ -147,10 +140,6 @@
         internal::kHistogramLargestContentfulPaint, 0, 1);
   }
 
-  // The RenderFrameHost for the page B was likely in the back-forward cache
-  // just after the history navigation, but now this might be evicted due to
-  // outstanding-network request.
-
   // Navigate to B again.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
   EXPECT_EQ(rfh_a->GetLifecycleState(),
@@ -164,7 +153,7 @@
             kFirstPaintAfterBackForwardCacheRestore);
     web_contents()->GetController().GoBack();
     EXPECT_TRUE(WaitForLoadStop(web_contents()));
-    EXPECT_EQ(rfh_a, top_frame_host());
+    EXPECT_EQ(rfh_a.get(), top_frame_host());
     EXPECT_NE(rfh_a->GetLifecycleState(),
               content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
@@ -182,24 +171,15 @@
   }
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// Bulk-disabled for arm64 bot stabilization: https://crbug.com/1154345
-#define MAYBE_FirstPaintAfterBackForwardCacheRestoreBackground \
-  DISABLED_FirstPaintAfterBackForwardCacheRestoreBackground
-#else
-#define MAYBE_FirstPaintAfterBackForwardCacheRestoreBackground \
-  FirstPaintAfterBackForwardCacheRestoreBackground
-#endif
-
 IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
-                       MAYBE_FirstPaintAfterBackForwardCacheRestoreBackground) {
+                       FirstPaintAfterBackForwardCacheRestoreBackground) {
   Start();
   GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
 
   // Navigate to A.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHost* rfh_a = top_frame_host();
+  content::RenderFrameHostWrapper rfh_a(top_frame_host());
 
   // Navigate to B.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
@@ -219,7 +199,7 @@
     web_contents()->WasHidden();
 
     EXPECT_TRUE(WaitForLoadStop(web_contents()));
-    EXPECT_EQ(rfh_a, top_frame_host());
+    EXPECT_EQ(rfh_a.get(), top_frame_host());
     EXPECT_NE(rfh_a->GetLifecycleState(),
               content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
@@ -242,25 +222,15 @@
   }
 }
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// Bulk-disabled for arm64 bot stabilization: https://crbug.com/1154345
-#define MAYBE_FirstInputDelayAfterBackForwardCacheRestoreBackground \
-  DISABLED_FirstInputDelayAfterBackForwardCacheRestoreBackground
-#else
-#define MAYBE_FirstInputDelayAfterBackForwardCacheRestoreBackground \
-  FirstInputDelayAfterBackForwardCacheRestoreBackground
-#endif
-
-IN_PROC_BROWSER_TEST_F(
-    BackForwardCachePageLoadMetricsObserverBrowserTest,
-    MAYBE_FirstInputDelayAfterBackForwardCacheRestoreBackground) {
+IN_PROC_BROWSER_TEST_F(BackForwardCachePageLoadMetricsObserverBrowserTest,
+                       FirstInputDelayAfterBackForwardCacheRestoreBackground) {
   Start();
   GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
   GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html"));
 
   // Navigate to A.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a));
-  content::RenderFrameHost* rfh_a = top_frame_host();
+  content::RenderFrameHostWrapper rfh_a(top_frame_host());
 
   // Navigate to B.
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
@@ -279,7 +249,7 @@
 
     web_contents()->GetController().GoBack();
     EXPECT_TRUE(WaitForLoadStop(web_contents()));
-    EXPECT_EQ(rfh_a, top_frame_host());
+    EXPECT_EQ(rfh_a.get(), top_frame_host());
     EXPECT_NE(rfh_a->GetLifecycleState(),
               content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
diff --git a/chrome/browser/password_manager/password_manager_util_mac.mm b/chrome/browser/password_manager/password_manager_util_mac.mm
index b3ce5bc..7ace1fd 100644
--- a/chrome/browser/password_manager/password_manager_util_mac.mm
+++ b/chrome/browser/password_manager/password_manager_util_mac.mm
@@ -8,10 +8,10 @@
 #import <Foundation/Foundation.h>
 #include <Security/Authorization.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/authorization_util.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_authorizationref.h"
-#include "base/stl_util.h"
 #include "chrome/grit/chromium_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc
index b70466a..e44899c 100644
--- a/chrome/browser/permissions/permission_request_manager_browsertest.cc
+++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -826,7 +826,7 @@
   base::RunLoop().RunUntilIdle();
 
   permissions::MockPermissionRequest request2(
-      u"request2", permissions::RequestType::kGeolocation,
+      u"request2", permissions::RequestType::kMicStream,
       permissions::PermissionRequestGestureType::UNKNOWN);
   GetPermissionRequestManager()->AddRequest(source_frame, &request2);
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/permissions/permissions_security_model_browsertest.cc b/chrome/browser/permissions/permissions_security_model_browsertest.cc
index 75a225fa..8d1e9a0 100644
--- a/chrome/browser/permissions/permissions_security_model_browsertest.cc
+++ b/chrome/browser/permissions/permissions_security_model_browsertest.cc
@@ -18,6 +18,28 @@
 
 namespace {
 
+// Helper for CreateBlobURL() and CreateFilesystemURL().
+// ASSERT_* macros can only be used in functions returning void.
+void AssertResultIsString(const content::EvalJsResult& result) {
+  // Verify no error.
+  ASSERT_EQ("", result.error);
+  // We could use result.value.is_string(), but this logs the actual type in
+  // case of mismatch.
+  ASSERT_EQ(base::Value::Type::STRING, result.value.type()) << result.value;
+}
+
+// Creates a blob containing dummy HTML, then returns its URL.
+// Executes javascript to do so in |rfh|.
+GURL CreateBlobURL(content::RenderFrameHost* rfh) {
+  content::EvalJsResult result = content::EvalJs(rfh, R"(
+    const blob = new Blob(["foo"], {type: "text/html"});
+    URL.createObjectURL(blob)
+  )");
+
+  AssertResultIsString(result);
+  return GURL(result.ExtractString());
+}
+
 // Tests of permissions behavior for an inheritance and embedding of an origin.
 // Test fixtures are run with and without the `PermissionsRevisedOriginHandling`
 // flag.
@@ -43,15 +65,18 @@
         embedder_support::kDisablePopupBlocking);
   }
 
-  Browser* OpenPopup(Browser* browser) const {
-    auto* contents = browser->tab_strip_model()->GetActiveWebContents();
+  content::WebContents* OpenPopup(Browser* browser, const GURL& url) const {
+    content::WebContents* contents =
+        browser->tab_strip_model()->GetActiveWebContents();
     content::ExecuteScriptAsync(
-        contents, "w = open('about:blank', '', 'width=200,height=200');");
+        contents, content::JsReplace("window.open($1, '', '[]');", url));
     Browser* popup = ui_test_utils::WaitForBrowserToOpen();
     EXPECT_NE(popup, browser);
-    auto* popup_contents = popup->tab_strip_model()->GetActiveWebContents();
+    content::WebContents* popup_contents =
+        popup->tab_strip_model()->GetActiveWebContents();
     EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetMainFrame()));
-    return popup;
+    WaitForLoadStop(popup_contents);
+    return popup_contents;
   }
 
   bool IsRevisedOriginHandlingEnabled() { return GetParam(); }
@@ -191,13 +216,13 @@
                          ::testing::Bool());
 
 IN_PROC_BROWSER_TEST_P(PermissionsSecurityModelBrowserTest,
-                       AboutBlankOriginEmbedder) {
+                       EmbedIframeAboutBlank) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL url(embedded_test_server()->GetURL("/iframe_about_blank.html"));
-  content::RenderFrameHost* main_host =
+  content::RenderFrameHost* main_rfh =
       ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url,
                                                                 1);
-  ASSERT_TRUE(main_host);
+  ASSERT_TRUE(main_rfh);
 
   content::WebContents* embedder_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -214,7 +239,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(PermissionsSecurityModelBrowserTest,
-                       AboutBlankOriginOpener) {
+                       WindowOpenAboutBlank) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL url(embedded_test_server()->GetURL("/empty.html"));
   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
@@ -222,9 +247,8 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(opener_contents);
 
-  Browser* popup = OpenPopup(browser());
   content::WebContents* popup_contents =
-      popup->tab_strip_model()->GetActiveWebContents();
+      OpenPopup(browser(), GURL("about:blank"));
   ASSERT_TRUE(popup_contents);
 
   TestNotifications(opener_contents, popup_contents->GetMainFrame());
@@ -232,4 +256,75 @@
   TestCamera(opener_contents, popup_contents->GetMainFrame());
 }
 
+// `about:srcdoc` supports only embedder WebContents, hence no test for opener.
+IN_PROC_BROWSER_TEST_P(PermissionsSecurityModelBrowserTest, EmbedIframeSrcDoc) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url(embedded_test_server()->GetURL("/iframe_srcdoc.html"));
+  content::RenderFrameHost* main_rfh =
+      ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url,
+                                                                1);
+  ASSERT_TRUE(main_rfh);
+
+  content::WebContents* embedder_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::RenderFrameHost* srcdoc_iframe = content::FrameMatchingPredicate(
+      embedder_contents,
+      base::BindRepeating(&content::FrameMatchesName, "srcdoc_iframe"));
+  ASSERT_TRUE(srcdoc_iframe);
+
+  TestNotifications(embedder_contents, srcdoc_iframe);
+  TestGeolocation(embedder_contents, srcdoc_iframe);
+  TestCamera(embedder_contents, srcdoc_iframe);
+}
+
+IN_PROC_BROWSER_TEST_P(PermissionsSecurityModelBrowserTest, EmbedIframeBlob) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url(embedded_test_server()->GetURL("/iframe_blob.html"));
+  content::RenderFrameHost* main_rfh =
+      ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url,
+                                                                1);
+  ASSERT_TRUE(main_rfh);
+
+  content::WebContents* embedder_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::RenderFrameHost* blob_iframe_rfh = content::FrameMatchingPredicate(
+      embedder_contents,
+      base::BindRepeating(&content::FrameMatchesName, "blob_iframe"));
+  ASSERT_TRUE(blob_iframe_rfh);
+  EXPECT_TRUE(blob_iframe_rfh->GetLastCommittedURL().SchemeIsBlob());
+
+  TestNotifications(embedder_contents, blob_iframe_rfh);
+  TestGeolocation(embedder_contents, blob_iframe_rfh);
+  TestCamera(embedder_contents, blob_iframe_rfh);
+}
+
+IN_PROC_BROWSER_TEST_P(PermissionsSecurityModelBrowserTest, WindowOpenBlob) {
+  if (GetParam()) {
+    // Blob iframe on an opener contents does not work if
+    // `kRevisedOriginHandling` feature enabled.
+    // TODO(crbug.com/698985): Remove when the bug is fixed.
+    return;
+  }
+
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL url(embedded_test_server()->GetURL("/empty.html"));
+  EXPECT_TRUE(ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+      browser(), url, 1));
+  content::WebContents* opener_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(opener_contents);
+
+  content::WebContents* blob_popup_contents =
+      OpenPopup(browser(), CreateBlobURL(opener_contents->GetMainFrame()));
+  ASSERT_TRUE(blob_popup_contents);
+
+  EXPECT_TRUE(blob_popup_contents->GetLastCommittedURL().SchemeIsBlob());
+
+  TestNotifications(opener_contents, blob_popup_contents->GetMainFrame());
+  TestGeolocation(opener_contents, blob_popup_contents->GetMainFrame());
+  TestCamera(opener_contents, blob_popup_contents->GetMainFrame());
+}
+
 }  // anonymous namespace
diff --git a/chrome/browser/platform_util_linux.cc b/chrome/browser/platform_util_linux.cc
index f7e96b9f..4052389 100644
--- a/chrome/browser/platform_util_linux.cc
+++ b/chrome/browser/platform_util_linux.cc
@@ -4,8 +4,15 @@
 
 #include "chrome/browser/platform_util.h"
 
+#include <fcntl.h>
+
+#include <string>
+#include <vector>
+
 #include "base/bind.h"
+#include "base/containers/contains.h"
 #include "base/no_destructor.h"
+#include "base/posix/eintr_wrapper.h"
 #include "base/process/kill.h"
 #include "base/process/launch.h"
 #include "base/strings/string_util.h"
@@ -25,6 +32,7 @@
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_proxy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using content::BrowserThread;
@@ -33,11 +41,20 @@
 
 namespace {
 
+const char kMethodListActivatableNames[] = "ListActivatableNames";
+const char kMethodNameHasOwner[] = "NameHasOwner";
+
 const char kFreedesktopFileManagerName[] = "org.freedesktop.FileManager1";
 const char kFreedesktopFileManagerPath[] = "/org/freedesktop/FileManager1";
 
 const char kMethodShowItems[] = "ShowItems";
 
+const char kFreedesktopPortalName[] = "org.freedesktop.portal.Desktop";
+const char kFreedesktopPortalPath[] = "/org/freedesktop/portal/desktop";
+const char kFreedesktopPortalOpenURI[] = "org.freedesktop.portal.OpenURI";
+
+const char kMethodOpenDirectory[] = "OpenDirectory";
+
 class ShowItemHelper : public content::NotificationObserver {
  public:
   static ShowItemHelper& GetInstance() {
@@ -62,7 +79,7 @@
     if (bus_)
       bus_->ShutdownOnDBusThreadAndBlock();
     bus_.reset();
-    filemanager_proxy_ = nullptr;
+    object_proxy_ = nullptr;
   }
 
   void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
@@ -75,8 +92,148 @@
       bus_ = base::MakeRefCounted<dbus::Bus>(bus_options);
     }
 
-    if (!filemanager_proxy_) {
-      filemanager_proxy_ =
+    if (!dbus_proxy_) {
+      dbus_proxy_ = bus_->GetObjectProxy(DBUS_SERVICE_DBUS,
+                                         dbus::ObjectPath(DBUS_PATH_DBUS));
+    }
+
+    if (prefer_filemanager_interface_.has_value()) {
+      if (prefer_filemanager_interface_.value()) {
+        VLOG(1) << "Using FileManager1 to show folder";
+        ShowItemUsingFileManager(profile, full_path);
+      } else {
+        VLOG(1) << "Using OpenURI to show folder";
+        ShowItemUsingFreedesktopPortal(profile, full_path);
+      }
+    } else {
+      CheckFileManagerRunning(profile, full_path);
+    }
+  }
+
+ private:
+  void CheckFileManagerRunning(Profile* profile,
+                               const base::FilePath& full_path) {
+    dbus::MethodCall method_call(DBUS_INTERFACE_DBUS, kMethodNameHasOwner);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(kFreedesktopFileManagerName);
+
+    dbus_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::BindOnce(&ShowItemHelper::CheckFileManagerRunningResponse,
+                       weak_ptr_factory_.GetWeakPtr(), profile, full_path));
+  }
+
+  void CheckFileManagerRunningResponse(Profile* profile,
+                                       const base::FilePath& full_path,
+                                       dbus::Response* response) {
+    if (prefer_filemanager_interface_.has_value()) {
+      ShowItemInFolder(profile, full_path);
+      return;
+    }
+
+    bool is_running = false;
+
+    if (!response) {
+      LOG(ERROR) << "Failed to call " << kMethodNameHasOwner;
+    } else {
+      dbus::MessageReader reader(response);
+      bool owned = false;
+
+      if (!reader.PopBool(&owned)) {
+        LOG(ERROR) << "Failed to read " << kMethodNameHasOwner << " resposne";
+      } else if (owned) {
+        is_running = true;
+      }
+    }
+
+    if (is_running) {
+      prefer_filemanager_interface_ = true;
+      ShowItemInFolder(profile, full_path);
+    } else {
+      CheckFileManagerActivatable(profile, full_path);
+    }
+  }
+
+  void CheckFileManagerActivatable(Profile* profile,
+                                   const base::FilePath& full_path) {
+    dbus::MethodCall method_call(DBUS_INTERFACE_DBUS,
+                                 kMethodListActivatableNames);
+    dbus_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::BindOnce(&ShowItemHelper::CheckFileManagerActivatableResponse,
+                       weak_ptr_factory_.GetWeakPtr(), profile, full_path));
+  }
+
+  void CheckFileManagerActivatableResponse(Profile* profile,
+                                           const base::FilePath& full_path,
+                                           dbus::Response* response) {
+    if (prefer_filemanager_interface_.has_value()) {
+      ShowItemInFolder(profile, full_path);
+      return;
+    }
+
+    bool is_activatable = false;
+
+    if (!response) {
+      LOG(ERROR) << "Failed to call " << kMethodListActivatableNames;
+    } else {
+      dbus::MessageReader reader(response);
+      std::vector<std::string> names;
+      if (!reader.PopArrayOfStrings(&names)) {
+        LOG(ERROR) << "Failed to read " << kMethodListActivatableNames
+                   << " response";
+      } else if (base::Contains(names, kFreedesktopFileManagerName)) {
+        is_activatable = true;
+      }
+    }
+
+    prefer_filemanager_interface_ = is_activatable;
+    ShowItemInFolder(profile, full_path);
+  }
+
+  void ShowItemUsingFreedesktopPortal(Profile* profile,
+                                      const base::FilePath& full_path) {
+    if (!object_proxy_) {
+      object_proxy_ = bus_->GetObjectProxy(
+          kFreedesktopPortalName, dbus::ObjectPath(kFreedesktopPortalPath));
+    }
+
+    base::ScopedFD fd(
+        HANDLE_EINTR(open(full_path.value().c_str(), O_RDONLY | O_CLOEXEC)));
+    if (!fd.is_valid()) {
+      PLOG(ERROR) << "Failed to open " << full_path << " for URI portal";
+
+      // At least open the parent folder, as long as we're not in the unit
+      // tests.
+      if (internal::AreShellOperationsAllowed()) {
+        OpenItem(profile, full_path.DirName(), OPEN_FOLDER,
+                 OpenOperationCallback());
+      }
+
+      return;
+    }
+
+    dbus::MethodCall open_directory_call(kFreedesktopPortalOpenURI,
+                                         kMethodOpenDirectory);
+    dbus::MessageWriter writer(&open_directory_call);
+
+    writer.AppendString("");
+
+    // Note that AppendFileDescriptor() duplicates the fd, so we shouldn't
+    // release ownership of it here.
+    writer.AppendFileDescriptor(fd.get());
+
+    dbus::MessageWriter options_writer(nullptr);
+    writer.OpenArray("{sv}", &options_writer);
+    writer.CloseContainer(&options_writer);
+
+    ShowItemUsingBusCall(&open_directory_call, profile, full_path);
+  }
+
+  void ShowItemUsingFileManager(Profile* profile,
+                                const base::FilePath& full_path) {
+    if (!object_proxy_) {
+      object_proxy_ =
           bus_->GetObjectProxy(kFreedesktopFileManagerName,
                                dbus::ObjectPath(kFreedesktopFileManagerPath));
     }
@@ -89,26 +246,33 @@
         {"file://" + full_path.value()});  // List of file(s) to highlight.
     writer.AppendString({});               // startup-id
 
+    ShowItemUsingBusCall(&show_items_call, profile, full_path);
+  }
+
+  void ShowItemUsingBusCall(dbus::MethodCall* call,
+                            Profile* profile,
+                            const base::FilePath& full_path) {
     // Skip opening the folder during browser tests, to avoid leaving an open
     // file explorer window behind.
     if (!internal::AreShellOperationsAllowed())
       return;
 
-    filemanager_proxy_->CallMethod(
-        &show_items_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+    object_proxy_->CallMethod(
+        call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::BindOnce(&ShowItemHelper::ShowItemInFolderResponse,
-                       weak_ptr_factory_.GetWeakPtr(), profile, full_path));
+                       weak_ptr_factory_.GetWeakPtr(), profile, full_path,
+                       call->GetMember()));
   }
 
- private:
   void ShowItemInFolderResponse(Profile* profile,
                                 const base::FilePath& full_path,
+                                const std::string& method,
                                 dbus::Response* response) {
     if (response)
       return;
 
-    LOG(ERROR) << "Error calling " << kMethodShowItems;
-    // If the FileManager1 call fails, at least open the parent folder.
+    LOG(ERROR) << "Error calling " << method;
+    // If the bus call fails, at least open the parent folder.
     OpenItem(profile, full_path.DirName(), OPEN_FOLDER,
              OpenOperationCallback());
   }
@@ -116,7 +280,10 @@
   content::NotificationRegistrar registrar_;
 
   scoped_refptr<dbus::Bus> bus_;
-  dbus::ObjectProxy* filemanager_proxy_ = nullptr;
+  dbus::ObjectProxy* dbus_proxy_ = nullptr;
+  dbus::ObjectProxy* object_proxy_ = nullptr;
+
+  absl::optional<bool> prefer_filemanager_interface_;
 
   base::WeakPtrFactory<ShowItemHelper> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/plugins/plugin_prefs.cc b/chrome/browser/plugins/plugin_prefs.cc
index 0ad77e71..a84ef6e6 100644
--- a/chrome/browser/plugins/plugin_prefs.cc
+++ b/chrome/browser/plugins/plugin_prefs.cc
@@ -114,7 +114,7 @@
   {  // Scoped update of prefs::kPluginsPluginsList.
     ListPrefUpdate update(prefs_, prefs::kPluginsPluginsList);
     base::ListValue* saved_plugins_list = update.Get();
-    if (saved_plugins_list && !saved_plugins_list->empty()) {
+    if (saved_plugins_list) {
       for (auto& plugin_value : saved_plugins_list->GetList()) {
         base::DictionaryValue* plugin;
         if (!plugin_value.GetAsDictionary(&plugin)) {
diff --git a/chrome/browser/policy/boolean_disabling_policy_handler_unittest.cc b/chrome/browser/policy/boolean_disabling_policy_handler_unittest.cc
index a253c54e..f3b67525 100644
--- a/chrome/browser/policy/boolean_disabling_policy_handler_unittest.cc
+++ b/chrome/browser/policy/boolean_disabling_policy_handler_unittest.cc
@@ -56,9 +56,7 @@
   UpdateProviderPolicy(policy);
   // When policy is false, false should be pushed to prefs.
   EXPECT_TRUE(store_->GetValue(kTestPref, &value_ptr));
-  bool value = true;
-  value_ptr->GetAsBoolean(&value);
-  EXPECT_FALSE(value);
+  EXPECT_FALSE(value_ptr->GetBool());
 }
 
 }  // namespace
diff --git a/chrome/browser/policy/dm_token_utils.cc b/chrome/browser/policy/dm_token_utils.cc
index 3cab2a16..1976e49 100644
--- a/chrome/browser/policy/dm_token_utils.cc
+++ b/chrome/browser/policy/dm_token_utils.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/policy/dm_token_utils.h"
 
 #include "base/no_destructor.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
@@ -65,9 +66,8 @@
   }
 
 #elif !defined(OS_ANDROID)
-  if (dm_token.is_empty() && g_browser_process->browser_policy_connector()
-                                 ->chrome_browser_cloud_management_controller()
-                                 ->IsEnabled()) {
+  if (dm_token.is_empty() &&
+      ChromeBrowserCloudManagementController::IsEnabled()) {
     dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken();
   }
 #endif
diff --git a/chrome/browser/policy/network_prediction_policy_handler.cc b/chrome/browser/policy/network_prediction_policy_handler.cc
index df61d25..e79e8c8 100644
--- a/chrome/browser/policy/network_prediction_policy_handler.cc
+++ b/chrome/browser/policy/network_prediction_policy_handler.cc
@@ -64,16 +64,14 @@
   // Observe deprecated policy setting for compatibility.
   const base::Value* network_prediction_enabled =
       policies.GetValue(key::kDnsPrefetchingEnabled);
-  bool bool_setting;
-  if (network_prediction_enabled &&
-      network_prediction_enabled->GetAsBoolean(&bool_setting)) {
+  if (network_prediction_enabled && network_prediction_enabled->is_bool()) {
     // Some predictive network actions, most notably prefetch, used to be
     // hardwired never to run on cellular network.  In order to retain this
     // behavior (unless explicitly overriden by kNetworkPredictionOptions),
     // kNetworkPredictionEnabled = true is translated to
     // kNetworkPredictionOptions = WIFI_ONLY.
     prefs->SetInteger(prefs::kNetworkPredictionOptions,
-                      bool_setting
+                      network_prediction_enabled->GetBool()
                           ? chrome_browser_net::NETWORK_PREDICTION_WIFI_ONLY
                           : chrome_browser_net::NETWORK_PREDICTION_NEVER);
   }
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
index 2731802..ad4410b 100644
--- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
+++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -2449,7 +2449,9 @@
         {{kSearchPrefetchServicePrefetching,
           {{"stream_responses", "true"}, {"cache_size", "1"}}},
          {{kSearchPrefetchService}, {}},
-         {{features::kBackForwardCache}, {{"enable_same_site", "true"}}}},
+         {{features::kBackForwardCache},
+          {{"enable_same_site", "true"},
+           {"ignore_outstanding_network_request_for_testing", "true"}}}},
         // Allow BackForwardCache for all devices regardless of their memory.
         {features::kBackForwardCacheMemoryControls});
   }
@@ -2458,16 +2460,8 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-#if defined(OS_MAC) && defined(ARCH_CPU_ARM64)
-// https://crbug.com/1223445
-#define MAYBE_BackForwardPrefetchServedFromBFCache \
-  DISABLED_BackForwardPrefetchServedFromBFCache
-#else
-#define MAYBE_BackForwardPrefetchServedFromBFCache \
-  BackForwardPrefetchServedFromBFCache
-#endif
 IN_PROC_BROWSER_TEST_F(SearchPrefetchServiceBFCacheTest,
-                       MAYBE_BackForwardPrefetchServedFromBFCache) {
+                       BackForwardPrefetchServedFromBFCache) {
   // This test prefetches and serves two SRP responses. It then navigates back
   // then forward, the back navigation should not be cached, due to cache limit
   // size of 1, the second navigation should be cached.
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 98e70552..78ab555 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -62,8 +62,8 @@
 #include "chrome/browser/profiles/chrome_version_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_impl.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
 #include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
@@ -808,7 +808,7 @@
   policy::PolicyStatisticsCollector::RegisterPrefs(registry);
   PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
   ProfileAttributesEntry::RegisterLocalStatePrefs(registry);
-  ProfileInfoCache::RegisterPrefs(registry);
+  ProfileAttributesStorage::RegisterPrefs(registry);
   ProfileNetworkContextService::RegisterLocalStatePrefs(registry);
   profiles::RegisterPrefs(registry);
   RegisterScreenshotPrefs(registry);
diff --git a/chrome/browser/printing/cloud_print/privet_notifications.cc b/chrome/browser/printing/cloud_print/privet_notifications.cc
deleted file mode 100644
index ca87788..0000000
--- a/chrome/browser/printing/cloud_print/privet_notifications.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/printing/cloud_print/privet_notifications.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/containers/contains.h"
-#include "base/location.h"
-#include "base/rand_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/local_discovery/service_discovery_shared_client.h"
-#include "chrome/browser/notifications/notification_display_service.h"
-#include "chrome/browser/notifications/notification_handler.h"
-#include "chrome/browser/printing/cloud_print/privet_device_lister_impl.h"
-#include "chrome/browser/printing/cloud_print/privet_http_asynchronous_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_navigator_params.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/grit/generated_resources.h"
-#include "chrome/grit/theme_resources.h"
-#include "components/prefs/pref_service.h"
-#include "components/signin/public/identity_manager/consent_level.h"
-#include "components/signin/public/identity_manager/identity_manager.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "net/net_buildflags.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/page_transition_types.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/message_center/public/cpp/notification.h"
-#include "ui/message_center/public/cpp/notifier_id.h"
-
-#if BUILDFLAG(ENABLE_MDNS)
-#include "chrome/browser/printing/cloud_print/privet_traffic_detector.h"
-#endif
-
-namespace cloud_print {
-
-namespace {
-
-const int kTenMinutesInSeconds = 600;
-const char kPrivetInfoKeyUptime[] = "uptime";
-const char kPrivetNotificationID[] = "privet_notification";
-const char kPrivetNotificationOriginUrl[] = "chrome://devices";
-
-}  // namespace
-
-PrivetNotificationsListener::PrivetNotificationsListener(
-    std::unique_ptr<PrivetHTTPAsynchronousFactory> privet_http_factory,
-    Delegate* delegate)
-    : delegate_(delegate), devices_active_(0) {
-  privet_http_factory_.swap(privet_http_factory);
-}
-
-PrivetNotificationsListener::~PrivetNotificationsListener() {
-}
-
-void PrivetNotificationsListener::DeviceChanged(
-    const std::string& name,
-    const DeviceDescription& description) {
-  auto it = devices_seen_.find(name);
-  if (it != devices_seen_.end()) {
-    if (!description.id.empty() &&  // Device is registered
-        it->second->notification_may_be_active) {
-      it->second->notification_may_be_active = false;
-      devices_active_--;
-      NotifyDeviceRemoved();
-    }
-    return;  // Already saw this device.
-  }
-
-  std::unique_ptr<DeviceContext>& device_context = devices_seen_[name];
-  device_context = std::make_unique<DeviceContext>();
-  device_context->notification_may_be_active = false;
-  device_context->registered = !description.id.empty();
-
-  if (device_context->registered)
-    return;
-
-  device_context->privet_http_resolution =
-      privet_http_factory_->CreatePrivetHTTP(name);
-  device_context->privet_http_resolution->Start(
-      description.address,
-      base::BindOnce(&PrivetNotificationsListener::CreateInfoOperation,
-                     base::Unretained(this)));
-}
-
-void PrivetNotificationsListener::CreateInfoOperation(
-    std::unique_ptr<PrivetHTTPClient> http_client) {
-  // Do nothing if resolution fails.
-  if (!http_client)
-    return;
-
-  std::string name = http_client->GetName();
-  auto it = devices_seen_.find(name);
-  if (it == devices_seen_.end())
-    return;
-
-  DeviceContext* device = it->second.get();
-  device->privet_http.swap(http_client);
-  device->info_operation = device->privet_http->CreateInfoOperation(
-      base::BindOnce(&PrivetNotificationsListener::OnPrivetInfoDone,
-                     base::Unretained(this), device));
-  device->info_operation->Start();
-}
-
-void PrivetNotificationsListener::OnPrivetInfoDone(
-    DeviceContext* device,
-    const base::DictionaryValue* json_value) {
-  int uptime;
-
-  if (!json_value ||
-      !json_value->GetInteger(kPrivetInfoKeyUptime, &uptime) ||
-      uptime > kTenMinutesInSeconds) {
-    return;
-  }
-
-  DCHECK(!device->notification_may_be_active);
-  device->notification_may_be_active = true;
-  devices_active_++;
-  delegate_->PrivetNotify(devices_active_, true);
-}
-
-void PrivetNotificationsListener::DeviceRemoved(const std::string& name) {
-  auto it = devices_seen_.find(name);
-  if (it == devices_seen_.end())
-    return;
-
-  DeviceContext* device = it->second.get();
-  device->info_operation.reset();
-  device->privet_http_resolution.reset();
-  if (!device->notification_may_be_active)
-    return;
-
-  device->notification_may_be_active = false;
-  devices_active_--;
-  NotifyDeviceRemoved();
-}
-
-void PrivetNotificationsListener::DeviceCacheFlushed() {
-  for (const auto& it : devices_seen_) {
-    DeviceContext* device = it.second.get();
-    device->info_operation.reset();
-    device->privet_http_resolution.reset();
-    device->notification_may_be_active = false;
-  }
-
-  devices_active_ = 0;
-  NotifyDeviceRemoved();
-}
-
-void PrivetNotificationsListener::NotifyDeviceRemoved() {
-  if (devices_active_ == 0) {
-    delegate_->PrivetRemoveNotification();
-  } else {
-    delegate_->PrivetNotify(devices_active_, false);
-  }
-}
-
-PrivetNotificationsListener::DeviceContext::DeviceContext() {
-}
-
-PrivetNotificationsListener::DeviceContext::~DeviceContext() {
-}
-
-// static
-constexpr base::TimeDelta PrivetNotificationService::kStartDelay;
-
-PrivetNotificationService::PrivetNotificationService(
-    content::BrowserContext* profile)
-    : profile_(profile) {
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::BindOnce(&PrivetNotificationService::Start, AsWeakPtr()),
-      kStartDelay + base::TimeDelta::FromMilliseconds(base::RandInt(0, 1000)));
-}
-
-PrivetNotificationService::~PrivetNotificationService() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-}
-
-void PrivetNotificationService::DeviceChanged(
-    const std::string& name,
-    const DeviceDescription& description) {
-  privet_notifications_listener_->DeviceChanged(name, description);
-}
-
-void PrivetNotificationService::DeviceRemoved(const std::string& name) {
-  privet_notifications_listener_->DeviceRemoved(name);
-}
-
-void PrivetNotificationService::DeviceCacheFlushed() {
-  privet_notifications_listener_->DeviceCacheFlushed();
-}
-
-// static
-bool PrivetNotificationService::IsEnabled() {
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  return command_line->HasSwitch(switches::kEnableDeviceDiscoveryNotifications);
-}
-
-void PrivetNotificationService::PrivetNotify(int devices_active,
-                                             bool added) {
-  DCHECK_GT(devices_active, 0);
-
-  NotificationDisplayService::GetForProfile(
-      Profile::FromBrowserContext(profile_))
-      ->GetDisplayed(base::BindOnce(&PrivetNotificationService::AddNotification,
-                                    AsWeakPtr(), devices_active, added));
-}
-
-void PrivetNotificationService::AddNotification(
-    int devices_active,
-    bool device_added,
-    std::set<std::string> displayed_notifications,
-    bool supports_synchronization) {
-  // If the UI is already open or a device was removed, we'll update the
-  // existing notification but not add a new one.
-  const bool notification_exists =
-      base::Contains(displayed_notifications, kPrivetNotificationID);
-  if (!notification_exists && !device_added)
-    return;
-
-  message_center::RichNotificationData rich_notification_data;
-  rich_notification_data.buttons.push_back(
-      message_center::ButtonInfo(l10n_util::GetStringUTF16(
-          IDS_LOCAL_DISCOVERY_NOTIFICATION_BUTTON_PRINTER)));
-  rich_notification_data.buttons.push_back(
-      message_center::ButtonInfo(l10n_util::GetStringUTF16(
-          IDS_LOCAL_DISCOVERY_NOTIFICATIONS_DISABLE_BUTTON_LABEL)));
-
-  std::u16string title = l10n_util::GetPluralStringFUTF16(
-      IDS_LOCAL_DISCOVERY_NOTIFICATION_TITLE_PRINTER, devices_active);
-  std::u16string body = l10n_util::GetPluralStringFUTF16(
-      IDS_LOCAL_DISCOVERY_NOTIFICATION_CONTENTS_PRINTER, devices_active);
-  std::u16string product_name =
-      l10n_util::GetStringUTF16(IDS_LOCAL_DISCOVERY_SERVICE_NAME_PRINTER);
-
-  Profile* profile = Profile::FromBrowserContext(profile_);
-  message_center::Notification notification(
-      message_center::NOTIFICATION_TYPE_SIMPLE, kPrivetNotificationID, title,
-      body,
-      ui::ResourceBundle::GetSharedInstance().GetImageNamed(
-          IDR_LOCAL_DISCOVERY_CLOUDPRINT_ICON),
-      product_name, GURL(kPrivetNotificationOriginUrl),
-      message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
-                                 kPrivetNotificationID),
-      rich_notification_data, CreateNotificationDelegate(profile));
-
-  NotificationDisplayService::GetForProfile(
-      Profile::FromBrowserContext(profile_))
-      ->Display(NotificationHandler::Type::TRANSIENT, notification,
-                /*metadata=*/nullptr);
-}
-
-void PrivetNotificationService::PrivetRemoveNotification() {
-  NotificationDisplayService::GetForProfile(
-      Profile::FromBrowserContext(profile_))
-      ->Close(NotificationHandler::Type::TRANSIENT, kPrivetNotificationID);
-}
-
-void PrivetNotificationService::Start() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  auto* identity_manager = IdentityManagerFactory::GetForProfileIfExists(
-      Profile::FromBrowserContext(profile_));
-
-  // Only show notifications for signed-in accounts. https://crbug.com/349098
-  if (!identity_manager ||
-      !identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
-    return;
-  }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-  enable_privet_notification_member_.Init(
-      prefs::kLocalDiscoveryNotificationsEnabled,
-      Profile::FromBrowserContext(profile_)->GetPrefs(),
-      base::BindRepeating(
-          &PrivetNotificationService::OnNotificationsEnabledChanged,
-          base::Unretained(this)));
-  OnNotificationsEnabledChanged();
-}
-
-void PrivetNotificationService::OnNotificationsEnabledChanged() {
-#if BUILDFLAG(ENABLE_MDNS)
-  traffic_detector_.reset();
-
-  if (*enable_privet_notification_member_) {
-    traffic_detector_ = std::make_unique<PrivetTrafficDetector>(
-        profile_, base::BindRepeating(&PrivetNotificationService::StartLister,
-                                      AsWeakPtr()));
-  } else {
-    device_lister_.reset();
-    service_discovery_client_ = nullptr;
-    privet_notifications_listener_.reset();
-  }
-#else
-  if (*enable_privet_notification_member_) {
-    StartLister();
-  } else {
-    device_lister_.reset();
-    service_discovery_client_ = nullptr;
-    privet_notifications_listener_.reset();
-  }
-#endif
-}
-
-void PrivetNotificationService::StartLister() {
-  service_discovery_client_ =
-      local_discovery::ServiceDiscoverySharedClient::GetInstance();
-  device_lister_ = std::make_unique<PrivetDeviceListerImpl>(
-      service_discovery_client_.get(), this);
-  device_lister_->Start();
-  device_lister_->DiscoverNewDevices();
-
-  std::unique_ptr<PrivetHTTPAsynchronousFactory> http_factory(
-      PrivetHTTPAsynchronousFactory::CreateInstance(
-          profile_->GetDefaultStoragePartition()
-              ->GetURLLoaderFactoryForBrowserProcess()));
-
-  privet_notifications_listener_ =
-      std::make_unique<PrivetNotificationsListener>(std::move(http_factory),
-                                                    this);
-}
-
-PrivetNotificationDelegate*
-PrivetNotificationService::CreateNotificationDelegate(Profile* profile) {
-  return new PrivetNotificationDelegate(profile);
-}
-
-PrivetNotificationDelegate::PrivetNotificationDelegate(Profile* profile)
-    : profile_(profile) {}
-
-PrivetNotificationDelegate::~PrivetNotificationDelegate() {
-}
-
-void PrivetNotificationDelegate::Click(
-    const absl::optional<int>& button_index,
-    const absl::optional<std::u16string>& reply) {
-  if (!button_index)
-    return;
-
-  if (*button_index == 0) {
-    OpenTab(GURL(kPrivetNotificationOriginUrl));
-  } else {
-    DCHECK_EQ(1, *button_index);
-    DisableNotifications();
-  }
-  CloseNotification();
-}
-
-void PrivetNotificationDelegate::OpenTab(const GURL& url) {
-  NavigateParams params(profile_, url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
-  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
-  Navigate(&params);
-}
-
-void PrivetNotificationDelegate::DisableNotifications() {
-  profile_->GetPrefs()->SetBoolean(prefs::kLocalDiscoveryNotificationsEnabled,
-                                   false);
-}
-
-void PrivetNotificationDelegate::CloseNotification() {
-  NotificationDisplayService::GetForProfile(profile_)->Close(
-      NotificationHandler::Type::TRANSIENT, kPrivetNotificationID);
-}
-
-}  // namespace cloud_print
diff --git a/chrome/browser/printing/cloud_print/privet_notifications.h b/chrome/browser/printing/cloud_print/privet_notifications.h
deleted file mode 100644
index 9a28cc9..0000000
--- a/chrome/browser/printing/cloud_print/privet_notifications.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_H_
-#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-
-#include "base/time/time.h"
-#include "chrome/browser/printing/cloud_print/privet_device_lister.h"
-#include "chrome/browser/printing/cloud_print/privet_http.h"
-#include "components/keyed_service/core/keyed_service.h"
-#include "components/prefs/pref_member.h"
-#include "net/net_buildflags.h"
-#include "ui/message_center/public/cpp/notification_delegate.h"
-
-class Profile;
-
-namespace content {
-class BrowserContext;
-}
-
-namespace local_discovery {
-class ServiceDiscoverySharedClient;
-}
-
-namespace cloud_print {
-
-class PrivetDeviceLister;
-class PrivetHTTPAsynchronousFactory;
-class PrivetHTTPResolution;
-class PrivetNotificationDelegate;
-struct DeviceDescription;
-
-#if BUILDFLAG(ENABLE_MDNS)
-class PrivetTrafficDetector;
-#endif
-
-// Contains logic related to notifications not tied actually displaying them.
-class PrivetNotificationsListener  {
- public:
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Notify user that printer(s) have been added or removed.
-    virtual void PrivetNotify(int devices_active, bool added) = 0;
-
-    // Notify user that all printers have been removed.
-    virtual void PrivetRemoveNotification() = 0;
-  };
-
-  PrivetNotificationsListener(
-      std::unique_ptr<PrivetHTTPAsynchronousFactory> privet_http_factory,
-      Delegate* delegate);
-  virtual ~PrivetNotificationsListener();
-
-  // These two methods are akin to those of PrivetDeviceLister::Delegate. The
-  // user of PrivetNotificationListener should create a PrivetDeviceLister and
-  // forward device notifications to the PrivetNotificationLister.
-  void DeviceChanged(const std::string& name,
-                     const DeviceDescription& description);
-  void DeviceRemoved(const std::string& name);
-  virtual void DeviceCacheFlushed();
-
- private:
-  struct DeviceContext {
-    DeviceContext();
-    ~DeviceContext();
-
-    bool notification_may_be_active;
-    bool registered;
-    std::unique_ptr<PrivetJSONOperation> info_operation;
-    std::unique_ptr<PrivetHTTPResolution> privet_http_resolution;
-    std::unique_ptr<PrivetHTTPClient> privet_http;
-  };
-
-  using DeviceContextMap =
-      std::map<std::string, std::unique_ptr<DeviceContext>>;
-
-  void CreateInfoOperation(std::unique_ptr<PrivetHTTPClient> http_client);
-  void OnPrivetInfoDone(DeviceContext* device,
-                        const base::DictionaryValue* json_value);
-
-
-  void NotifyDeviceRemoved();
-
-  Delegate* const delegate_;
-  std::unique_ptr<PrivetDeviceLister> device_lister_;
-  std::unique_ptr<PrivetHTTPAsynchronousFactory> privet_http_factory_;
-  DeviceContextMap devices_seen_;
-  int devices_active_;
-};
-
-class PrivetNotificationService
-    : public KeyedService,
-      public PrivetDeviceLister::Delegate,
-      public PrivetNotificationsListener::Delegate,
-      public base::SupportsWeakPtr<PrivetNotificationService> {
- public:
-  // Visible for testing.
-  static constexpr base::TimeDelta kStartDelay =
-      base::TimeDelta::FromSeconds(5);
-
-  explicit PrivetNotificationService(content::BrowserContext* profile);
-  ~PrivetNotificationService() override;
-
-  // PrivetDeviceLister::Delegate implementation:
-  void DeviceChanged(const std::string& name,
-                     const DeviceDescription& description) override;
-  void DeviceRemoved(const std::string& name) override;
-  void DeviceCacheFlushed() override;
-
-  // PrivetNotificationListener::Delegate implementation:
-  void PrivetNotify(int devices_active, bool added) override;
-  void PrivetRemoveNotification() override;
-
-  static bool IsEnabled();
-
-  PrivetDeviceLister* device_lister_for_test() { return device_lister_.get(); }
-  PrivetTrafficDetector* traffic_detector_for_test() {
-    return traffic_detector_.get();
-  }
-
- private:
-  void Start();
-  void OnNotificationsEnabledChanged();
-  void StartLister();
-
-  void AddNotification(int devices_active,
-                       bool device_added,
-                       std::set<std::string> displayed_notifications,
-                       bool supports_synchronization);
-
-  // Virtual for testing. The returned delegate is refcounted.
-  virtual PrivetNotificationDelegate* CreateNotificationDelegate(
-      Profile* profile);
-
-  content::BrowserContext* const profile_;
-  std::unique_ptr<PrivetDeviceLister> device_lister_;
-  scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
-      service_discovery_client_;
-  std::unique_ptr<PrivetNotificationsListener> privet_notifications_listener_;
-  BooleanPrefMember enable_privet_notification_member_;
-
-#if BUILDFLAG(ENABLE_MDNS)
-  std::unique_ptr<PrivetTrafficDetector> traffic_detector_;
-#endif
-};
-
-class PrivetNotificationDelegate : public message_center::NotificationDelegate {
- public:
-  explicit PrivetNotificationDelegate(Profile* profile);
-
-  // NotificationDelegate implementation.
-  void Click(const absl::optional<int>& button_index,
-             const absl::optional<std::u16string>& reply) override;
-
- protected:
-  // Refcounted.
-  ~PrivetNotificationDelegate() override;
-
- private:
-  // Click() response handlers. Virtual for testing.
-  virtual void OpenTab(const GURL& url);
-  virtual void DisableNotifications();
-
-  void CloseNotification();
-
-  Profile* const profile_;
-};
-
-}  // namespace cloud_print
-
-#endif  // CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_H_
diff --git a/chrome/browser/printing/cloud_print/privet_notifications_factory.cc b/chrome/browser/printing/cloud_print/privet_notifications_factory.cc
deleted file mode 100644
index 8f87e34..0000000
--- a/chrome/browser/printing/cloud_print/privet_notifications_factory.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/printing/cloud_print/privet_notifications_factory.h"
-
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/printing/cloud_print/privet_notifications.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-
-namespace cloud_print {
-
-PrivetNotificationServiceFactory*
-PrivetNotificationServiceFactory::GetInstance() {
-  return base::Singleton<PrivetNotificationServiceFactory>::get();
-}
-
-PrivetNotificationServiceFactory::PrivetNotificationServiceFactory()
-    : BrowserContextKeyedServiceFactory(
-        "PrivetNotificationService",
-        BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(IdentityManagerFactory::GetInstance());
-}
-
-PrivetNotificationServiceFactory::~PrivetNotificationServiceFactory() {
-}
-
-KeyedService* PrivetNotificationServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* profile) const {
-  return new PrivetNotificationService(profile);
-}
-
-bool
-PrivetNotificationServiceFactory::ServiceIsCreatedWithBrowserContext() const {
-  return PrivetNotificationService::IsEnabled();
-}
-
-bool PrivetNotificationServiceFactory::ServiceIsNULLWhileTesting() const {
-  return true;
-}
-
-}  // namespace cloud_print
diff --git a/chrome/browser/printing/cloud_print/privet_notifications_factory.h b/chrome/browser/printing/cloud_print/privet_notifications_factory.h
deleted file mode 100644
index c22d5f3..0000000
--- a/chrome/browser/printing/cloud_print/privet_notifications_factory.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_FACTORY_H_
-#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_FACTORY_H_
-
-#include "base/memory/singleton.h"
-#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-
-namespace cloud_print {
-
-class PrivetNotificationServiceFactory
-    : public BrowserContextKeyedServiceFactory {
- public:
-  // Returns singleton instance of PrivetNotificationServiceFactory.
-  static PrivetNotificationServiceFactory* GetInstance();
-
- private:
-  friend struct base::DefaultSingletonTraits<PrivetNotificationServiceFactory>;
-
-  PrivetNotificationServiceFactory();
-  ~PrivetNotificationServiceFactory() override;
-
-  // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
-      content::BrowserContext* profile) const override;
-  bool ServiceIsCreatedWithBrowserContext() const override;
-  bool ServiceIsNULLWhileTesting() const override;
-};
-
-}  // namespace cloud_print
-
-#endif  // CHROME_BROWSER_PRINTING_CLOUD_PRINT_PRIVET_NOTIFICATIONS_FACTORY_H_
diff --git a/chrome/browser/printing/cloud_print/privet_notifications_unittest.cc b/chrome/browser/printing/cloud_print/privet_notifications_unittest.cc
deleted file mode 100644
index 21cb3a24e..0000000
--- a/chrome/browser/printing/cloud_print/privet_notifications_unittest.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/printing/cloud_print/privet_notifications.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/notifications/notification_display_service_tester.h"
-#include "chrome/browser/printing/cloud_print/privet_http_asynchronous_factory.h"
-#include "chrome/browser/printing/cloud_print/privet_http_impl.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/testing_profile_manager.h"
-#include "content/public/test/browser_task_environment.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
-#include "services/network/test/test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::StrictMock;
-
-using ::testing::_;
-using ::testing::SaveArg;
-
-namespace cloud_print {
-
-namespace {
-
-const char kExampleDeviceName[] = "test._privet._tcp.local";
-const char kExampleDeviceHumanName[] = "Test device";
-const char kExampleDeviceDescription[] = "Testing testing";
-const char kExampleDeviceID[] = "__test__id";
-const char kDeviceInfoURL[] = "http://1.2.3.4:8080/privet/info";
-
-const char kInfoResponseUptime20[] = "{\"uptime\": 20}";
-const char kInfoResponseUptime3600[] = "{\"uptime\": 3600}";
-const char kInfoResponseNoUptime[] = "{}";
-
-class MockPrivetNotificationsListenerDeleagate
-    : public PrivetNotificationsListener::Delegate {
- public:
-  MOCK_METHOD2(PrivetNotify, void(int devices_active, bool added));
-  MOCK_METHOD0(PrivetRemoveNotification, void());
-};
-
-class MockPrivetHttpFactory : public PrivetHTTPAsynchronousFactory {
- public:
-  class MockResolution : public PrivetHTTPResolution {
-   public:
-    MockResolution(
-        const std::string& name,
-        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-        : name_(name), url_loader_factory_(url_loader_factory) {}
-
-    ~MockResolution() override {}
-
-    void Start(const net::HostPortPair& address,
-               ResultCallback callback) override {
-      auto privet_http_client = std::make_unique<PrivetHTTPClientImpl>(
-          name_, net::HostPortPair("1.2.3.4", 8080), url_loader_factory_);
-      std::move(callback).Run(std::move(privet_http_client));
-    }
-
-   private:
-    std::string name_;
-    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-  };
-
-  explicit MockPrivetHttpFactory(
-      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
-      : url_loader_factory_(url_loader_factory) {}
-
-  std::unique_ptr<PrivetHTTPResolution> CreatePrivetHTTP(
-      const std::string& name) override {
-    return std::make_unique<MockResolution>(name, url_loader_factory_);
-  }
-
- private:
-  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-};
-
-class PrivetNotificationsListenerTest : public testing::Test {
- public:
-  PrivetNotificationsListenerTest()
-      : test_shared_url_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)) {
-    notification_listener_ = std::make_unique<PrivetNotificationsListener>(
-        std::make_unique<MockPrivetHttpFactory>(
-            test_shared_url_loader_factory_),
-        &mock_delegate_);
-    description_.name = kExampleDeviceHumanName;
-    description_.description = kExampleDeviceDescription;
-  }
-
-  ~PrivetNotificationsListenerTest() override {}
-
-  bool SuccessfulResponseToInfo(const std::string& response) {
-    return test_url_loader_factory_.SimulateResponseForPendingRequest(
-        GURL(kDeviceInfoURL), network::URLLoaderCompletionStatus(net::OK),
-        network::CreateURLResponseHead(net::HTTP_OK), response);
-  }
-
- protected:
-  content::BrowserTaskEnvironment task_environment;
-  network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
-      test_shared_url_loader_factory_;
-  StrictMock<MockPrivetNotificationsListenerDeleagate> mock_delegate_;
-  std::unique_ptr<PrivetNotificationsListener> notification_listener_;
-  DeviceDescription description_;
-};
-
-TEST_F(PrivetNotificationsListenerTest, DisappearReappearTest) {
-  EXPECT_CALL(mock_delegate_, PrivetNotify(1, true));
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(SuccessfulResponseToInfo(kInfoResponseUptime20));
-
-  EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
-  notification_listener_->DeviceRemoved(kExampleDeviceName);
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  description_.id = kExampleDeviceID;
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-}
-
-TEST_F(PrivetNotificationsListenerTest, RegisterTest) {
-  EXPECT_CALL(mock_delegate_, PrivetNotify(1, true));
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(SuccessfulResponseToInfo(kInfoResponseUptime20));
-
-  EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
-  description_.id = kExampleDeviceID;
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-}
-
-TEST_F(PrivetNotificationsListenerTest, RepeatedNotification) {
-  EXPECT_CALL(mock_delegate_, PrivetNotify(1, true));
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(SuccessfulResponseToInfo(kInfoResponseUptime20));
-
-  EXPECT_CALL(mock_delegate_, PrivetNotify(_, _)).Times(0);
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-
-  EXPECT_CALL(mock_delegate_, PrivetRemoveNotification());
-  notification_listener_->DeviceRemoved(kExampleDeviceName);
-
-  EXPECT_CALL(mock_delegate_, PrivetNotify(_, _)).Times(0);
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-
-  EXPECT_CALL(mock_delegate_, PrivetRemoveNotification()).Times(0);
-  notification_listener_->DeviceRemoved(kExampleDeviceName);
-}
-
-TEST_F(PrivetNotificationsListenerTest, HighUptimeTest) {
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(SuccessfulResponseToInfo(kInfoResponseUptime3600));
-  description_.id = kExampleDeviceID;
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-}
-
-TEST_F(PrivetNotificationsListenerTest, HTTPErrorTest) {
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
-      GURL(kDeviceInfoURL), network::URLLoaderCompletionStatus(net::OK),
-      network::CreateURLResponseHead(net::HTTP_NOT_FOUND),
-      /*content=*/""));
-}
-
-TEST_F(PrivetNotificationsListenerTest, DictionaryErrorTest) {
-  notification_listener_->DeviceChanged(kExampleDeviceName, description_);
-  EXPECT_TRUE(SuccessfulResponseToInfo(kInfoResponseNoUptime));
-}
-
-class TestPrivetNotificationService;
-
-class TestPrivetNotificationDelegate : public PrivetNotificationDelegate {
- public:
-  TestPrivetNotificationDelegate(TestPrivetNotificationService* service,
-                                 Profile* profile)
-      : PrivetNotificationDelegate(profile), service_(service) {}
-
- private:
-  // Refcounted.
-  ~TestPrivetNotificationDelegate() override {}
-
-  // PrivetNotificationDelegate:
-  void OpenTab(const GURL& url) override;
-  void DisableNotifications() override;
-
-  TestPrivetNotificationService* const service_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestPrivetNotificationDelegate);
-};
-
-class TestPrivetNotificationService : public PrivetNotificationService {
- public:
-  explicit TestPrivetNotificationService(Profile* profile)
-      : PrivetNotificationService(profile) {}
-  ~TestPrivetNotificationService() override {}
-
-  const GURL& open_tab_url() const { return open_tab_url_; }
-  size_t open_tab_count() const { return open_tab_count_; }
-  size_t disable_notifications_count() const {
-    return disable_notifications_count_;
-  }
-
-  void OpenTab(const GURL& url) {
-    open_tab_url_ = url;
-    ++open_tab_count_;
-  }
-
-  void DisableNotifications() { ++disable_notifications_count_; }
-
- private:
-  // PrivetNotificationService:
-  PrivetNotificationDelegate* CreateNotificationDelegate(
-      Profile* profile) override {
-    return new TestPrivetNotificationDelegate(this, profile);
-  }
-
-  GURL open_tab_url_;
-  size_t open_tab_count_ = 0;
-  size_t disable_notifications_count_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(TestPrivetNotificationService);
-};
-
-void TestPrivetNotificationDelegate::OpenTab(const GURL& url) {
-  service_->OpenTab(url);
-}
-
-void TestPrivetNotificationDelegate::DisableNotifications() {
-  service_->DisableNotifications();
-}
-
-class PrivetNotificationsNotificationTest : public testing::Test {
- public:
-  PrivetNotificationsNotificationTest() {}
-  ~PrivetNotificationsNotificationTest() override {}
-
-  void SetUp() override {
-    testing::Test::SetUp();
-
-    profile_manager_ = std::make_unique<TestingProfileManager>(
-        TestingBrowserProcess::GetGlobal());
-    ASSERT_TRUE(profile_manager_->SetUp());
-    profile_ = profile_manager_->CreateTestingProfile("test-user");
-    display_service_ =
-        std::make_unique<NotificationDisplayServiceTester>(profile_);
-  }
-
-  void TearDown() override {
-    profile_manager_.reset();
-    testing::Test::TearDown();
-  }
-
-  Profile* profile() { return profile_; }
-
-  // The thread bundle must be first so it is destroyed last.
-  content::BrowserTaskEnvironment task_environment_;
-
-  std::unique_ptr<NotificationDisplayServiceTester> display_service_;
-
-  std::unique_ptr<TestingProfileManager> profile_manager_;
-  Profile* profile_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PrivetNotificationsNotificationTest);
-};
-
-TEST_F(PrivetNotificationsNotificationTest, AddToCloudPrint) {
-  TestPrivetNotificationService service(profile());
-  service.PrivetNotify(1 /* devices_active */, true /* added */);
-  // The notification is added asynchronously.
-  base::RunLoop().RunUntilIdle();
-
-  auto notifications = display_service_->GetDisplayedNotificationsForType(
-      NotificationHandler::Type::TRANSIENT);
-  ASSERT_EQ(1U, notifications.size());
-  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
-                                  notifications[0].id(), 0 /* add */,
-                                  absl::nullopt);
-
-  EXPECT_EQ("chrome://devices/", service.open_tab_url().spec());
-  EXPECT_EQ(1U, service.open_tab_count());
-  EXPECT_EQ(0U, service.disable_notifications_count());
-  EXPECT_EQ(0U, display_service_
-                    ->GetDisplayedNotificationsForType(
-                        NotificationHandler::Type::TRANSIENT)
-                    .size());
-}
-
-TEST_F(PrivetNotificationsNotificationTest, DontShowAgain) {
-  TestPrivetNotificationService service(profile());
-  service.PrivetNotify(1 /* devices_active */, true /* added */);
-  // The notification is added asynchronously.
-  base::RunLoop().RunUntilIdle();
-
-  auto notifications = display_service_->GetDisplayedNotificationsForType(
-      NotificationHandler::Type::TRANSIENT);
-  ASSERT_EQ(1U, notifications.size());
-  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
-                                  notifications[0].id(),
-                                  1 /* don't show again */, absl::nullopt);
-
-  EXPECT_EQ("", service.open_tab_url().spec());
-  EXPECT_EQ(0U, service.open_tab_count());
-  EXPECT_EQ(1U, service.disable_notifications_count());
-  EXPECT_EQ(0U, display_service_
-                    ->GetDisplayedNotificationsForType(
-                        NotificationHandler::Type::TRANSIENT)
-                    .size());
-}
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-TEST(PrivetNotificationServiceTest, NoNotificationsInGuestMode) {
-  content::BrowserTaskEnvironment task_environment{
-      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  TestingProfileManager profile_manager(TestingBrowserProcess::GetGlobal());
-  ASSERT_TRUE(profile_manager.SetUp());
-  Profile* profile = profile_manager.CreateGuestProfile();
-
-  TestPrivetNotificationService service(profile);
-  // Wait for delayed initialization.
-  task_environment.FastForwardBy(PrivetNotificationService::kStartDelay * 2);
-
-  // We're not watching for printers.
-  EXPECT_FALSE(service.device_lister_for_test());
-  EXPECT_FALSE(service.traffic_detector_for_test());
-}
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-}  // namespace
-
-}  // namespace cloud_print
diff --git a/chrome/browser/privacy_budget/BUILD.gn b/chrome/browser/privacy_budget/BUILD.gn
index 05d0e9f6..333eb41 100644
--- a/chrome/browser/privacy_budget/BUILD.gn
+++ b/chrome/browser/privacy_budget/BUILD.gn
@@ -11,6 +11,7 @@
     "privacy_budget_prefs.h",
     "privacy_budget_ukm_entry_filter.h",
     "representative_surface_set.h",
+    "surface_set_equivalence.h",
   ]
 
   deps = [
@@ -31,6 +32,7 @@
     "privacy_budget_prefs.cc",
     "privacy_budget_ukm_entry_filter.cc",
     "representative_surface_set.cc",
+    "surface_set_equivalence.cc",
   ]
 
   public_deps = [ ":headers" ]
@@ -58,6 +60,7 @@
     "privacy_budget_metrics_provider_unittest.cc",
     "privacy_budget_ukm_entry_filter_unittest.cc",
     "representative_surface_set_unittest.cc",
+    "surface_set_equivalence_unittest.cc",
   ]
 
   deps = [
diff --git a/chrome/browser/privacy_budget/surface_set_equivalence.cc b/chrome/browser/privacy_budget/surface_set_equivalence.cc
new file mode 100644
index 0000000..c03eb94
--- /dev/null
+++ b/chrome/browser/privacy_budget/surface_set_equivalence.cc
@@ -0,0 +1,102 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/privacy_budget/surface_set_equivalence.h"
+
+#include <iterator>
+#include <set>
+
+#include "base/containers/contains.h"
+#include "chrome/common/privacy_budget/field_trial_param_conversions.h"
+#include "chrome/common/privacy_budget/privacy_budget_features.h"
+
+SurfaceSetEquivalence::EquivalenceClassIdentifierMap
+SurfaceSetEquivalence::DecodeEquivalenceClassSet(
+    base::StringPiece param_value) {
+  EquivalenceClassIdentifierMap representative_map;
+  auto surface_set_set =
+      DecodeIdentifiabilityFieldTrialParam<SurfaceSetEquivalentClassesList>(
+          param_value);
+
+  // A surface must only appear once as a key _or_ as a value in our mapping.
+  // Otherwise the mapping will violate the invariants.
+  std::set<blink::IdentifiableSurface> seen;
+
+  for (const auto& surface_set : surface_set_set) {
+    // A single surface set or an empty one is a no-op. These shouldn't be sent
+    // as a part of a valid configuration, but the code shouldn't get confused
+    // upon seeing one either.
+    if (surface_set.size() <= 1)
+      continue;
+
+    auto first_surface = surface_set.front();
+
+    if (base::Contains(seen, first_surface))
+      continue;
+    seen.insert(first_surface);
+
+    auto representative = RepresentativeSurface(first_surface);
+
+    for (const auto& surface : surface_set) {
+      if (!base::Contains(seen, surface)) {
+        seen.insert(surface);
+        representative_map[surface] = representative;
+      }
+    }
+  }
+
+  return representative_map;
+}
+
+SurfaceSetEquivalence::SurfaceSetEquivalence()
+    : equivalence_map_(DecodeEquivalenceClassSet(
+          features::kIdentifiabilityStudySurfaceEquivalenceClasses.Get())) {}
+
+SurfaceSetEquivalence::~SurfaceSetEquivalence() = default;
+
+RepresentativeSurface SurfaceSetEquivalence::GetRepresentative(
+    blink::IdentifiableSurface surface) const {
+  auto it = equivalence_map_.find(surface);
+  if (it == equivalence_map_.end())
+    return RepresentativeSurface(surface);
+  return RepresentativeSurface(it->second);
+}
+
+RepresentativeSurfaceSet SurfaceSetEquivalence::GetRepresentatives(
+    const IdentifiableSurfaceSet& source) const {
+  // This implementation assumes that IdentifiableSurfaceSet is a flat_set<>.
+  // The most efficient way to construct one is to construct a container and
+  // move it into the flat_set<>.
+  RepresentativeSurfaceSet::container_type container;
+  container.reserve(source.size());
+  for (const auto s : source)
+    container.push_back(GetRepresentative(s));
+  return RepresentativeSurfaceSet(std::move(container));
+}
+
+RepresentativeSurfaceList SurfaceSetEquivalence::GetRepresentatives(
+    const IdentifiableSurfaceList& source) const {
+  RepresentativeSurfaceList result;
+  result.reserve(source.size());
+  std::set<RepresentativeSurface> seen;
+  for (const auto surface : source) {
+    auto representative = GetRepresentative(surface);
+    auto inserted = seen.insert(representative);
+    if (inserted.second)
+      result.push_back(representative);
+  }
+  result.shrink_to_fit();
+  return result;
+}
+
+bool SurfaceSetEquivalence::IsRepresentative(
+    blink::IdentifiableSurface surface) const {
+  return surface == GetRepresentative(surface).value();
+}
+
+bool SurfaceSetEquivalence::IsRepresentative(
+    const IdentifiableSurfaceSet& source) const {
+  return base::ranges::all_of(source,
+                              [this](auto s) { return IsRepresentative(s); });
+}
diff --git a/chrome/browser/privacy_budget/surface_set_equivalence.h b/chrome/browser/privacy_budget/surface_set_equivalence.h
new file mode 100644
index 0000000..94045c0
--- /dev/null
+++ b/chrome/browser/privacy_budget/surface_set_equivalence.h
@@ -0,0 +1,66 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_EQUIVALENCE_H_
+#define CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_EQUIVALENCE_H_
+
+#include "base/containers/flat_map.h"
+#include "base/strings/string_piece_forward.h"
+#include "chrome/browser/privacy_budget/representative_surface_set.h"
+#include "chrome/common/privacy_budget/types.h"
+#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
+
+// Evaluates surface set equivalence.
+//
+// A surface set equivalence class is a set of identifiable surfaces that have
+// a high degree of pairwise correlation within the set. In other words
+// exposure of any surface in the set is equivalent to the exposure of any and
+// all other surfaces in the set.
+//
+// Much like a Union-Find data structure, every equivalence class has
+// a representative surface. The cost of any and all surfaces in the set is the
+// cost of the representative surface.
+class SurfaceSetEquivalence {
+ public:
+  SurfaceSetEquivalence();
+  ~SurfaceSetEquivalence();
+
+  // Determines the representative surface for the equivalence class containing
+  // `surface`. Returns `surface` unchanged if it is not a member of any
+  // equivalence class. Either way all surface inclusion and costing decisions
+  // should be made based on the returned surface.
+  RepresentativeSurface GetRepresentative(
+      blink::IdentifiableSurface surface) const;
+
+  RepresentativeSurfaceSet GetRepresentatives(
+      const IdentifiableSurfaceSet& source) const;
+
+  RepresentativeSurfaceList GetRepresentatives(
+      const IdentifiableSurfaceList& source) const;
+
+  bool IsRepresentative(blink::IdentifiableSurface surface) const;
+
+  bool IsRepresentative(const IdentifiableSurfaceSet& source) const;
+
+ private:
+  using EquivalenceClassIdentifierMap =
+      base::flat_map<blink::IdentifiableSurface, RepresentativeSurface>;
+
+  static EquivalenceClassIdentifierMap DecodeEquivalenceClassSet(
+      base::StringPiece encoded_class_set);
+
+  // Maps an IdentifiableSurface to its corresponding representative surface.
+  //
+  // Invariants:
+  //
+  //   * (s,s) ∉ equivalence_map_.
+  //
+  //   * (s,∙) ∈ equivalence_map_ ⇒  (∙,s) ∉ equivalence_map_.
+  //
+  //   * (∙,s) ∈ equivalence_map_ ⇒  (s,∙) ∉ equivalence_map_.
+  //
+  const EquivalenceClassIdentifierMap equivalence_map_;
+};
+
+#endif  // CHROME_BROWSER_PRIVACY_BUDGET_SURFACE_SET_EQUIVALENCE_H_
diff --git a/chrome/browser/privacy_budget/surface_set_equivalence_unittest.cc b/chrome/browser/privacy_budget/surface_set_equivalence_unittest.cc
new file mode 100644
index 0000000..0c4cfe0
--- /dev/null
+++ b/chrome/browser/privacy_budget/surface_set_equivalence_unittest.cc
@@ -0,0 +1,88 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/privacy_budget/surface_set_equivalence.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/common/privacy_budget/privacy_budget_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+constexpr auto kSurface1 = blink::IdentifiableSurface::FromMetricHash(100);
+constexpr auto kSurface2 = blink::IdentifiableSurface::FromMetricHash(257);
+constexpr auto kSurface3 = blink::IdentifiableSurface::FromMetricHash(300);
+constexpr auto kSurface4 = blink::IdentifiableSurface::FromMetricHash(301);
+
+}  // namespace
+
+TEST(SurfaceSetEquivalenceTest, NoEquivalenceSets) {
+  base::FieldTrialParams params = {
+      {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name, ""}};
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(features::kIdentifiabilityStudy,
+                                              params);
+  SurfaceSetEquivalence equivalence;
+
+  // In the absence of any equivalence sets,
+  // `SurfaceSetEquivalence.GetRepresentative()` is an identity function.
+  EXPECT_EQ(kSurface1, equivalence.GetRepresentative(kSurface1).value());
+
+  // Ditto for `GetRepresentatives()` with the exception that it clones the
+  // input.
+  IdentifiableSurfaceSet surfaces = {kSurface1, kSurface2, kSurface3};
+  EXPECT_EQ(3u, equivalence.GetRepresentatives(surfaces).size());
+}
+
+TEST(SurfaceSetEquivalenceTest, EmptyCollections) {
+  base::FieldTrialParams params = {
+      {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name, ""}};
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(features::kIdentifiabilityStudy,
+                                              params);
+  SurfaceSetEquivalence equivalence;
+
+  EXPECT_TRUE(equivalence.GetRepresentatives(IdentifiableSurfaceSet{}).empty());
+  EXPECT_TRUE(
+      equivalence.GetRepresentatives(IdentifiableSurfaceList{}).empty());
+}
+
+TEST(SurfaceSetEquivalenceTest, SingleEquivalenceSet) {
+  // kSurface1 and kSurface2 are in an equivalence set. kSurface1 is the
+  // representative.
+  base::FieldTrialParams params = {
+      {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name,
+       "100;257"}};
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(features::kIdentifiabilityStudy,
+                                              params);
+  SurfaceSetEquivalence equivalence;
+
+  EXPECT_EQ(kSurface1, equivalence.GetRepresentative(kSurface2).value());
+
+  IdentifiableSurfaceList surface_list = {kSurface1, kSurface2, kSurface3};
+  IdentifiableSurfaceSet surface_set(surface_list.begin(), surface_list.end());
+  RepresentativeSurfaceList expected_surface_list = {
+      RepresentativeSurface(kSurface1), RepresentativeSurface(kSurface3)};
+  RepresentativeSurfaceSet expected_surface_set(expected_surface_list.begin(),
+                                                expected_surface_list.end());
+  EXPECT_EQ(expected_surface_set, equivalence.GetRepresentatives(surface_set));
+  EXPECT_EQ(expected_surface_list,
+            equivalence.GetRepresentatives(surface_list));
+}
+
+TEST(SurfaceSetEquivalenceTest, OverlappingEquivalenceSets) {
+  // kSurface1 and kSurface2 are in an equivalence set. kSurface1 is the
+  // representative.
+  base::FieldTrialParams params = {
+      {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name,
+       "100;257,257;301,300;301"}};
+  base::test::ScopedFeatureList features;
+  features.InitAndEnableFeatureWithParameters(features::kIdentifiabilityStudy,
+                                              params);
+  SurfaceSetEquivalence equivalence;
+
+  EXPECT_EQ(kSurface1, equivalence.GetRepresentative(kSurface2).value());
+  EXPECT_EQ(kSurface3, equivalence.GetRepresentative(kSurface4).value());
+}
diff --git a/chrome/browser/profile_resetter/brandcoded_default_settings.cc b/chrome/browser/profile_resetter/brandcoded_default_settings.cc
index f8531d5..b98f8c3 100644
--- a/chrome/browser/profile_resetter/brandcoded_default_settings.cc
+++ b/chrome/browser/profile_resetter/brandcoded_default_settings.cc
@@ -92,10 +92,9 @@
 
 std::unique_ptr<base::ListValue> BrandcodedDefaultSettings::ExtractList(
     const char* pref_name) const {
-  const base::ListValue* value = NULL;
-  if (master_dictionary_ &&
-      master_dictionary_->GetList(pref_name, &value) &&
-      !value->empty()) {
+  const base::ListValue* value = nullptr;
+  if (master_dictionary_ && master_dictionary_->GetList(pref_name, &value) &&
+      !value->GetList().empty()) {
     return value->CreateDeepCopy();
   }
   return nullptr;
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 54d3fad..7191d56a 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -175,10 +175,6 @@
 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
 #endif
 
-#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
-#include "chrome/browser/printing/cloud_print/privet_notifications_factory.h"
-#endif
-
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
 #include "chrome/browser/sessions/session_service_factory.h"
 #endif
@@ -292,9 +288,6 @@
   ChromeBrowsingDataRemoverDelegateFactory::GetInstance();
   ChromeSigninClientFactory::GetInstance();
   ClientHintsFactory::GetInstance();
-#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
-  cloud_print::PrivetNotificationServiceFactory::GetInstance();
-#endif
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !BUILDFLAG(IS_CHROMEOS_ASH)
   CloudPrintProxyServiceFactory::GetInstance();
 #endif
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
index 7ace7cb..2bbb2661 100644
--- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc
+++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_downloader.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_info_cache_unittest.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc
index e94f0a3..c529e9c23 100644
--- a/chrome/browser/profiles/profile_attributes_entry.cc
+++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -15,8 +15,8 @@
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/signin/signin_util.h"
 #include "chrome/browser/ui/signin/profile_colors_util.h"
@@ -84,6 +84,9 @@
 const char kSigninRequiredKey[] = "signin_required";
 const char kIsAuthErrorKey[] = "is_auth_error";
 
+// Deprecated 7/2021.
+const char kProfileIsGuest[] = "is_guest";
+
 constexpr int kIntegerNotSet = -1;
 
 // Persisted in prefs.
@@ -117,7 +120,6 @@
 const char ProfileAttributesEntry::kAvatarIconKey[] = "avatar_icon";
 const char ProfileAttributesEntry::kBackgroundAppsKey[] = "background_apps";
 const char ProfileAttributesEntry::kProfileIsEphemeral[] = "is_ephemeral";
-const char ProfileAttributesEntry::kProfileIsGuest[] = "is_guest";
 const char ProfileAttributesEntry::kUserNameKey[] = "user_name";
 const char ProfileAttributesEntry::kGAIAIdKey[] = "gaia_id";
 const char ProfileAttributesEntry::kIsConsentedPrimaryAccountKey[] =
@@ -140,12 +142,12 @@
 
 ProfileAttributesEntry::ProfileAttributesEntry() = default;
 
-void ProfileAttributesEntry::Initialize(ProfileInfoCache* cache,
+void ProfileAttributesEntry::Initialize(ProfileAttributesStorage* storage,
                                         const base::FilePath& path,
                                         PrefService* prefs) {
-  DCHECK(!profile_info_cache_);
-  DCHECK(cache);
-  profile_info_cache_ = cache;
+  DCHECK(!profile_attributes_storage_);
+  DCHECK(storage);
+  profile_attributes_storage_ = storage;
 
   DCHECK(profile_path_.empty());
   DCHECK(!path.empty());
@@ -155,8 +157,8 @@
   DCHECK(prefs);
   prefs_ = prefs;
 
-  DCHECK(profile_info_cache_->GetUserDataDir() == profile_path_.DirName());
-  storage_key_ = profile_path_.BaseName().MaybeAsASCII();
+  storage_key_ =
+      profile_attributes_storage_->StorageKeyFromProfilePath(profile_path_);
 
   MigrateObsoleteProfileAttributes();
 
@@ -207,7 +209,7 @@
 
   // The profile local name is a default profile name : Person n.
   std::vector<ProfileAttributesEntry*> entries =
-      profile_info_cache_->GetAllProfilesAttributes();
+      profile_attributes_storage_->GetAllProfilesAttributes();
 
   for (ProfileAttributesEntry* entry : entries) {
     if (entry == this)
@@ -388,7 +390,7 @@
     return nullptr;
 
   base::FilePath image_path = profile_path_.AppendASCII(file_name);
-  return profile_info_cache_->LoadAvatarPictureFromPath(
+  return profile_attributes_storage_->LoadAvatarPictureFromPath(
       profile_path_, storage_key_, image_path);
 }
 
@@ -402,7 +404,7 @@
 }
 
 bool ProfileAttributesEntry::IsGAIAPictureLoaded() const {
-  return profile_info_cache_->IsGAIAPictureLoaded(storage_key_);
+  return profile_attributes_storage_->IsGAIAPictureLoaded(storage_key_);
 }
 
 std::string ProfileAttributesEntry::GetLastDownloadedGAIAPictureUrlWithSize()
@@ -438,10 +440,6 @@
   return GetBool(kProfileIsEphemeral);
 }
 
-bool ProfileAttributesEntry::IsGuest() const {
-  return GetBool(kProfileIsGuest);
-}
-
 bool ProfileAttributesEntry::IsUsingDefaultName() const {
   return GetBool(kIsUsingDefaultNameKey);
 }
@@ -541,7 +539,7 @@
   bool changed = SetString16(kNameKey, name);
   changed |= SetBool(kIsUsingDefaultNameKey, is_default_name);
   if (changed)
-    profile_info_cache_->NotifyIfProfileNamesHaveChanged();
+    profile_attributes_storage_->NotifyIfProfileNamesHaveChanged();
 }
 
 void ProfileAttributesEntry::SetShortcutName(const std::u16string& name) {
@@ -562,12 +560,13 @@
 
   // Send a notification only if the value has really changed.
   if (old_value != is_omitted_)
-    profile_info_cache_->NotifyProfileIsOmittedChanged(GetPath());
+    profile_attributes_storage_->NotifyProfileIsOmittedChanged(GetPath());
 }
 
 void ProfileAttributesEntry::SetSupervisedUserId(const std::string& id) {
   if (SetString(kSupervisedUserId, id))
-    profile_info_cache_->NotifyProfileSupervisedUserIdChanged(GetPath());
+    profile_attributes_storage_->NotifyProfileSupervisedUserIdChanged(
+        GetPath());
 }
 
 void ProfileAttributesEntry::SetBackgroundStatus(bool running_background_apps) {
@@ -576,12 +575,12 @@
 
 void ProfileAttributesEntry::SetGAIAName(const std::u16string& name) {
   if (SetString16(kGAIANameKey, name))
-    profile_info_cache_->NotifyIfProfileNamesHaveChanged();
+    profile_attributes_storage_->NotifyIfProfileNamesHaveChanged();
 }
 
 void ProfileAttributesEntry::SetGAIAGivenName(const std::u16string& name) {
   if (SetString16(kGAIAGivenNameKey, name))
-    profile_info_cache_->NotifyIfProfileNamesHaveChanged();
+    profile_attributes_storage_->NotifyIfProfileNamesHaveChanged();
 }
 
 void ProfileAttributesEntry::SetGAIAPicture(
@@ -595,8 +594,8 @@
   if (image.IsEmpty()) {
     // Delete the old bitmap from disk.
     base::FilePath image_path = profile_path_.AppendASCII(old_file_name);
-    profile_info_cache_->DeleteGAIAImageAtPath(profile_path_, storage_key_,
-                                               image_path);
+    profile_attributes_storage_->DeleteGAIAImageAtPath(
+        profile_path_, storage_key_, image_path);
   } else {
     // Save the new bitmap to disk.
     new_file_name =
@@ -604,18 +603,18 @@
             ? base::FilePath(profiles::kGAIAPictureFileName).MaybeAsASCII()
             : old_file_name;
     base::FilePath image_path = profile_path_.AppendASCII(new_file_name);
-    profile_info_cache_->SaveGAIAImageAtPath(profile_path_, storage_key_, image,
-                                             image_path, image_url_with_size);
+    profile_attributes_storage_->SaveGAIAImageAtPath(
+        profile_path_, storage_key_, image, image_path, image_url_with_size);
   }
 
   SetString(kGAIAPictureFileNameKey, new_file_name);
-  profile_info_cache_->NotifyOnProfileAvatarChanged(profile_path_);
+  profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path_);
 }
 
 void ProfileAttributesEntry::SetIsUsingGAIAPicture(bool value) {
   SetBool(kUseGAIAPictureKey, value);
   // TODO(alexilin): send notification only if the value has changed.
-  profile_info_cache_->NotifyOnProfileAvatarChanged(profile_path_);
+  profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path_);
 }
 
 void ProfileAttributesEntry::SetLastDownloadedGAIAPictureUrlWithSize(
@@ -634,7 +633,7 @@
   if (GetBool(kForceSigninProfileLockedKey) == is_lock)
     return;
   SetBool(kForceSigninProfileLockedKey, is_lock);
-  profile_info_cache_->NotifyIsSigninRequiredChanged(GetPath());
+  profile_attributes_storage_->NotifyIsSigninRequiredChanged(GetPath());
 }
 
 void ProfileAttributesEntry::RecordAccountMetrics() const {
@@ -651,13 +650,9 @@
   SetBool(kProfileIsEphemeral, value);
 }
 
-void ProfileAttributesEntry::SetIsGuest(bool value) {
-  SetBool(kProfileIsGuest, value);
-}
-
 void ProfileAttributesEntry::SetIsUsingDefaultName(bool value) {
   if (SetBool(kIsUsingDefaultNameKey, value))
-    profile_info_cache_->NotifyIfProfileNamesHaveChanged();
+    profile_attributes_storage_->NotifyIfProfileNamesHaveChanged();
 }
 
 void ProfileAttributesEntry::SetIsUsingDefaultAvatar(bool value) {
@@ -679,12 +674,12 @@
   SetString(kAvatarIconKey, default_avatar_icon_url);
 
   base::FilePath profile_path = GetPath();
-  if (!profile_info_cache_->GetDisableAvatarDownloadForTesting()) {
-    profile_info_cache_->DownloadHighResAvatarIfNeeded(icon_index,
-                                                       profile_path);
+  if (!profile_attributes_storage_->GetDisableAvatarDownloadForTesting()) {
+    profile_attributes_storage_->DownloadHighResAvatarIfNeeded(icon_index,
+                                                               profile_path);
   }
 
-  profile_info_cache_->NotifyOnProfileAvatarChanged(profile_path);
+  profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path);
 }
 
 void ProfileAttributesEntry::SetProfileThemeColors(
@@ -704,15 +699,15 @@
   }
 
   if (changed) {
-    profile_info_cache_->NotifyProfileThemeColorsChanged(GetPath());
+    profile_attributes_storage_->NotifyProfileThemeColorsChanged(GetPath());
     if (GetAvatarIconIndex() == profiles::GetPlaceholderAvatarIndex())
-      profile_info_cache_->NotifyOnProfileAvatarChanged(GetPath());
+      profile_attributes_storage_->NotifyOnProfileAvatarChanged(GetPath());
   }
 }
 
 void ProfileAttributesEntry::SetHostedDomain(std::string hosted_domain) {
   if (SetString(kHostedDomain, hosted_domain))
-    profile_info_cache_->NotifyProfileHostedDomainChanged(GetPath());
+    profile_attributes_storage_->NotifyProfileHostedDomainChanged(GetPath());
 }
 
 void ProfileAttributesEntry::SetAuthInfo(const std::string& gaia_id,
@@ -734,7 +729,7 @@
   new_data.SetBoolKey(kIsConsentedPrimaryAccountKey,
                       is_consented_primary_account);
   SetEntryData(std::move(new_data));
-  profile_info_cache_->NotifyProfileAuthInfoChanged(profile_path_);
+  profile_attributes_storage_->NotifyProfileAuthInfoChanged(profile_path_);
 }
 
 void ProfileAttributesEntry::AddAccountName(const std::string& name) {
@@ -788,8 +783,8 @@
       profiles::GetDefaultAvatarIconFileNameAtIndex(avatar_index);
   const base::FilePath image_path =
       profiles::GetPathOfHighResAvatarAtIndex(avatar_index);
-  return profile_info_cache_->LoadAvatarPictureFromPath(GetPath(), key,
-                                                        image_path);
+  return profile_attributes_storage_->LoadAvatarPictureFromPath(GetPath(), key,
+                                                                image_path);
 }
 
 gfx::Image ProfileAttributesEntry::GetPlaceholderAvatarIcon(int size) const {
@@ -843,17 +838,17 @@
 }
 
 const base::Value* ProfileAttributesEntry::GetEntryData() const {
-  const base::DictionaryValue* cache =
-      prefs_->GetDictionary(prefs::kProfileInfoCache);
-  return cache->FindKeyOfType(storage_key_, base::Value::Type::DICTIONARY);
+  const base::DictionaryValue* attributes =
+      prefs_->GetDictionary(prefs::kProfileAttributes);
+  return attributes->FindKeyOfType(storage_key_, base::Value::Type::DICTIONARY);
 }
 
 void ProfileAttributesEntry::SetEntryData(base::Value data) {
   DCHECK(data.is_dict());
 
-  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
-  base::DictionaryValue* cache = update.Get();
-  cache->SetKey(storage_key_, std::move(data));
+  DictionaryPrefUpdate update(prefs_, prefs::kProfileAttributes);
+  base::DictionaryValue* attributes = update.Get();
+  attributes->SetKey(storage_key_, std::move(data));
 }
 
 const base::Value* ProfileAttributesEntry::GetValue(const char* key) const {
@@ -1010,6 +1005,9 @@
   // Added 6/2021.
   ClearValue(kSigninRequiredKey);
   ClearValue(kIsAuthErrorKey);
+
+  // Added 7/2021.
+  ClearValue(kProfileIsGuest);
 }
 
 void ProfileAttributesEntry::SetIsOmittedInternal(bool is_omitted) {
diff --git a/chrome/browser/profiles/profile_attributes_entry.h b/chrome/browser/profiles/profile_attributes_entry.h
index fc471d2..8676e29 100644
--- a/chrome/browser/profiles/profile_attributes_entry.h
+++ b/chrome/browser/profiles/profile_attributes_entry.h
@@ -21,7 +21,7 @@
 
 class PrefRegistrySimple;
 class PrefService;
-class ProfileInfoCache;
+class ProfileAttributesStorage;
 struct ProfileThemeColors;
 
 enum class SigninState {
@@ -119,10 +119,6 @@
   std::string GetSupervisedUserId() const;
   // Returns true if the profile is an ephemeral profile.
   bool IsEphemeral() const;
-  // Returns true if the profile is a Guest profile.
-  // Only ephemeral Guest profiles are stored in profile attributes and
-  // therefore a Guest profile here is always ephemeral as well.
-  bool IsGuest() const;
   // Returns true if the profile is using a default name, typically of the
   // format "Person %d".
   bool IsUsingDefaultName() const;
@@ -176,7 +172,6 @@
   // responsibility of the caller to make sure that the entry is set as
   // non-ephemeral only if prefs::kForceEphemeralProfiles is false.
   void SetIsEphemeral(bool value);
-  void SetIsGuest(bool value);
   // TODO(msalama): Remove this function.
   void SetIsUsingDefaultName(bool value);
   void SetIsUsingDefaultAvatar(bool value);
@@ -215,7 +210,6 @@
   static const char kAvatarIconKey[];
   static const char kBackgroundAppsKey[];
   static const char kProfileIsEphemeral[];
-  static const char kProfileIsGuest[];
   static const char kUserNameKey[];
   static const char kGAIAIdKey[];
   static const char kIsConsentedPrimaryAccountKey[];
@@ -227,7 +221,6 @@
 
  private:
   friend class ProfileAttributesStorage;
-  friend class ProfileInfoCache;
   friend class ProfileThemeUpdateServiceBrowserTest;
   FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest,
                            EntryInternalAccessors);
@@ -237,7 +230,7 @@
 
   // Initializes the current entry instance. The callers must subsequently call
   // InitializeLastNameToDisplay() for this entry.
-  void Initialize(ProfileInfoCache* cache,
+  void Initialize(ProfileAttributesStorage* storage,
                   const base::FilePath& path,
                   PrefService* prefs);
 
@@ -329,7 +322,7 @@
   // notifications.
   void SetIsOmittedInternal(bool is_omitted);
 
-  ProfileInfoCache* profile_info_cache_ = nullptr;
+  ProfileAttributesStorage* profile_attributes_storage_ = nullptr;
   PrefService* prefs_ = nullptr;
   base::FilePath profile_path_;
   std::string storage_key_;
diff --git a/chrome/browser/profiles/profile_attributes_init_params.h b/chrome/browser/profiles/profile_attributes_init_params.h
index 16f9323..448dc49b 100644
--- a/chrome/browser/profiles/profile_attributes_init_params.h
+++ b/chrome/browser/profiles/profile_attributes_init_params.h
@@ -45,9 +45,6 @@
   // `AccountId` of the user of the profile. Empty if the profile doesn't have
   // any associated `user_manager::User`.
   AccountId account_id{EmptyAccountId()};
-  // TODO(https://crbug.com/1225156): Remove this.
-  // Whether the profile is guest.
-  bool is_guest = false;
   // Whether the profile is ephemeral. Ephemeral profiles are cleaned up on
   // every Chrome restart.
   bool is_ephemeral = false;
diff --git a/chrome/browser/profiles/profile_attributes_storage.cc b/chrome/browser/profiles/profile_attributes_storage.cc
index 82b6e4d1..1698fc0 100644
--- a/chrome/browser/profiles/profile_attributes_storage.cc
+++ b/chrome/browser/profiles/profile_attributes_storage.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 
 #include <algorithm>
-#include <memory>
 #include <unordered_set>
 #include <utility>
 
@@ -15,19 +14,28 @@
 #include "base/files/file_util.h"
 #include "base/i18n/number_formatting.h"
 #include "base/i18n/string_compare.h"
+#include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
 #include "base/task_runner_util.h"
 #include "base/threading/scoped_blocking_call.h"
+#include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile_avatar_downloader.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_metrics.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/account_id/account_id.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/scoped_user_pref_update.h"
 #include "components/profile_metrics/state.h"
+#include "components/signin/public/base/persistent_repeating_timer.h"
+#include "components/signin/public/base/signin_pref_names.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "third_party/icu/source/i18n/unicode/coll.h"
@@ -72,6 +80,12 @@
                         // used.
 };
 
+const char kProfileCountLastUpdatePref[] = "profile.profile_counts_reported";
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+const char kLegacyProfileNameMigrated[] = "legacy.profile.name.migrated";
+bool g_migration_enabled_for_testing = false;
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+
 // Reads a PNG from disk and decodes it. If the bitmap was successfully read
 // from disk then this will return the bitmap image, otherwise it will return
 // an empty gfx::Image.
@@ -172,7 +186,7 @@
 
   int active_count = std::count_if(
       entries.begin(), entries.end(), [](ProfileAttributesEntry* entry) {
-        return ProfileMetrics::IsProfileActive(entry) && !entry->IsGuest();
+        return ProfileMetrics::IsProfileActive(entry);
       });
 
   if (active_count <= 1)
@@ -216,8 +230,8 @@
   if (entry->IsChild())
     return profile_metrics::UnconsentedPrimaryAccountType::kChild;
   // TODO(crbug.com/1060113): Replace this check by
-  // !entry->GetHostedDomain().has_value() in M84 (once the cache gets
-  // reasonably well populated).
+  // !entry->GetHostedDomain().has_value() in M84 (once the attributes storage
+  // gets reasonably well populated).
   if (policy::BrowserPolicyConnector::IsNonEnterpriseUser(
           base::UTF16ToUTF8(entry->GetUserName()))) {
     return profile_metrics::UnconsentedPrimaryAccountType::kConsumer;
@@ -243,24 +257,196 @@
 
 }  // namespace
 
-ProfileAttributesStorage::ProfileAttributesStorage(PrefService* prefs)
+ProfileAttributesStorage::ProfileAttributesStorage(
+    PrefService* prefs,
+    const base::FilePath& user_data_dir)
     : prefs_(prefs),
       file_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {}
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
+      user_data_dir_(user_data_dir) {
+  // Populate the attributes storage.
+  DictionaryPrefUpdate update(prefs_, prefs::kProfileAttributes);
+  base::DictionaryValue* attributes = update.Get();
+  for (auto kv : attributes->DictItems()) {
+    base::Value& info = kv.second;
+    std::string* name = info.FindStringKey(ProfileAttributesEntry::kNameKey);
 
-ProfileAttributesStorage::~ProfileAttributesStorage() {
+    absl::optional<bool> using_default_name =
+        info.FindBoolKey(ProfileAttributesEntry::kIsUsingDefaultNameKey);
+    if (!using_default_name.has_value()) {
+      // If the preference hasn't been set, and the name is default, assume
+      // that the user hasn't done this on purpose.
+      // |include_check_for_legacy_profile_name| is true as this is an old
+      // pre-existing profile and might have a legacy default profile name.
+      using_default_name = IsDefaultProfileName(
+          name ? base::UTF8ToUTF16(*name) : std::u16string(),
+          /*include_check_for_legacy_profile_name=*/true);
+      info.SetBoolKey(ProfileAttributesEntry::kIsUsingDefaultNameKey,
+                      using_default_name.value());
+    }
+
+    // For profiles that don't have the "using default avatar" state set yet,
+    // assume it's the same as the "using default name" state.
+    if (!info.FindBoolKey(ProfileAttributesEntry::kIsUsingDefaultAvatarKey)) {
+      info.SetBoolKey(ProfileAttributesEntry::kIsUsingDefaultAvatarKey,
+                      using_default_name.value());
+    }
+
+    // `info` may become invalid after this call.
+    // Profiles loaded from disk can never be omitted.
+    InitEntryWithKey(kv.first, /*is_omitted=*/false);
+  }
+
+  // A profile name can depend on other profile names. Do an additional pass to
+  // update last used profile names once all profiles are initialized.
+  for (ProfileAttributesEntry* entry : GetAllProfilesAttributes()) {
+    entry->InitializeLastNameToDisplay();
+  }
+
+  // If needed, start downloading the high-res avatars and migrate any legacy
+  // profile names.
+  if (!disable_avatar_download_for_testing_)
+    DownloadAvatars();
+
+#if !defined(OS_ANDROID)
+  LoadGAIAPictureIfNeeded();
+#endif
+
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+  bool migrate_legacy_profile_names =
+      (!prefs_->GetBoolean(kLegacyProfileNameMigrated) ||
+       g_migration_enabled_for_testing);
+  if (migrate_legacy_profile_names) {
+    MigrateLegacyProfileNamesAndRecomputeIfNeeded();
+    prefs_->SetBoolean(kLegacyProfileNameMigrated, true);
+  }
+
+  repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
+      prefs_, kProfileCountLastUpdatePref, base::TimeDelta::FromHours(24),
+      base::BindRepeating(&ProfileMetrics::LogNumberOfProfiles, this));
+  repeating_timer_->Start();
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+}
+
+ProfileAttributesStorage::~ProfileAttributesStorage() = default;
+
+// static
+void ProfileAttributesStorage::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterDictionaryPref(prefs::kProfileAttributes);
+  registry->RegisterTimePref(kProfileCountLastUpdatePref, base::Time());
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+  registry->RegisterBooleanPref(kLegacyProfileNameMigrated, false);
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+}
+
+void ProfileAttributesStorage::AddProfile(ProfileAttributesInitParams params) {
+  std::string key = StorageKeyFromProfilePath(params.profile_path);
+  DictionaryPrefUpdate update(prefs_, prefs::kProfileAttributes);
+  base::DictionaryValue* attributes = update.Get();
+
+  base::Value info(base::Value::Type::DICTIONARY);
+  info.SetStringKey(ProfileAttributesEntry::kNameKey, params.profile_name);
+  info.SetStringKey(ProfileAttributesEntry::kGAIAIdKey, params.gaia_id);
+  info.SetStringKey(ProfileAttributesEntry::kUserNameKey, params.user_name);
+  DCHECK(!params.is_consented_primary_account || !params.gaia_id.empty() ||
+         !params.user_name.empty());
+  info.SetBoolKey(ProfileAttributesEntry::kIsConsentedPrimaryAccountKey,
+                  params.is_consented_primary_account);
+  info.SetStringKey(ProfileAttributesEntry::kAvatarIconKey,
+                    profiles::GetDefaultAvatarIconUrl(params.icon_index));
+  // Default value for whether background apps are running is false.
+  info.SetBoolKey(ProfileAttributesEntry::kBackgroundAppsKey, false);
+  info.SetStringKey(ProfileAttributesEntry::kSupervisedUserId,
+                    params.supervised_user_id);
+  info.SetBoolKey(ProfileAttributesEntry::kProfileIsEphemeral,
+                  params.is_ephemeral);
+  // Either the user has provided a name manually on purpose, and in this case
+  // we should not check for legacy profile names or this a new profile but then
+  // it is not a legacy name, so we dont need to check for legacy names.
+  info.SetBoolKey(
+      ProfileAttributesEntry::kIsUsingDefaultNameKey,
+      IsDefaultProfileName(params.profile_name,
+                           /*include_check_for_legacy_profile_name*/ false));
+  // Assume newly created profiles use a default avatar.
+  info.SetBoolKey(ProfileAttributesEntry::kIsUsingDefaultAvatarKey, true);
+  if (params.account_id.HasAccountIdKey())
+    info.SetStringKey(ProfileAttributesEntry::kAccountIdKey,
+                      params.account_id.GetAccountIdKey());
+  info.SetBoolKey(prefs::kSignedInWithCredentialProvider,
+                  params.is_signed_in_with_credential_provider);
+  attributes->SetKey(key, std::move(info));
+
+  ProfileAttributesEntry* entry = InitEntryWithKey(key, params.is_omitted);
+  entry->InitializeLastNameToDisplay();
+
+  // `OnProfileAdded()` must be the first observer method being called right
+  // after a new profile is added to the storage.
+  for (auto& observer : observer_list_)
+    observer.OnProfileAdded(params.profile_path);
+
+  if (!disable_avatar_download_for_testing_)
+    DownloadHighResAvatarIfNeeded(params.icon_index, params.profile_path);
+
+  NotifyIfProfileNamesHaveChanged();
+}
+
+void ProfileAttributesStorage::RemoveProfileByAccountId(
+    const AccountId& account_id) {
+  for (ProfileAttributesEntry* entry : GetAllProfilesAttributes()) {
+    bool account_id_keys_match =
+        account_id.HasAccountIdKey() &&
+        account_id.GetAccountIdKey() == entry->GetAccountIdKey();
+    bool gaia_ids_match = !entry->GetGAIAId().empty() &&
+                          account_id.GetGaiaId() == entry->GetGAIAId();
+    bool user_names_match =
+        !entry->GetUserName().empty() &&
+        account_id.GetUserEmail() == base::UTF16ToUTF8(entry->GetUserName());
+    if (account_id_keys_match || gaia_ids_match || user_names_match) {
+      RemoveProfile(entry->GetPath());
+      return;
+    }
+  }
+  LOG(ERROR) << "Failed to remove profile.info_cache entry for account type "
+             << static_cast<int>(account_id.GetAccountType())
+             << ": matching entry not found.";
+}
+
+void ProfileAttributesStorage::RemoveProfile(
+    const base::FilePath& profile_path) {
+  ProfileAttributesEntry* entry = GetProfileAttributesWithPath(profile_path);
+  if (!entry) {
+    NOTREACHED();
+    return;
+  }
+
+  std::u16string name = entry->GetName();
+
+  for (auto& observer : observer_list_)
+    observer.OnProfileWillBeRemoved(profile_path);
+
+  DictionaryPrefUpdate update(prefs_, prefs::kProfileAttributes);
+  base::DictionaryValue* attributes = update.Get();
+  std::string key = StorageKeyFromProfilePath(profile_path);
+  attributes->Remove(key, nullptr);
+  profile_attributes_entries_.erase(profile_path.value());
+
+  // `OnProfileWasRemoved()` must be the first observer method being called
+  // right after a profile was removed from the storage.
+  for (auto& observer : observer_list_) {
+    observer.OnProfileWasRemoved(profile_path, name);
+  }
+
+  NotifyIfProfileNamesHaveChanged();
 }
 
 std::vector<ProfileAttributesEntry*>
-ProfileAttributesStorage::GetAllProfilesAttributes(
-    bool include_guest_profile) const {
+ProfileAttributesStorage::GetAllProfilesAttributes() const {
   std::vector<ProfileAttributesEntry*> ret;
   for (auto& path_and_entry : profile_attributes_entries_) {
     ProfileAttributesEntry* entry = &path_and_entry.second;
     DCHECK(entry);
-    if (!entry->IsGuest() || include_guest_profile)
-      ret.push_back(entry);
+    ret.push_back(entry);
   }
   return ret;
 }
@@ -268,8 +454,7 @@
 std::vector<ProfileAttributesEntry*>
 ProfileAttributesStorage::GetAllProfilesAttributesSorted(
     bool use_local_profile_name) const {
-  std::vector<ProfileAttributesEntry*> ret =
-      GetAllProfilesAttributes(/*include_guest_profile=*/false);
+  std::vector<ProfileAttributesEntry*> ret = GetAllProfilesAttributes();
   // Do not allocate the collator and sort if it is not necessary.
   if (ret.size() < 2)
     return ret;
@@ -307,16 +492,8 @@
   return &entry_iter->second;
 }
 
-size_t ProfileAttributesStorage::GetNumberOfProfiles(
-    bool include_guest_profile) const {
-  // Ephemeral Guest profile is registered in profile attributes storage,
-  // because if Chrome crashes we need the registry to find and delete it.
-  // But it should not be counted as a regular profile.
-  return std::count_if(
-      profile_attributes_entries_.begin(), profile_attributes_entries_.end(),
-      [include_guest_profile](const auto& key_value) {
-        return !key_value.second.IsGuest() || include_guest_profile;
-      });
+size_t ProfileAttributesStorage::GetNumberOfProfiles() const {
+  return profile_attributes_entries_.size();
 }
 
 std::u16string ProfileAttributesStorage::ChooseNameForNewProfile(
@@ -347,8 +524,7 @@
 
     // Loop through previously named profiles to ensure we're not duplicating.
     std::vector<ProfileAttributesEntry*> entries =
-        const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes(
-            /*include_guest_profile=*/false);
+        const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes();
 
     if (std::none_of(entries.begin(), entries.end(),
                      [name](ProfileAttributesEntry* entry) {
@@ -395,8 +571,7 @@
   std::unordered_set<size_t> used_icon_indices;
 
   std::vector<ProfileAttributesEntry*> entries =
-      const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes(
-          /*include_guest_profile=*/false);
+      const_cast<ProfileAttributesStorage*>(this)->GetAllProfilesAttributes();
   for (const ProfileAttributesEntry* entry : entries)
     used_icon_indices.insert(entry->GetAvatarIconIndex());
 
@@ -484,8 +659,7 @@
 #endif
 
 void ProfileAttributesStorage::RecordProfilesState() {
-  std::vector<ProfileAttributesEntry*> entries =
-      GetAllProfilesAttributes(/*include_guest_profile=*/false);
+  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
   if (entries.size() == 0)
     return;
 
@@ -577,6 +751,18 @@
     observer.OnProfileHighResAvatarLoaded(profile_path);
 }
 
+std::string ProfileAttributesStorage::StorageKeyFromProfilePath(
+    const base::FilePath& profile_path) const {
+  DCHECK(user_data_dir_ == profile_path.DirName());
+  return profile_path.BaseName().MaybeAsASCII();
+}
+
+void ProfileAttributesStorage::DisableProfileMetricsForTesting() {
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+  repeating_timer_.reset();
+#endif
+}
+
 void ProfileAttributesStorage::DownloadHighResAvatarIfNeeded(
     size_t icon_index,
     const base::FilePath& profile_path) {
@@ -660,6 +846,82 @@
   }
 }
 
+ProfileAttributesEntry* ProfileAttributesStorage::InitEntryWithKey(
+    const std::string& key,
+    bool is_omitted) {
+  base::FilePath path = user_data_dir_.AppendASCII(key);
+  DCHECK(!base::Contains(profile_attributes_entries_, path.value()));
+  ProfileAttributesEntry* new_entry =
+      &profile_attributes_entries_[path.value()];
+  new_entry->Initialize(this, path, prefs_);
+  new_entry->SetIsOmittedInternal(is_omitted);
+  return new_entry;
+}
+
+void ProfileAttributesStorage::DownloadAvatars() {
+#if !defined(OS_ANDROID)
+  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
+  for (ProfileAttributesEntry* entry : entries) {
+    DownloadHighResAvatarIfNeeded(entry->GetAvatarIconIndex(),
+                                  entry->GetPath());
+  }
+#endif
+}
+
+#if !defined(OS_ANDROID)
+void ProfileAttributesStorage::LoadGAIAPictureIfNeeded() {
+  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
+  for (ProfileAttributesEntry* entry : entries) {
+    if (entry->GetSigninState() == SigninState::kNotSignedIn)
+      continue;
+
+    bool is_using_GAIA_picture =
+        entry->GetBool(ProfileAttributesEntry::kUseGAIAPictureKey);
+    bool is_using_default_avatar = entry->IsUsingDefaultAvatar();
+    // Load from disk into memory GAIA picture if it exists.
+    if (is_using_GAIA_picture || is_using_default_avatar)
+      entry->GetGAIAPicture();
+  }
+}
+#endif
+
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+void ProfileAttributesStorage::MigrateLegacyProfileNamesAndRecomputeIfNeeded() {
+  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
+  for (size_t i = 0; i < entries.size(); i++) {
+    std::u16string profile_name = entries[i]->GetLocalProfileName();
+    if (!entries[i]->IsUsingDefaultName())
+      continue;
+
+    // Migrate any legacy profile names ("First user", "Default Profile",
+    // "Saratoga", ...) to new style default names Person %n ("Person 1").
+    if (!IsDefaultProfileName(
+            profile_name, /*include_check_for_legacy_profile_name=*/false)) {
+      entries[i]->SetLocalProfileName(
+          ChooseNameForNewProfile(entries[i]->GetAvatarIconIndex()),
+          /*is_default_name=*/true);
+      continue;
+    }
+
+    // Current profile name is Person %n.
+    // Rename duplicate default profile names, e.g.: Person 1, Person 1 to
+    // Person 1, Person 2.
+    for (size_t j = i + 1; j < entries.size(); j++) {
+      if (profile_name == entries[j]->GetLocalProfileName()) {
+        entries[j]->SetLocalProfileName(
+            ChooseNameForNewProfile(entries[j]->GetAvatarIconIndex()),
+            /*is_default_name=*/true);
+      }
+    }
+  }
+}
+
+// static
+void ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(bool value) {
+  g_migration_enabled_for_testing = value;
+}
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+
 void ProfileAttributesStorage::OnAvatarPictureLoaded(
     const base::FilePath& profile_path,
     const std::string& key,
diff --git a/chrome/browser/profiles/profile_attributes_storage.h b/chrome/browser/profiles/profile_attributes_storage.h
index 18afa73..05055bf 100644
--- a/chrome/browser/profiles/profile_attributes_storage.h
+++ b/chrome/browser/profiles/profile_attributes_storage.h
@@ -18,6 +18,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_init_params.h"
 #include "chrome/browser/profiles/profile_info_cache_observer.h"
@@ -30,38 +31,46 @@
 class Image;
 }
 
+namespace signin {
+class PersistentRepeatingTimer;
+}
+
 class AccountId;
 class PrefService;
 class ProfileAttributesEntry;
 class ProfileAvatarDownloader;
+class PrefRegistrySimple;
 
 class ProfileAttributesStorage
     : public base::SupportsWeakPtr<ProfileAttributesStorage> {
  public:
   using Observer = ProfileInfoCacheObserver;
 
-  explicit ProfileAttributesStorage(PrefService* prefs);
+  explicit ProfileAttributesStorage(PrefService* prefs,
+                                    const base::FilePath& user_data_dir);
   ProfileAttributesStorage(const ProfileAttributesStorage&) = delete;
   ProfileAttributesStorage& operator=(const ProfileAttributesStorage&) = delete;
-  virtual ~ProfileAttributesStorage();
+  ~ProfileAttributesStorage();
+
+  // Register cache related preferences in Local State.
+  static void RegisterPrefs(PrefRegistrySimple* registry);
 
   // Adds a new profile with `params` to the attributes storage.
   // `params.profile_path` must be a valid path within the user data directory
   // that hasn't been registered with this `ProfileAttributesStorage` before.
-  virtual void AddProfile(ProfileAttributesInitParams params) = 0;
+  void AddProfile(ProfileAttributesInitParams params);
 
   // Removes the profile matching given |account_id| from this storage.
   // Calculates profile path and calls RemoveProfile() on it.
-  virtual void RemoveProfileByAccountId(const AccountId& account_id) = 0;
+  void RemoveProfileByAccountId(const AccountId& account_id);
 
   // Removes the profile at |profile_path| from this storage. Does not delete or
   // affect the actual profile's data.
-  virtual void RemoveProfile(const base::FilePath& profile_path) = 0;
+  void RemoveProfile(const base::FilePath& profile_path);
 
   // Returns a vector containing one attributes entry per known profile. They
   // are not sorted in any particular order.
-  std::vector<ProfileAttributesEntry*> GetAllProfilesAttributes(
-      bool include_guest_profile = false) const;
+  std::vector<ProfileAttributesEntry*> GetAllProfilesAttributes() const;
 
   // Returns all non-Guest profile attributes sorted by name.
   std::vector<ProfileAttributesEntry*> GetAllProfilesAttributesSortedByName()
@@ -75,11 +84,11 @@
   // if the operation is successful. Returns |nullptr| otherwise.
   // Returned value should not be cached because the profile entry may be
   // deleted at any time, an then using this value would cause use-after-free.
-  virtual ProfileAttributesEntry* GetProfileAttributesWithPath(
+  ProfileAttributesEntry* GetProfileAttributesWithPath(
       const base::FilePath& path);
 
   // Returns the count of known profiles.
-  virtual size_t GetNumberOfProfiles(bool include_guest_profile = false) const;
+  size_t GetNumberOfProfiles() const;
 
   // Returns a unique name that can be assigned to a newly created profile.
   std::u16string ChooseNameForNewProfile(size_t icon_index) const;
@@ -164,16 +173,22 @@
   void NotifyProfileHostedDomainChanged(
       const base::FilePath& profile_path) const;
 
+  // Returns a pref dictionary key of a profile at `profile_path`.
+  std::string StorageKeyFromProfilePath(
+      const base::FilePath& profile_path) const;
+
   // Disables the periodic reporting of profile metrics, as this is causing
   // tests to time out.
-  virtual void DisableProfileMetricsForTesting() {}
+  void DisableProfileMetricsForTesting();
 
- protected:
+ private:
   FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest, EntriesInAttributesStorage);
   FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest,
                            DownloadHighResAvatarTest);
   FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest,
                            NothingToDownloadHighResAvatarTest);
+  FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest,
+                           MigrateLegacyProfileNamesAndRecomputeIfNeeded);
 
   // Starts downloading the high res avatar at index |icon_index| for profile
   // with path |profile_path|.
@@ -189,39 +204,32 @@
                              const base::FilePath& image_path,
                              base::OnceClosure callback);
 
-  PrefService* const prefs_;
-  mutable std::unordered_map<base::FilePath::StringType, ProfileAttributesEntry>
-      profile_attributes_entries_;
-
-  mutable base::ObserverList<Observer>::Unchecked observer_list_;
-
-  // A cache of gaia/high res avatar profile pictures. This cache is updated
-  // lazily so it needs to be mutable.
-  mutable std::unordered_map<std::string, gfx::Image> cached_avatar_images_;
-
-  // Marks a profile picture as loading from disk. This prevents a picture from
-  // loading multiple times.
-  mutable std::unordered_map<std::string, bool> cached_avatar_images_loading_;
-
-  // Hash table of profile pictures currently being downloaded from the remote
-  // location and the ProfileAvatarDownloader instances downloading them.
-  // This prevents a picture from being downloaded multiple times. The
-  // ProfileAvatarDownloader instances are deleted when the download completes
-  // or when the ProfileInfoCache is destroyed.
-  std::unordered_map<std::string, std::unique_ptr<ProfileAvatarDownloader>>
-      avatar_images_downloads_in_progress_;
-
-  // Determines of the ProfileAvatarDownloader should be created and executed
-  // or not. Only set to true for tests.
-  bool disable_avatar_download_for_testing_ = false;
-
-  // Task runner used for file operation on avatar images.
-  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
-
- private:
   std::vector<ProfileAttributesEntry*> GetAllProfilesAttributesSorted(
       bool use_local_profile_name) const;
 
+  // Creates and initializes a ProfileAttributesEntry with `key`. `is_omitted`
+  // indicates whether the profile should be hidden in UI.
+  ProfileAttributesEntry* InitEntryWithKey(const std::string& key,
+                                           bool is_omitted);
+
+  // Download and high-res avatars used by the profiles.
+  void DownloadAvatars();
+
+#if !defined(OS_ANDROID)
+  // Loads GAIA pictures (if any) for all profiles registered in the storage and
+  // puts them in memory cache.
+  void LoadGAIAPictureIfNeeded();
+#endif
+
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+  // Migrate any legacy profile names ("First user", "Default Profile") to
+  // new style default names ("Person 1"). Rename any duplicates of "Person n"
+  // i.e. Two or more profiles with the profile name "Person 1" would be
+  // recomputed to "Person 1" and "Person 2".
+  void MigrateLegacyProfileNamesAndRecomputeIfNeeded();
+  static void SetLegacyProfileMigrationForTesting(bool value);
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+
   // Called when the picture given by |key| has been loaded from disk and
   // decoded into |image|.
   void OnAvatarPictureLoaded(const base::FilePath& profile_path,
@@ -249,6 +257,42 @@
   // Notifies observers.
   void NotifyOnProfileHighResAvatarLoaded(
       const base::FilePath& profile_path) const;
+
+  PrefService* const prefs_;
+  mutable std::unordered_map<base::FilePath::StringType, ProfileAttributesEntry>
+      profile_attributes_entries_;
+
+  mutable base::ObserverList<Observer>::Unchecked observer_list_;
+
+  // A cache of gaia/high res avatar profile pictures. This cache is updated
+  // lazily so it needs to be mutable.
+  mutable std::unordered_map<std::string, gfx::Image> cached_avatar_images_;
+
+  // Marks a profile picture as loading from disk. This prevents a picture from
+  // loading multiple times.
+  mutable std::unordered_map<std::string, bool> cached_avatar_images_loading_;
+
+  // Hash table of profile pictures currently being downloaded from the remote
+  // location and the ProfileAvatarDownloader instances downloading them.
+  // This prevents a picture from being downloaded multiple times. The
+  // ProfileAvatarDownloader instances are deleted when the download completes
+  // or when the ProfileAttributesStorage is destroyed.
+  std::unordered_map<std::string, std::unique_ptr<ProfileAvatarDownloader>>
+      avatar_images_downloads_in_progress_;
+
+  // Determines of the ProfileAvatarDownloader should be created and executed
+  // or not. Only set to true for tests.
+  bool disable_avatar_download_for_testing_ = false;
+
+  // Task runner used for file operation on avatar images.
+  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
+
+  const base::FilePath user_data_dir_;
+
+#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
+  // PersistentRepeatingTimer for periodically logging profile metrics.
+  std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
+#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 };
 
 #endif  // CHROME_BROWSER_PROFILES_PROFILE_ATTRIBUTES_STORAGE_H_
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
index c81be62..12339d6b 100644
--- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc
+++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/profiles/profile_attributes_init_params.h"
 #include "chrome/browser/profiles/profile_avatar_downloader.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/signin_util.h"
 #include "chrome/browser/supervised_user/supervised_user_constants.h"
@@ -92,7 +91,6 @@
                          bool is_consented_primary_account,
                          size_t icon_index,
                          const std::string& supervised_user_id,
-                         bool is_guest,
                          bool is_ephemeral,
                          bool is_omitted,
                          bool is_signed_in_with_credential_provider) {
@@ -104,7 +102,6 @@
   EXPECT_EQ(is_consented_primary_account, entry->IsAuthenticated());
   EXPECT_EQ(icon_index, entry->GetAvatarIconIndex());
   EXPECT_EQ(supervised_user_id, entry->GetSupervisedUserId());
-  EXPECT_EQ(is_guest, entry->IsGuest());
   EXPECT_EQ(is_ephemeral, entry->IsEphemeral());
   EXPECT_EQ(is_omitted, entry->IsOmitted());
   EXPECT_EQ(is_signed_in_with_credential_provider,
@@ -204,11 +201,7 @@
   }
 
   ProfileAttributesStorage* storage() {
-    return profile_info_cache();
-  }
-
-  ProfileInfoCache* profile_info_cache() {
-    return testing_profile_manager_.profile_info_cache();
+    return testing_profile_manager_.profile_attributes_storage();
   }
 
   ProfileAttributesTestObserver& observer() { return observer_; }
@@ -238,9 +231,9 @@
     EXPECT_EQ(number_of_profiles + 1, storage()->GetNumberOfProfiles());
   }
 
-  void ResetProfileInfoCache() {
+  void ResetProfileAttributesStorage() {
     DisableObserver();
-    testing_profile_manager_.DeleteProfileInfoCache();
+    testing_profile_manager_.DeleteProfileAttributesStorage();
     EnableObserver();
   }
 
@@ -370,7 +363,6 @@
   params.supervised_user_id = "testing_supervised_user_id";
   params.account_id = AccountId::FromUserEmailGaiaId(
       base::UTF16ToUTF8(params.user_name), params.gaia_id);
-  params.is_guest = true;
   params.is_ephemeral = true;
   params.is_omitted = true;
   params.is_signed_in_with_credential_provider = true;
@@ -385,7 +377,7 @@
       /*gaia_id=*/"testing_profile_gaia",
       /*user_name=*/u"testing_profile_username",
       /*is_consented_primary_account=*/true, /*icon_index=*/kIconIndex,
-      /*supervised_user_id=*/"testing_supervised_user_id", /*is_guest=*/true,
+      /*supervised_user_id=*/"testing_supervised_user_id",
       /*is_ephemeral=*/true, /*is_omitted=*/true,
       /*is_signed_in_with_credential_provider=*/true);
 }
@@ -405,7 +397,6 @@
   EXPECT_EQ(0U, params.icon_index);
   EXPECT_TRUE(params.supervised_user_id.empty());
   EXPECT_TRUE(params.account_id.empty());
-  EXPECT_FALSE(params.is_guest);
   EXPECT_FALSE(params.is_ephemeral);
   EXPECT_FALSE(params.is_omitted);
   EXPECT_FALSE(params.is_signed_in_with_credential_provider);
@@ -419,7 +410,7 @@
   VerifyInitialValues(entry, profile_path, /*profile_name=*/std::u16string(),
                       /*gaia_id=*/std::string(), /*user_name=*/std::u16string(),
                       /*is_consented_primary_account=*/false, /*icon_index=*/0,
-                      /*supervised_user_id=*/std::string(), /*is_guest=*/false,
+                      /*supervised_user_id=*/std::string(),
                       /*is_ephemeral=*/false, /*is_omitted=*/false,
                       /*is_signed_in_with_credential_provider=*/false);
 }
@@ -673,7 +664,7 @@
       storage()->GetProfileAttributesWithPath(GetProfilePath("alpha_path"));
   ASSERT_NE(entry, nullptr);
 
-  // Trigger a ProfileInfoCache re-sort.
+  // Trigger a ProfileAttributesStorage re-sort.
   entry->SetLocalProfileName(u"zulu_name",
                              /*is_default_name=*/false);
   EXPECT_EQ(GetProfilePath("alpha_path"), entry->GetPath());
@@ -682,9 +673,8 @@
 TEST_F(ProfileAttributesStorageTest, RemoveOtherProfile) {
   AddTestingProfile();
   AddTestingProfile();
-  AddTestingProfile();
 
-  EXPECT_EQ(3U, storage()->GetNumberOfProfiles());
+  EXPECT_EQ(2U, storage()->GetNumberOfProfiles());
 
   ProfileAttributesEntry* first_entry = storage()->GetProfileAttributesWithPath(
       GetProfilePath("testing_profile_path0"));
@@ -706,16 +696,6 @@
 
   EXPECT_EQ(GetProfilePath("testing_profile_path0"), first_entry->GetPath());
   EXPECT_EQ(u"testing_profile_name0", first_entry->GetName());
-
-  // Deleting through the ProfileInfoCache should be reflected in the
-  // ProfileAttributesStorage as well.
-  AddCallExpectationsForRemoveProfile(2);
-  profile_info_cache()->RemoveProfile(
-      GetProfilePath("testing_profile_path2"));
-  VerifyAndResetCallExpectations();
-  second_entry = storage()->GetProfileAttributesWithPath(
-      GetProfilePath("testing_profile_path2"));
-  ASSERT_EQ(second_entry, nullptr);
 }
 
 TEST_F(ProfileAttributesStorageTest, AccessFromElsewhere) {
@@ -737,10 +717,6 @@
   EXPECT_EQ(u"NewName", second_entry->GetName());
   EXPECT_EQ(first_entry, second_entry);
 
-  // The ProfileInfoCache should also reflect the changes and its changes
-  // should be reflected by the ProfileAttributesStorage.
-  EXPECT_EQ(u"NewName", second_entry->GetName());
-
   second_entry->SetLocalProfileName(u"OtherNewName",
                                     /*is_default_name=*/false);
   EXPECT_EQ(u"OtherNewName", first_entry->GetName());
@@ -847,7 +823,7 @@
     VerifyAndResetCallExpectations();
 
     // IsSigninRequired() cannot be set as an init parameter. Set it after an
-    // entry is initialized and reset the cache to reinitialize an entry from
+    // entry is initialized and reset the storage to reinitialize an entry from
     // prefs.
     EXPECT_CALL(observer(), OnProfileSigninRequiredChanged(profile_path))
         .Times(1);
@@ -855,7 +831,7 @@
         storage()->GetProfileAttributesWithPath(profile_path);
     entry->LockForceSigninProfile(true);
     VerifyAndResetCallExpectations();
-    ResetProfileInfoCache();
+    ResetProfileAttributesStorage();
 
     entry = storage()->GetProfileAttributesWithPath(profile_path);
     ASSERT_NE(entry, nullptr);
@@ -863,9 +839,9 @@
     EXPECT_TRUE(entry->IsSigninRequired());
   }
 
-  // Reset the cache once more after the policy has been disabled and check that
-  // sign-in is no longer required.
-  ResetProfileInfoCache();
+  // Reset the storage once more after the policy has been disabled and check
+  // that sign-in is no longer required.
+  ResetProfileAttributesStorage();
   ProfileAttributesEntry* entry =
       storage()->GetProfileAttributesWithPath(profile_path);
   ASSERT_NE(entry, nullptr);
@@ -962,7 +938,7 @@
 
   // The previous |GetHighResAvater| starts |LoadAvatarPictureFromPath| async.
   // The async code will end up at |OnAvatarPictureLoaded| storing an empty
-  // image in the cache.
+  // image in the storage.
   EXPECT_CALL(observer(), OnProfileHighResAvatarLoaded(profile_path)).Times(1);
   content::RunAllTasksUntilIdle();
   VerifyAndResetCallExpectations();
@@ -1314,7 +1290,7 @@
             "GAIA_IMAGE_URL_WITH_SIZE_0");
   EXPECT_TRUE(gfx::test::AreImagesEqual(gaia_image, *entry->GetGAIAPicture()));
 
-  ResetProfileInfoCache();
+  ResetProfileAttributesStorage();
   // Try to get the GAIA picture. This should return NULL until the read from
   // disk is done.
   entry = storage()->GetProfileAttributesWithPath(profile_path);
@@ -1388,10 +1364,10 @@
   // Make sure this profile is using GAIA picture.
   EXPECT_TRUE(entry->IsUsingGAIAPicture());
 
-  ResetProfileInfoCache();
+  ResetProfileAttributesStorage();
   entry = storage()->GetProfileAttributesWithPath(profile_path);
 
-  // We need to explicitly set the GAIA usage flag after resetting the cache.
+  // We need to explicitly set the GAIA usage flag after resetting the storage.
   EXPECT_CALL(observer(), OnProfileAvatarChanged(profile_path)).Times(1);
   EXPECT_CALL(observer(), OnProfileHighResAvatarLoaded(profile_path)).Times(1);
   entry->SetIsUsingGAIAPicture(true);
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index 30293e9..1cd77f4 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -36,8 +36,11 @@
 class PrefService;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-namespace chromeos {
+namespace ash {
 class KioskTest;
+}
+
+namespace chromeos {
 class LocaleChangeGuard;
 class Preferences;
 class SupervisedUserTestBase;
@@ -177,7 +180,7 @@
 
  private:
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  friend class chromeos::KioskTest;
+  friend class ash::KioskTest;
   friend class chromeos::SupervisedUserTestBase;
 #endif
   friend class Profile;
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
deleted file mode 100644
index 1d328a53..0000000
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/profiles/profile_info_cache.h"
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/containers/contains.h"
-#include "base/files/file_util.h"
-#include "base/i18n/case_conversion.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile_attributes_entry.h"
-#include "chrome/browser/profiles/profile_attributes_init_params.h"
-#include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profiles_state.h"
-#include "chrome/common/buildflags.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/account_id/account_id.h"
-#include "components/prefs/pref_registry_simple.h"
-#include "components/prefs/pref_service.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "components/signin/public/base/signin_pref_names.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_util.h"
-
-namespace {
-
-const char kProfileCountLastUpdatePref[] = "profile.profile_counts_reported";
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-const char kLegacyProfileNameMigrated[] = "legacy.profile.name.migrated";
-bool migration_enabled_for_testing = false;
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-
-}  // namespace
-
-ProfileInfoCache::ProfileInfoCache(PrefService* prefs,
-                                   const base::FilePath& user_data_dir)
-    : ProfileAttributesStorage(prefs), user_data_dir_(user_data_dir) {
-  // Populate the cache
-  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
-  base::DictionaryValue* cache = update.Get();
-  for (base::DictionaryValue::Iterator it(*cache);
-       !it.IsAtEnd(); it.Advance()) {
-    base::DictionaryValue* info = nullptr;
-    cache->GetDictionaryWithoutPathExpansion(it.key(), &info);
-    std::u16string name;
-    info->GetString(ProfileAttributesEntry::kNameKey, &name);
-
-    bool using_default_name;
-    if (!info->GetBoolean(ProfileAttributesEntry::kIsUsingDefaultNameKey,
-                          &using_default_name)) {
-      // If the preference hasn't been set, and the name is default, assume
-      // that the user hasn't done this on purpose.
-      // |include_check_for_legacy_profile_name| is true as this is an old
-      // pre-existing profile and might have a legacy default profile name.
-      using_default_name = IsDefaultProfileName(
-          name, /*include_check_for_legacy_profile_name=*/true);
-      info->SetBoolean(ProfileAttributesEntry::kIsUsingDefaultNameKey,
-                       using_default_name);
-    }
-
-    // For profiles that don't have the "using default avatar" state set yet,
-    // assume it's the same as the "using default name" state.
-    if (!info->HasKey(ProfileAttributesEntry::kIsUsingDefaultAvatarKey)) {
-      info->SetBoolean(ProfileAttributesEntry::kIsUsingDefaultAvatarKey,
-                       using_default_name);
-    }
-
-    // `info` may become invalid after this call.
-    // Profiles loaded from disk can never be omitted.
-    InitEntryWithKey(it.key(), /*is_omitted=*/false);
-  }
-
-  // A profile name can depend on other profile names. Do an additional pass to
-  // update last used profile names once all profiles are initialized.
-  for (ProfileAttributesEntry* entry :
-       GetAllProfilesAttributes(/*include_guest_profile=*/true)) {
-    entry->InitializeLastNameToDisplay();
-  }
-
-  // If needed, start downloading the high-res avatars and migrate any legacy
-  // profile names.
-  if (!disable_avatar_download_for_testing_)
-    DownloadAvatars();
-
-#if !defined(OS_ANDROID)
-  LoadGAIAPictureIfNeeded();
-#endif
-
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-  bool migrate_legacy_profile_names =
-      (!prefs_->GetBoolean(kLegacyProfileNameMigrated) ||
-       migration_enabled_for_testing);
-  if (migrate_legacy_profile_names) {
-    MigrateLegacyProfileNamesAndRecomputeIfNeeded();
-    prefs_->SetBoolean(kLegacyProfileNameMigrated, true);
-  }
-
-  repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
-      prefs_, kProfileCountLastUpdatePref, base::TimeDelta::FromHours(24),
-      base::BindRepeating(&ProfileMetrics::LogNumberOfProfiles, this));
-  repeating_timer_->Start();
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-}
-
-ProfileInfoCache::~ProfileInfoCache() = default;
-
-void ProfileInfoCache::AddProfileToCache(ProfileAttributesInitParams params) {
-  std::string key = CacheKeyFromProfilePath(params.profile_path);
-  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
-  base::DictionaryValue* cache = update.Get();
-
-  std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue);
-  info->SetString(ProfileAttributesEntry::kNameKey, params.profile_name);
-  info->SetString(ProfileAttributesEntry::kGAIAIdKey, params.gaia_id);
-  info->SetString(ProfileAttributesEntry::kUserNameKey, params.user_name);
-  DCHECK(!params.is_consented_primary_account || !params.gaia_id.empty() ||
-         !params.user_name.empty());
-  info->SetBoolean(ProfileAttributesEntry::kIsConsentedPrimaryAccountKey,
-                   params.is_consented_primary_account);
-  info->SetString(ProfileAttributesEntry::kAvatarIconKey,
-                  profiles::GetDefaultAvatarIconUrl(params.icon_index));
-  // Default value for whether background apps are running is false.
-  info->SetBoolean(ProfileAttributesEntry::kBackgroundAppsKey, false);
-  info->SetString(ProfileAttributesEntry::kSupervisedUserId,
-                  params.supervised_user_id);
-  info->SetBoolean(ProfileAttributesEntry::kProfileIsEphemeral,
-                   params.is_ephemeral);
-  info->SetBoolean(ProfileAttributesEntry::kProfileIsGuest, params.is_guest);
-  // Either the user has provided a name manually on purpose, and in this case
-  // we should not check for legacy profile names or this a new profile but then
-  // it is not a legacy name, so we dont need to check for legacy names.
-  info->SetBoolean(
-      ProfileAttributesEntry::kIsUsingDefaultNameKey,
-      IsDefaultProfileName(params.profile_name,
-                           /*include_check_for_legacy_profile_name*/ false));
-  // Assume newly created profiles use a default avatar.
-  info->SetBoolean(ProfileAttributesEntry::kIsUsingDefaultAvatarKey, true);
-  if (params.account_id.HasAccountIdKey())
-    info->SetString(ProfileAttributesEntry::kAccountIdKey,
-                    params.account_id.GetAccountIdKey());
-  info->SetBoolKey(prefs::kSignedInWithCredentialProvider,
-                   params.is_signed_in_with_credential_provider);
-  cache->SetKey(key, base::Value::FromUniquePtrValue(std::move(info)));
-  ProfileAttributesEntry* entry = InitEntryWithKey(key, params.is_omitted);
-  entry->InitializeLastNameToDisplay();
-
-  // `OnProfileAdded()` must be the first observer method being called right
-  // after a new profile is added to cache.
-  for (auto& observer : observer_list_)
-    observer.OnProfileAdded(params.profile_path);
-
-  if (!disable_avatar_download_for_testing_)
-    DownloadHighResAvatarIfNeeded(params.icon_index, params.profile_path);
-
-  NotifyIfProfileNamesHaveChanged();
-}
-
-void ProfileInfoCache::DisableProfileMetricsForTesting() {
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-  repeating_timer_.reset();
-#endif
-}
-
-void ProfileInfoCache::DeleteProfileFromCache(
-    const base::FilePath& profile_path) {
-  ProfileAttributesEntry* entry = GetProfileAttributesWithPath(profile_path);
-  if (!entry) {
-    NOTREACHED();
-    return;
-  }
-
-  std::u16string name = entry->GetName();
-
-  for (auto& observer : observer_list_)
-    observer.OnProfileWillBeRemoved(profile_path);
-
-  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
-  base::DictionaryValue* cache = update.Get();
-  std::string key = CacheKeyFromProfilePath(profile_path);
-  cache->Remove(key, nullptr);
-  profile_attributes_entries_.erase(profile_path.value());
-
-  // `OnProfileWasRemoved()` must be the first observer method being called
-  // right after a profile was removed from cache.
-  for (auto& observer : observer_list_) {
-    observer.OnProfileWasRemoved(profile_path, name);
-  }
-
-  NotifyIfProfileNamesHaveChanged();
-}
-
-const base::FilePath& ProfileInfoCache::GetUserDataDir() const {
-  return user_data_dir_;
-}
-
-// static
-void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) {
-  registry->RegisterDictionaryPref(prefs::kProfileInfoCache);
-  registry->RegisterTimePref(kProfileCountLastUpdatePref, base::Time());
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-  registry->RegisterBooleanPref(kLegacyProfileNameMigrated, false);
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-}
-
-std::string ProfileInfoCache::CacheKeyFromProfilePath(
-    const base::FilePath& profile_path) const {
-  DCHECK(user_data_dir_ == profile_path.DirName());
-  base::FilePath base_name = profile_path.BaseName();
-  return base_name.MaybeAsASCII();
-}
-
-#if !defined(OS_ANDROID)
-void ProfileInfoCache::LoadGAIAPictureIfNeeded() {
-  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
-  for (ProfileAttributesEntry* entry : entries) {
-    if (entry->GetSigninState() == SigninState::kNotSignedIn)
-      continue;
-
-    bool is_using_GAIA_picture =
-        entry->GetBool(ProfileAttributesEntry::kUseGAIAPictureKey);
-    bool is_using_default_avatar = entry->IsUsingDefaultAvatar();
-    // Load from disk into memory GAIA picture if it exists.
-    if (is_using_GAIA_picture || is_using_default_avatar)
-      entry->GetGAIAPicture();
-  }
-}
-#endif
-
-ProfileAttributesEntry* ProfileInfoCache::InitEntryWithKey(
-    const std::string& key,
-    bool is_omitted) {
-  base::FilePath path = user_data_dir_.AppendASCII(key);
-  DCHECK(!base::Contains(profile_attributes_entries_, path.value()));
-  ProfileAttributesEntry* new_entry =
-      &profile_attributes_entries_[path.value()];
-  new_entry->Initialize(this, path, prefs_);
-  new_entry->SetIsOmittedInternal(is_omitted);
-  return new_entry;
-}
-
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-void ProfileInfoCache::MigrateLegacyProfileNamesAndRecomputeIfNeeded() {
-  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
-  for (size_t i = 0; i < entries.size(); i++) {
-    std::u16string profile_name = entries[i]->GetLocalProfileName();
-    if (!entries[i]->IsUsingDefaultName())
-      continue;
-
-    // Migrate any legacy profile names ("First user", "Default Profile",
-    // "Saratoga", ...) to new style default names Person %n ("Person 1").
-    if (!IsDefaultProfileName(
-            profile_name, /*include_check_for_legacy_profile_name=*/false)) {
-      entries[i]->SetLocalProfileName(
-          ChooseNameForNewProfile(entries[i]->GetAvatarIconIndex()),
-          /*is_default_name=*/true);
-      continue;
-    }
-
-    if (i == (entries.size() - 1))
-      continue;
-
-    // Current profile name is Person %n.
-    // Rename duplicate default profile names, e.g.: Person 1, Person 1 to
-    // Person 1, Person 2.
-    for (size_t j = i + 1; j < entries.size(); j++) {
-      if (profile_name == entries[j]->GetLocalProfileName()) {
-        entries[j]->SetLocalProfileName(
-            ChooseNameForNewProfile(entries[j]->GetAvatarIconIndex()),
-            /*is_default_name=*/true);
-      }
-    }
-  }
-}
-
-// static
-void ProfileInfoCache::SetLegacyProfileMigrationForTesting(bool value) {
-  migration_enabled_for_testing = value;
-}
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-
-void ProfileInfoCache::DownloadAvatars() {
-#if !defined(OS_ANDROID)
-  std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
-  for (ProfileAttributesEntry* entry : entries) {
-    DownloadHighResAvatarIfNeeded(entry->GetAvatarIconIndex(),
-                                  entry->GetPath());
-  }
-#endif
-}
-
-void ProfileInfoCache::AddProfile(ProfileAttributesInitParams params) {
-  AddProfileToCache(std::move(params));
-}
-
-void ProfileInfoCache::RemoveProfileByAccountId(const AccountId& account_id) {
-  for (ProfileAttributesEntry* entry : GetAllProfilesAttributes(true)) {
-    bool account_id_keys_match =
-        account_id.HasAccountIdKey() &&
-        account_id.GetAccountIdKey() == entry->GetAccountIdKey();
-    bool gaia_ids_match = !entry->GetGAIAId().empty() &&
-                          account_id.GetGaiaId() == entry->GetGAIAId();
-    bool user_names_match =
-        !entry->GetUserName().empty() &&
-        account_id.GetUserEmail() == base::UTF16ToUTF8(entry->GetUserName());
-    if (account_id_keys_match || gaia_ids_match || user_names_match) {
-      RemoveProfile(entry->GetPath());
-      return;
-    }
-  }
-  LOG(ERROR) << "Failed to remove profile.info_cache entry for account type "
-             << static_cast<int>(account_id.GetAccountType())
-             << ": matching entry not found.";
-}
-
-void ProfileInfoCache::RemoveProfile(const base::FilePath& profile_path) {
-  DeleteProfileFromCache(profile_path);
-}
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
deleted file mode 100644
index fc603ce..0000000
--- a/chrome/browser/profiles/profile_info_cache.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
-#define CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/browser/profiles/profile_attributes_entry.h"
-#include "chrome/browser/profiles/profile_attributes_init_params.h"
-#include "chrome/browser/profiles/profile_attributes_storage.h"
-#include "components/signin/public/base/persistent_repeating_timer.h"
-
-class PrefService;
-class PrefRegistrySimple;
-
-// This class saves various information about profiles to local preferences.
-// This cache can be used to display a list of profiles without having to
-// actually load the profiles from disk.
-class ProfileInfoCache : public ProfileAttributesStorage {
- public:
-  ProfileInfoCache(PrefService* prefs, const base::FilePath& user_data_dir);
-  ProfileInfoCache(const ProfileInfoCache&) = delete;
-  ProfileInfoCache& operator=(const ProfileInfoCache&) = delete;
-  ~ProfileInfoCache() override;
-
-  // Deprecated. Use AddProfile instead.
-  void AddProfileToCache(ProfileAttributesInitParams params);
-  // Deprecated. Use RemoveProfile instead.
-  void DeleteProfileFromCache(const base::FilePath& profile_path);
-
-  const base::FilePath& GetUserDataDir() const;
-
-  // Register cache related preferences in Local State.
-  static void RegisterPrefs(PrefRegistrySimple* registry);
-
-  // ProfileAttributesStorage:
-  void AddProfile(ProfileAttributesInitParams) override;
-  void RemoveProfileByAccountId(const AccountId& account_id) override;
-  void RemoveProfile(const base::FilePath& profile_path) override;
-
-  void DisableProfileMetricsForTesting() override;
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(ProfileInfoCacheTest,
-                           MigrateLegacyProfileNamesAndRecomputeIfNeeded);
-
-  std::string CacheKeyFromProfilePath(const base::FilePath& profile_path) const;
-
-  // Download and high-res avatars used by the profiles.
-  void DownloadAvatars();
-
-#if !defined(OS_ANDROID)
-  void LoadGAIAPictureIfNeeded();
-#endif
-
-  ProfileAttributesEntry* InitEntryWithKey(const std::string& key,
-                                           bool is_omitted);
-
-#if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-  // Migrate any legacy profile names ("First user", "Default Profile") to
-  // new style default names ("Person 1"). Rename any duplicates of "Person n"
-  // i.e. Two or more profiles with the profile name "Person 1" would be
-  // recomputed to "Person 1" and "Person 2".
-  void MigrateLegacyProfileNamesAndRecomputeIfNeeded();
-  static void SetLegacyProfileMigrationForTesting(bool value);
-
-  std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
-#endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
-
-  const base::FilePath user_data_dir_;
-};
-
-#endif  // CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index 6d21678b..27c7245b 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -24,8 +24,8 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/avatar_menu.h"
 #include "chrome/browser/profiles/profile_attributes_init_params.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/signin_util.h"
 #include "chrome/common/chrome_switches.h"
@@ -109,8 +109,8 @@
   EXPECT_TRUE(profile_names_.find(profile_path) != profile_names_.end());
 }
 
-ProfileInfoCache* ProfileNameVerifierObserver::GetCache() {
-  return testing_profile_manager_->profile_info_cache();
+ProfileAttributesStorage* ProfileNameVerifierObserver::GetCache() {
+  return testing_profile_manager_->profile_attributes_storage();
 }
 
 ProfileInfoCacheTest::ProfileInfoCacheTest()
@@ -122,7 +122,8 @@
 
 void ProfileInfoCacheTest::SetUp() {
   ASSERT_TRUE(testing_profile_manager_.SetUp());
-  testing_profile_manager_.profile_info_cache()->AddObserver(&name_observer_);
+  testing_profile_manager_.profile_attributes_storage()->AddObserver(
+      &name_observer_);
 }
 
 void ProfileInfoCacheTest::TearDown() {
@@ -131,8 +132,8 @@
   content::RunAllTasksUntilIdle();
 }
 
-ProfileInfoCache* ProfileInfoCacheTest::GetCache() {
-  return testing_profile_manager_.profile_info_cache();
+ProfileAttributesStorage* ProfileInfoCacheTest::GetCache() {
+  return testing_profile_manager_.profile_attributes_storage();
 }
 
 base::FilePath ProfileInfoCacheTest::GetProfilePath(
@@ -142,7 +143,7 @@
 }
 
 void ProfileInfoCacheTest::ResetCache() {
-  testing_profile_manager_.DeleteProfileInfoCache();
+  testing_profile_manager_.DeleteProfileAttributesStorage();
 }
 
 std::u16string ProfileInfoCacheTest::GetConcatenation(
@@ -184,7 +185,7 @@
     params.profile_name = profile_name;
     params.icon_index = i;
     params.supervised_user_id = supervised_user_id;
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
 
     ProfileAttributesEntry* entry =
         GetCache()->GetProfileAttributesWithPath(profile_path);
@@ -241,14 +242,14 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = profile_path_1;
   params_1.profile_name = u"Person 1";
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
   ProfileAttributesEntry* entry_1 =
       GetCache()->GetProfileAttributesWithPath(profile_path_1);
   base::FilePath profile_path_2 = GetProfilePath("path_2");
   ProfileAttributesInitParams params_2;
   params_2.profile_path = profile_path_2;
   params_2.profile_name = u"Person 2";
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
   ProfileAttributesEntry* entry_2 =
       GetCache()->GetProfileAttributesWithPath(profile_path_2);
 
@@ -285,7 +286,7 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = profile_path_1;
   params_1.profile_name = u"Person 1";
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
   ProfileAttributesEntry* entry_1 =
       GetCache()->GetProfileAttributesWithPath(profile_path_1);
   EXPECT_EQ(u"Person 1", entry_1->GetName());
@@ -308,7 +309,7 @@
   ProfileAttributesInitParams params_2;
   params_2.profile_path = profile_path_2;
   params_2.profile_name = u"Person 2";
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
   ProfileAttributesEntry* entry_2 =
       GetCache()->GetProfileAttributesWithPath(profile_path_2);
   EXPECT_EQ(u"Patt", entry_1->GetName());
@@ -335,7 +336,7 @@
   ProfileAttributesInitParams params_3;
   params_3.profile_path = profile_path_3;
   params_3.profile_name = u"Person 3";
-  GetCache()->AddProfileToCache(std::move(params_3));
+  GetCache()->AddProfile(std::move(params_3));
   ProfileAttributesEntry* entry_3 =
       GetCache()->GetProfileAttributesWithPath(profile_path_3);
   entry_3->SetGAIAName(u"Patt Smith");
@@ -377,7 +378,7 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = path_1;
   params_1.profile_name = u"name_1";
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
 
   base::FilePath path_2 = GetProfilePath("path_2");
@@ -385,16 +386,16 @@
   ProfileAttributesInitParams params_2;
   params_2.profile_path = path_2;
   params_2.profile_name = name_2;
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
   ProfileAttributesEntry* entry =
       GetCache()->GetProfileAttributesWithPath(path_2);
   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
 
-  GetCache()->DeleteProfileFromCache(path_1);
+  GetCache()->RemoveProfile(path_1);
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
   EXPECT_EQ(name_2, entry->GetName());
 
-  GetCache()->DeleteProfileFromCache(path_2);
+  GetCache()->RemoveProfile(path_2);
   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
 }
 
@@ -403,13 +404,13 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = profile_path_1;
   params_1.profile_name = u"name_1";
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
 
   base::FilePath profile_path_2 = GetProfilePath("path_2");
   ProfileAttributesInitParams params_2;
   params_2.profile_path = profile_path_2;
   params_2.profile_name = u"name_2";
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
   ProfileAttributesEntry* entry_1 =
       GetCache()->GetProfileAttributesWithPath(profile_path_1);
   ProfileAttributesEntry* entry_2 =
@@ -441,13 +442,13 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = path_1;
   params_1.profile_name = u"name_1";
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
 
   base::FilePath path_2 = GetProfilePath("path_2");
   ProfileAttributesInitParams params_2;
   params_2.profile_path = path_2;
   params_2.profile_name = u"name_2";
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
 
   ProfileAttributesEntry* entry_1 =
       GetCache()->GetProfileAttributesWithPath(path_1);
@@ -478,7 +479,7 @@
   ProfileAttributesInitParams params;
   params.profile_path = profile_path;
   params.profile_name = u"Test";
-  GetCache()->AddProfileToCache(std::move(params));
+  GetCache()->AddProfile(std::move(params));
   ProfileAttributesEntry* entry =
       GetCache()->GetProfileAttributesWithPath(profile_path);
   EXPECT_FALSE(entry->IsSupervised());
@@ -548,7 +549,7 @@
     ProfileAttributesInitParams params;
     params.profile_path = profile_path;
     params.profile_name = profile_name;
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
     ProfileAttributesEntry* entry =
         GetCache()->GetProfileAttributesWithPath(profile_path);
     EXPECT_TRUE(entry);
@@ -560,8 +561,8 @@
   // Check that the profiles can be extracted from the local state.
   std::vector<std::u16string> names;
   PrefService* local_state = g_browser_process->local_state();
-  const base::DictionaryValue* cache = local_state->GetDictionary(
-      prefs::kProfileInfoCache);
+  const base::DictionaryValue* cache =
+      local_state->GetDictionary(prefs::kProfileAttributes);
   std::u16string name;
   for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd();
        it.Advance()) {
@@ -608,7 +609,7 @@
     params.profile_name = profile_name;
     params.icon_index = i;
     if (i == 0 || i == 2) {
-      GetCache()->AddProfileToCache(std::move(params));
+      GetCache()->AddProfile(std::move(params));
     } else {
       GetCache()->AddProfile(std::move(params));
     }
@@ -634,7 +635,7 @@
     // Use ProfileInfoCache in profiles 0 and 1, and ProfileAttributesStorage in
     // profiles 2 and 3.
     if (i == 0 || i == 1)
-      GetCache()->DeleteProfileFromCache(profile_path);
+      GetCache()->RemoveProfile(profile_path);
     else
       GetCache()->RemoveProfile(profile_path);
 
@@ -673,7 +674,7 @@
     params.profile_path = profile_path;
     params.profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
     params.icon_index = i;
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
     entry = GetCache()->GetProfileAttributesWithPath(profile_path);
     EXPECT_TRUE(entry);
     entry->SetIsUsingDefaultName(kTestCases[i].is_using_default_name);
@@ -682,9 +683,9 @@
   EXPECT_EQ(12U, GetCache()->GetNumberOfProfiles());
 
   ResetCache();
-  ProfileInfoCache::SetLegacyProfileMigrationForTesting(true);
+  ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(true);
   GetCache();
-  ProfileInfoCache::SetLegacyProfileMigrationForTesting(false);
+  ProfileAttributesStorage::SetLegacyProfileMigrationForTesting(false);
 
   entry = GetCache()->GetProfileAttributesWithPath(
       GetProfilePath(kTestCases[4].profile_path));
@@ -734,7 +735,7 @@
     params.profile_path = profile_path;
     params.profile_name = ASCIIToUTF16(kTestCases[i].profile_name);
     params.icon_index = i;
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
     ProfileAttributesEntry* entry =
         GetCache()->GetProfileAttributesWithPath(profile_path);
     EXPECT_TRUE(entry);
@@ -781,7 +782,7 @@
     params.user_name = UTF8ToUTF16(kTestCases[i].account_id.GetUserEmail());
     params.is_consented_primary_account =
         kTestCases[i].is_consented_primary_account;
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
     EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
   }
 
@@ -818,7 +819,7 @@
     params.profile_name = u"Test";
     params.gaia_id = account_id.GetGaiaId();
     params.user_name = UTF8ToUTF16(account_id.GetUserEmail());
-    GetCache()->AddProfileToCache(std::move(params));
+    GetCache()->AddProfile(std::move(params));
     ProfileAttributesEntry* entry =
         GetCache()->GetProfileAttributesWithPath(profile_path);
     // Set up the state so that ProfileAttributesEntry::Initialize() will modify
@@ -846,7 +847,7 @@
   ProfileAttributesInitParams params_1;
   params_1.profile_path = path_1;
   params_1.profile_name = kDefaultProfileName;
-  GetCache()->AddProfileToCache(std::move(params_1));
+  GetCache()->AddProfile(std::move(params_1));
   ProfileAttributesEntry* entry_1 =
       GetCache()->GetProfileAttributesWithPath(path_1);
   entry_1->SetGAIAGivenName(kCommonName);
@@ -857,7 +858,7 @@
   ProfileAttributesInitParams params_2;
   params_2.profile_path = path_2;
   params_2.profile_name = kCommonName;
-  GetCache()->AddProfileToCache(std::move(params_2));
+  GetCache()->AddProfile(std::move(params_2));
   ProfileAttributesEntry* entry_2 =
       GetCache()->GetProfileAttributesWithPath(path_2);
   entry_2->SetGAIAGivenName(kCommonName);
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.h b/chrome/browser/profiles/profile_info_cache_unittest.h
index 8b89325..730431c 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.h
+++ b/chrome/browser/profiles/profile_info_cache_unittest.h
@@ -7,6 +7,7 @@
 
 #include <set>
 
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_info_cache_observer.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -39,7 +40,7 @@
   void OnProfileAvatarChanged(const base::FilePath& profile_path) override;
 
  private:
-  ProfileInfoCache* GetCache();
+  ProfileAttributesStorage* GetCache();
   std::map<base::FilePath, std::u16string> profile_names_;
   TestingProfileManager* testing_profile_manager_;
 };
@@ -52,7 +53,7 @@
   void SetUp() override;
   void TearDown() override;
 
-  ProfileInfoCache* GetCache();
+  ProfileAttributesStorage* GetCache();
   base::FilePath GetProfilePath(const std::string& base_name);
   void ResetCache();
   void RemoveObserver();
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 2ed4bcf..360018a 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -61,7 +61,6 @@
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_destroyer.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_keep_alive_types.h"
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/profiles/profile_manager_observer.h"
@@ -739,8 +738,7 @@
 }
 
 size_t ProfileManager::GetNumberOfProfiles() {
-  return GetProfileAttributesStorage().GetNumberOfProfiles(
-      /*include_guest_profile=*/false);
+  return GetProfileAttributesStorage().GetNumberOfProfiles();
 }
 
 bool ProfileManager::LoadProfile(const std::string& profile_base_name,
@@ -992,17 +990,13 @@
   return new_path;
 }
 
-ProfileInfoCache& ProfileManager::GetProfileInfoCache() {
-  TRACE_EVENT0("browser", "ProfileManager::GetProfileInfoCache");
-  if (!profile_info_cache_) {
-    profile_info_cache_ = std::make_unique<ProfileInfoCache>(
+ProfileAttributesStorage& ProfileManager::GetProfileAttributesStorage() {
+  TRACE_EVENT0("browser", "ProfileManager::GetProfileAttributesStorage");
+  if (!profile_attributes_storage_) {
+    profile_attributes_storage_ = std::make_unique<ProfileAttributesStorage>(
         g_browser_process->local_state(), user_data_dir_);
   }
-  return *profile_info_cache_.get();
-}
-
-ProfileAttributesStorage& ProfileManager::GetProfileAttributesStorage() {
-  return GetProfileInfoCache();
+  return *profile_attributes_storage_.get();
 }
 
 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() {
@@ -1088,7 +1082,7 @@
   std::vector<base::FilePath> profiles_to_delete;
   ProfileAttributesStorage& storage = GetProfileAttributesStorage();
   std::vector<ProfileAttributesEntry*> entries =
-      storage.GetAllProfilesAttributes(/*include_guest_profile=*/true);
+      storage.GetAllProfilesAttributes();
   for (ProfileAttributesEntry* entry : entries) {
     base::FilePath profile_path = entry->GetPath();
     if (entry->IsEphemeral()) {
@@ -1112,8 +1106,6 @@
     profiles::SetLastUsedProfile(new_profile_path.BaseName().MaybeAsASCII());
   }
 
-  // This uses a separate loop, because deleting the profile from the
-  // ProfileInfoCache will modify indices.
   for (const base::FilePath& profile_path : profiles_to_delete) {
     base::ThreadPool::PostTask(
         FROM_HERE,
@@ -1173,8 +1165,8 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // User object may already have changed user type, so we apply that
   // type to profile.
-  // If profile type has changed, remove ProfileInfoCache entry for it to
-  // make sure it is fully re-initialized later.
+  // If profile type has changed, remove ProfileAttributesEntry for it to make
+  // sure it is fully re-initialized later.
   const user_manager::User* user =
       chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
   if (user) {
@@ -1222,7 +1214,7 @@
         transition = arc::ArcSupervisionTransition::NO_TRANSITION;
       }
 
-      profile->GetPrefs()->SetInteger(arc::prefs::kArcSupervisionTransition,
+      profile->GetPrefs()->SetInteger(arc::prefs::kArcManagementTransition,
                                       static_cast<int>(transition));
     }
 
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index c32e2727..915a95e 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -32,7 +32,6 @@
 #endif  // !defined(OS_ANDROID)
 
 class ProfileAttributesStorage;
-class ProfileInfoCache;
 enum class ProfileKeepAliveOrigin;
 class ProfileManagerObserver;
 class ScopedProfileKeepAlive;
@@ -434,11 +433,6 @@
   // Whether a new profile can be created at |path|.
   bool CanCreateProfileAtPath(const base::FilePath& path) const;
 
-  // Returns a ProfileInfoCache object which can be used to get information
-  // about profiles without having to load them from disk.
-  // Deprecated, use GetProfileAttributesStorage() instead.
-  ProfileInfoCache& GetProfileInfoCache();
-
   // Adds |profile| to the profile attributes storage if it hasn't been added
   // yet.
   void AddProfileToStorage(Profile* profile);
@@ -502,8 +496,8 @@
   void OnClosingAllBrowsersChanged(bool closing);
 #endif  // !defined(OS_ANDROID)
 
-  // Destroy after |profile_info_cache_| since Profile destruction may trigger
-  // some observers to unregister themselves.
+  // Destroy after |profile_attributes_storage_| since Profile destruction may
+  // trigger some observers to unregister themselves.
   base::ObserverList<ProfileManagerObserver> observers_;
 
   // Object to cache various information about profiles. Contains information
@@ -511,7 +505,7 @@
   // if it has not been explicitly deleted. It must be destroyed after
   // |profiles_info_| because ~ProfileInfo can trigger a chain of events leading
   // to an access to this member.
-  std::unique_ptr<ProfileInfoCache> profile_info_cache_;
+  std::unique_ptr<ProfileAttributesStorage> profile_attributes_storage_;
 
   base::CallbackListSubscription closing_all_browsers_subscription_;
 
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 1d1af00..48873f52 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -684,17 +684,7 @@
 
 // The test makes sense on those platforms where the keychain exists.
 #if !defined(OS_WIN) && !BUILDFLAG(IS_CHROMEOS_ASH)
-
-// Suddenly started failing on Linux, see http://crbug.com/660488.
-// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
-// complete.
-#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
-#define MAYBE_DeletePasswords DISABLED_DeletePasswords
-#else
-#define MAYBE_DeletePasswords DeletePasswords
-#endif
-
-IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, MAYBE_DeletePasswords) {
+IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, DeletePasswords) {
   Profile* profile = ProfileManager::GetActiveUserProfile();
   ASSERT_TRUE(profile);
 
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index a05caf2..e697030 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -31,8 +31,8 @@
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_attributes_init_params.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_keep_alive_types.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
@@ -665,7 +665,8 @@
   supervised_profile->GetPrefs()->SetString(
       prefs::kSupervisedUserId, supervised_users::kChildAccountSUID);
 
-  // RegisterTestingProfile adds the profile to the cache and takes ownership.
+  // RegisterTestingProfile adds the profile to the attributes storage and takes
+  // ownership.
   profile_manager->RegisterTestingProfile(std::move(supervised_profile), true);
   ASSERT_EQ(1u, storage.GetNumberOfProfiles());
   EXPECT_FALSE(storage.GetAllProfilesAttributesSortedByName()[0]->IsOmitted());
@@ -927,9 +928,9 @@
       avatar_index));
 }
 
-// Tests that a new profile's entry in the profile info cache is setup with the
-// same values that are in the profile prefs.
-TEST_F(ProfileManagerTest, InitProfileInfoCacheForAProfile) {
+// Tests that a new profile's entry in the profile attributes storage is setup
+// with the same values that are in the profile prefs.
+TEST_F(ProfileManagerTest, InitProfileAttributesStorageForAProfile) {
   base::FilePath dest_path = temp_dir_.GetPath();
   dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));
 
@@ -948,7 +949,7 @@
                                       .GetProfileAttributesWithPath(dest_path);
   ASSERT_NE(entry, nullptr);
 
-  // Check if the profile prefs are the same as the cache prefs
+  // Check if the profile prefs are the same as the storage prefs.
   EXPECT_EQ(profile_name, base::UTF16ToUTF8(entry->GetName()));
   EXPECT_EQ(avatar_index, entry->GetAvatarIconIndex());
 }
@@ -961,7 +962,7 @@
       false /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::NO_TRANSITION));
   EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
             supervised_users::kChildAccountSUID);
@@ -974,7 +975,7 @@
       false /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::REGULAR_TO_CHILD));
   EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
             supervised_users::kChildAccountSUID);
@@ -987,7 +988,7 @@
       false /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::CHILD_TO_REGULAR));
   EXPECT_TRUE(profile->GetPrefs()->GetString(prefs::kSupervisedUserId).empty());
 }
@@ -1003,7 +1004,7 @@
       true /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::UNMANAGED_TO_MANAGED));
 }
 
@@ -1018,7 +1019,7 @@
       true /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::NO_TRANSITION));
 }
 
@@ -1030,7 +1031,7 @@
       false /* profile_is_managed */, false /* arc_is_managed */);
 
   EXPECT_EQ(
-      profile->GetPrefs()->GetInteger(arc::prefs::kArcSupervisionTransition),
+      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
       static_cast<int>(arc::ArcSupervisionTransition::NO_TRANSITION));
   EXPECT_TRUE(profile->GetPrefs()->GetString(prefs::kSupervisedUserId).empty());
 }
@@ -1443,7 +1444,7 @@
   storage.AddProfile(std::move(params));
   ASSERT_TRUE(base::CreateDirectory(path));
 
-  ASSERT_EQ(1u, storage.GetNumberOfProfiles(/*include_guest_profile=*/true));
+  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
 
   // Set the active profile.
   PrefService* local_state = g_browser_process->local_state();
@@ -1467,7 +1468,7 @@
   EXPECT_TRUE(base::DirectoryExists(path));
   EXPECT_EQ(guest_profile_name,
             local_state->GetString(prefs::kProfileLastUsed));
-  ASSERT_EQ(1u, storage.GetNumberOfProfiles(/*include_guest_profile=*/true));
+  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
   ASSERT_EQ(2u, final_last_active_profile_list->GetSize());
   ASSERT_EQ(guest_path.BaseName().MaybeAsASCII(),
             (final_last_active_profile_list->GetList())[0].GetString());
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index 3f0b053e..e65f9818 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -67,6 +67,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/browsing_data_remover_test_util.h"
+#include "content/public/test/prerender_test_util.h"
 #include "content/public/test/test_utils.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -102,6 +103,13 @@
     "BFVSaqVujqpHlzYQwWY8HmW_oXvuSMnGu78CGFNyHQx7qeMRtwNSIdNxkBOowc_tIPcf0X_ydr"
     "YBINg1pdk8Q_0";
 
+// From chrome/browser/push_messaging/push_messaging_manager.cc
+const char* kIncognitoWarningPattern =
+    "Chrome currently does not support the Push API in incognito mode "
+    "(https://crbug.com/401439). There is deliberately no way to "
+    "feature-detect this, since incognito mode needs to be undetectable by "
+    "websites.";
+
 std::string GetTestApplicationServerKey(bool base64_url_encoded = false) {
   std::string application_server_key;
 
@@ -168,7 +176,6 @@
         net::EmbeddedTestServer::TYPE_HTTPS);
     https_server_->ServeFilesFromSourceDirectory(GetChromeTestDataDir());
     content::SetupCrossSiteRedirector(https_server_.get());
-    ASSERT_TRUE(https_server_->Start());
 
     site_engagement::SiteEngagementScore::SetParamValuesForTesting();
     InProcessBrowserTest::SetUp();
@@ -186,6 +193,7 @@
   // InProcessBrowserTest:
   void SetUpOnMainThread() override {
     host_resolver()->AddRule("*", "127.0.0.1");
+    ASSERT_TRUE(https_server_->Start());
 
     KeyedService* keyed_service =
         gcm::GCMProfileServiceFactory::GetForProfile(GetBrowser()->profile());
@@ -2768,17 +2776,26 @@
 
 class PushMessagingIncognitoBrowserTest : public PushMessagingBrowserTest {
  public:
+  PushMessagingIncognitoBrowserTest()
+      : prerender_helper_(base::BindRepeating(
+            &PushMessagingIncognitoBrowserTest::web_contents,
+            base::Unretained(this))) {}
   ~PushMessagingIncognitoBrowserTest() override = default;
 
   // PushMessagingBrowserTest:
   void SetUpOnMainThread() override {
     incognito_browser_ = CreateIncognitoBrowser();
+    prerender_helper_.SetUpOnMainThread(https_server());
     PushMessagingBrowserTest::SetUpOnMainThread();
   }
-
   Browser* GetBrowser() const override { return incognito_browser_; }
 
- private:
+  content::WebContents* web_contents() {
+    return GetBrowser()->tab_strip_model()->GetActiveWebContents();
+  }
+
+ protected:
+  content::test::PrerenderTestHelper prerender_helper_;
   Browser* incognito_browser_ = nullptr;
 };
 
@@ -2798,6 +2815,81 @@
   ASSERT_EQ("false - not subscribed", script_result);
 }
 
+IN_PROC_BROWSER_TEST_F(PushMessagingIncognitoBrowserTest, WarningToCorrectRFH) {
+  ASSERT_TRUE(GetBrowser()->profile()->IsOffTheRecord());
+
+  content::WebContentsConsoleObserver console_observer(web_contents());
+  console_observer.SetPattern(kIncognitoWarningPattern);
+
+  // Filter out the main frame host of the currently active page.
+  content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+  console_observer.SetFilter(base::BindLambdaForTesting(
+      [&](const content::WebContentsConsoleObserver::Message& message) {
+        return message.source_frame == rfh;
+      }));
+
+  std::string script_result;
+
+  ASSERT_TRUE(RunScript("registerServiceWorker()", &script_result));
+  ASSERT_EQ("ok - service worker registered", script_result);
+
+  ASSERT_TRUE(RunScript("documentSubscribePush()", &script_result));
+  ASSERT_EQ("AbortError - Registration failed - permission denied",
+            script_result);
+
+  console_observer.Wait();
+  EXPECT_EQ(1u, console_observer.messages().size());
+}
+
+IN_PROC_BROWSER_TEST_F(PushMessagingIncognitoBrowserTest,
+                       WarningToCorrectRFH_Prerender) {
+  ASSERT_TRUE(GetBrowser()->profile()->IsOffTheRecord());
+
+  const GURL url(https_server()->GetURL(GetTestURL()));
+
+  // Start a prerender with the push messaging test URL.
+  int host_id = prerender_helper_.AddPrerender(url);
+  content::test::PrerenderHostObserver prerender_observer(*web_contents(),
+                                                          host_id);
+  ASSERT_NE(prerender_helper_.GetHostForUrl(url),
+            content::RenderFrameHost::kNoFrameTreeNodeId);
+
+  content::WebContentsConsoleObserver console_observer(web_contents());
+  console_observer.SetPattern(kIncognitoWarningPattern);
+
+  // Filter out the main frame host of the prerendered page.
+  content::RenderFrameHost* prerender_rfh =
+      prerender_helper_.GetPrerenderedMainFrameHost(host_id);
+  console_observer.SetFilter(base::BindLambdaForTesting(
+      [&](const content::WebContentsConsoleObserver::Message& message) {
+        return message.source_frame == prerender_rfh;
+      }));
+
+  std::string script_result;
+
+  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+      prerender_rfh, "registerServiceWorker()", &script_result));
+  ASSERT_EQ("ok - service worker registered", script_result);
+
+  // Use ExecuteScriptAsync because binding of blink::mojom::PushMessaging
+  // is deferred for the prerendered page. Script execution will finish after
+  // the activation.
+  ExecuteScriptAsync(prerender_rfh, "documentSubscribePush()");
+
+  // Activate the prerendered page and wait for a response of script execution.
+  content::DOMMessageQueue message_queue;
+  prerender_helper_.NavigatePrimaryPage(url);
+  // Make sure that the prerender was activated.
+  ASSERT_TRUE(prerender_observer.was_activated());
+  do {
+    ASSERT_TRUE(message_queue.WaitForMessage(&script_result));
+  } while (script_result !=
+           "\"AbortError - Registration failed - permission denied\"");
+
+  console_observer.Wait();
+  EXPECT_EQ(1u, console_observer.messages().size());
+}
+
 class PushMessagingDisallowSenderIdsBrowserTest
     : public PushMessagingBrowserTest {
  public:
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc
index 3c1e04b..548b0e2 100644
--- a/chrome/browser/push_messaging/push_messaging_service_impl.cc
+++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -58,7 +58,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
@@ -179,14 +178,6 @@
       "Push message received" /* event_name */, message_id, event_metadata);
 }
 
-content::RenderFrameHost* GetMainFrameForRenderFrameHost(
-    content::RenderFrameHost* render_frame_host) {
-  content::WebContents* web_contents =
-      content::WebContents::FromRenderFrameHost(render_frame_host);
-
-  return web_contents ? web_contents->GetMainFrame() : nullptr;
-}
-
 PendingMessage::PendingMessage(std::string app_id, gcm::IncomingMessage message)
     : app_id(std::move(app_id)),
       message(std::move(message)),
@@ -779,13 +770,9 @@
   }
 
   if (!options->user_visible_only) {
-    content::RenderFrameHost* main_frame =
-        GetMainFrameForRenderFrameHost(render_frame_host);
-
-    if (main_frame) {
-      main_frame->AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kError,
-                                      kSilentPushUnsupportedMessage);
-    }
+    render_frame_host->AddMessageToConsole(
+        blink::mojom::ConsoleMessageLevel::kError,
+        kSilentPushUnsupportedMessage);
 
     SubscribeEndWithError(
         std::move(callback),
@@ -883,13 +870,10 @@
   if (!push_messaging::IsVapidKey(application_server_key_string)) {
     content::RenderFrameHost* render_frame_host =
         content::RenderFrameHost::FromID(render_process_id, render_frame_id);
-    content::RenderFrameHost* main_frame =
-        GetMainFrameForRenderFrameHost(render_frame_host);
-
     if (base::FeatureList::IsEnabled(
             features::kPushMessagingDisallowSenderIDs)) {
-      if (main_frame) {
-        main_frame->AddMessageToConsole(
+      if (render_frame_host) {
+        render_frame_host->AddMessageToConsole(
             blink::mojom::ConsoleMessageLevel::kError,
             kSenderIdRegistrationDisallowedMessage);
       }
@@ -897,8 +881,8 @@
           std::move(register_callback),
           blink::mojom::PushRegistrationStatus::UNSUPPORTED_GCM_SENDER_ID);
       return;
-    } else if (main_frame) {
-      main_frame->AddMessageToConsole(
+    } else if (render_frame_host) {
+      render_frame_host->AddMessageToConsole(
           blink::mojom::ConsoleMessageLevel::kWarning,
           kSenderIdRegistrationDeprecatedMessage);
     }
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher.cc b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
index d791a27b..559f584 100644
--- a/chrome/browser/resource_coordinator/tab_activity_watcher.cc
+++ b/chrome/browser/resource_coordinator/tab_activity_watcher.cc
@@ -402,11 +402,6 @@
 
   // Collect current ForegroundedOrClosedMetrics and send to ukm.
   void LogForegroundedOrClosedMetrics(bool is_foregrounded) {
-    // If background time logging is disabled, then we only log the case where
-    // the label_id_ != 0 (a feature is logged and a label has not been logged).
-    if (DisableBackgroundLogWithTabRanker() && label_id_ == 0)
-      return;
-
     TabMetricsLogger::ForegroundedOrClosedMetrics metrics;
     metrics.is_foregrounded = is_foregrounded;
     metrics.is_discarded = discarded_since_backgrounded_;
diff --git a/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc b/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc
index c9309ec..1232816 100644
--- a/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_activity_watcher_browsertest.cc
@@ -567,9 +567,17 @@
       0, {TabStripModel::GestureType::kOther});
   test_clock.Advance(base::TimeDelta::FromMinutes(1));
 
-  // No tab metrics should be logged till now.
+  // TabManager_TabMetrics should not have been logged yet.
   EXPECT_EQ(0, ukm_entry_checker_->NumNewEntriesRecorded(kTabMetricsEntryName));
 
+  // TabManager_Background_ForegroundedOrClosed should have been logged when
+  // tab@0 was activated.
+  ukm_entry_checker_->ExpectNewEntry(
+      kFOCEntryName, test_urls_[0],
+      {{TabManager_Background_ForegroundedOrClosed::kIsForegroundedName, 1},
+       {TabManager_Background_ForegroundedOrClosed::kLabelIdName, 0},
+       {TabManager_Background_ForegroundedOrClosed::kIsDiscardedName, 0}});
+
   // Logs tab@1.
   LogTabFeaturesAt(1);
   {
@@ -629,14 +637,23 @@
   CloseBrowserSynchronously(browser());
   {
     SCOPED_TRACE("");
-    // Close Browser should log a ForegroundedOrClosed event for tab@2 with
-    // correct label_id.
+    // No ForegroundedOrClosed event is logged for tab@1 because it was
+    // foregrounded. The event should be logged for tab@0 and tab@2.
+
+    // tab@2
     ukm_entry_checker_->ExpectNewEntry(
         kFOCEntryName, test_urls_[2],
         {{TabManager_Background_ForegroundedOrClosed::kIsForegroundedName, 0},
          {TabManager_Background_ForegroundedOrClosed::kLabelIdName,
           4 * kIdShift},
          {TabManager_Background_ForegroundedOrClosed::kIsDiscardedName, 0}});
+
+    // tab@0
+    ukm_entry_checker_->ExpectNewEntry(
+        kFOCEntryName, test_urls_[0],
+        {{TabManager_Background_ForegroundedOrClosed::kIsForegroundedName, 0},
+         {TabManager_Background_ForegroundedOrClosed::kLabelIdName, 0},
+         {TabManager_Background_ForegroundedOrClosed::kIsDiscardedName, 0}});
   }
 }
 
diff --git a/chrome/browser/resource_coordinator/tab_manager_features.h b/chrome/browser/resource_coordinator/tab_manager_features.h
index e0959a21..2cb377d 100644
--- a/chrome/browser/resource_coordinator/tab_manager_features.h
+++ b/chrome/browser/resource_coordinator/tab_manager_features.h
@@ -33,7 +33,7 @@
 // Gets number of oldest tabs that should be logged by TabRanker.
 int GetNumOldestTabsToLogWithTabRanker();
 
-// Whether to disable background time TabMetrics log.
+// Whether to disable recording of the TabManager_TabMetrics UKM.
 bool DisableBackgroundLogWithTabRanker();
 
 // Gets reload count penalty parameter for TabRanker.
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index cfdad06..5e995fa6 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -135,7 +135,6 @@
         "sync_file_system_internals:closure_compile",
         "tab_search:closure_compile",
         "usb_internals:closure_compile",
-        "web_app_internals:closure_compile",
       ]
     }
     if (is_win || is_android || is_linux || is_chromeos) {
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ar.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ar.xtb
index eeb0659..0f44d80 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ar.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ar.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">عرض قائمة الروابط</translation>
 <translation id="8656888282555543604">تفعيل ميزة تسجيل لغة برايل</translation>
 <translation id="8659501358298941449">القوائم المنسدلة</translation>
+<translation id="8666733765751421568">نهاية <ph name="TYPE" /></translation>
 <translation id="867187640362843212">العنوان الخامس</translation>
 <translation id="8693391540059827073">الفصل المفضَّل لديّ</translation>
 <translation id="8696284982970258155">شمّامي</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_as.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_as.xtb
index d6ead32..30f48dbe 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_as.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_as.xtb
@@ -1061,6 +1061,7 @@
 <translation id="8653646212587894517">লিংকৰ সূচী দেখুৱাওক</translation>
 <translation id="8656888282555543604">ব্ৰেইলি লগ ইন সক্ষম কৰক</translation>
 <translation id="8659501358298941449">ড্ৰপ ডাউনৰ সূচী</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> সমাপ্ত</translation>
 <translation id="867187640362843212">শিৰোনাম ৫</translation>
 <translation id="8693391540059827073">মোৰ প্ৰিয় ঋতু</translation>
 <translation id="8696284982970258155">HoneyDew</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bn.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bn.xtb
index 89274d7..ae011a0 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bn.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_bn.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">লিঙ্কের তালিকাগুলি দেখান</translation>
 <translation id="8656888282555543604">ব্রেইল লগ-ইন চালু করুন</translation>
 <translation id="8659501358298941449">ড্রপ-ডাউন তালিকা</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> শেষ</translation>
 <translation id="867187640362843212">শিরোনাম ৫</translation>
 <translation id="8693391540059827073">আমার প্রিয় ঋতু</translation>
 <translation id="8696284982970258155">হানিডিউ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_de.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_de.xtb
index 915cde6..e17c0d6b4 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_de.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_de.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">Linkliste anzeigen</translation>
 <translation id="8656888282555543604">Braille-Protokollierung aktivieren</translation>
 <translation id="8659501358298941449">Drop-down-Listen</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> Ende</translation>
 <translation id="867187640362843212">Überschrift 5</translation>
 <translation id="8693391540059827073">Meine Lieblingsjahreszeit</translation>
 <translation id="8696284982970258155">Honigmelone</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_es-419.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_es-419.xtb
index 88de0f0..f991714 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_es-419.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_es-419.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">Mostrar la lista de vínculos</translation>
 <translation id="8656888282555543604">Habilitar el acceso con braille</translation>
 <translation id="8659501358298941449">Listas desplegables</translation>
+<translation id="8666733765751421568">Final de <ph name="TYPE" /></translation>
 <translation id="867187640362843212">Encabezado 5</translation>
 <translation id="8693391540059827073">Mi estación favorita</translation>
 <translation id="8696284982970258155">Ambrosía</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_eu.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_eu.xtb
index a714bf3d..81f0ea3d 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_eu.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_eu.xtb
@@ -1061,6 +1061,7 @@
 <translation id="8653646212587894517">Erakutsi esteken zerrenda</translation>
 <translation id="8656888282555543604">Gaitu braille-teklatua erregistratzeko aukera</translation>
 <translation id="8659501358298941449">Goitibeherako zerrendak</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> den testuaren amaiera</translation>
 <translation id="867187640362843212">5. goiburua</translation>
 <translation id="8693391540059827073">Gogoko dudan urte-sasoia</translation>
 <translation id="8696284982970258155">Ezti-ihintzaren kolorekoa</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_fr.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_fr.xtb
index 1943e3c9..15a9185 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_fr.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_fr.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">Afficher la liste des liens</translation>
 <translation id="8656888282555543604">Activer la journalisation des caractères braille</translation>
 <translation id="8659501358298941449">Listes déroulantes</translation>
+<translation id="8666733765751421568">Fin de <ph name="TYPE" /></translation>
 <translation id="867187640362843212">Titre 5</translation>
 <translation id="8693391540059827073">Ma saison préférée</translation>
 <translation id="8696284982970258155">Bleu dragée clair</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb
index e1227df..22a0f8d 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">Mostra a lista de ligazóns</translation>
 <translation id="8656888282555543604">Activar rexistro de braille</translation>
 <translation id="8659501358298941449">Listas despregables</translation>
+<translation id="8666733765751421568">Fin de <ph name="TYPE" /></translation>
 <translation id="867187640362843212">Título 5</translation>
 <translation id="8693391540059827073">A miña estación favorita</translation>
 <translation id="8696284982970258155">Verde primavera pastel</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gu.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gu.xtb
index 7b2792f30..ae7412a2 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gu.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gu.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">લિંક્સની સૂચિ બતાવો</translation>
 <translation id="8656888282555543604">બ્રેઇલ લૉગિંગ ચાલુ કરો</translation>
 <translation id="8659501358298941449">ડ્રૉપ-ડાઉન સૂચિ</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> અંત</translation>
 <translation id="867187640362843212">મથાળું 5</translation>
 <translation id="8693391540059827073">મારી મનપસંદ ઋતુ</translation>
 <translation id="8696284982970258155">હનીડ્યૂ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ml.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ml.xtb
index f42c9cf..bbee69be 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ml.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ml.xtb
@@ -1061,6 +1061,7 @@
 <translation id="8653646212587894517">ലിങ്കുകളുടെ ലിസ്റ്റ് കാണിക്കുക</translation>
 <translation id="8656888282555543604">ബ്രെയിലി ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക</translation>
 <translation id="8659501358298941449">ഡ്രോപ്പ് ഡൗൺ ലിസ്റ്റുകൾ</translation>
+<translation id="8666733765751421568">അവസാനം <ph name="TYPE" /></translation>
 <translation id="867187640362843212">ശീർഷകം 5</translation>
 <translation id="8693391540059827073">എന്റെ പ്രിയപ്പെട്ട ഋതു</translation>
 <translation id="8696284982970258155">ഹണിഡ്യൂ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ne.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ne.xtb
index 2bba029..da5b923 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ne.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ne.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">लिङ्कहरूको सूची देखाउनुहोस्</translation>
 <translation id="8656888282555543604">ब्रेल लगिङ सक्षम पार्नुहोस्</translation>
 <translation id="8659501358298941449">ड्रप-डाउन सूचीहरू</translation>
+<translation id="8666733765751421568">अन्तिम <ph name="TYPE" /></translation>
 <translation id="867187640362843212">शिर्षक 5</translation>
 <translation id="8693391540059827073">मेरो मन पर्ने मौसम</translation>
 <translation id="8696284982970258155">मधुरसको रङ्ग</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_or.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_or.xtb
index 2f42bb1..d4bfac45 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_or.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_or.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">ଲିଙ୍କ୍‌ଗୁଡ଼ିକର ତାଲିକା ଦେଖାନ୍ତୁ</translation>
 <translation id="8656888282555543604">ବ୍ରେଲି ଲଗ୍ ଇନ୍ ସକ୍ଷମ କରନ୍ତୁ</translation>
 <translation id="8659501358298941449">ଡ୍ରପ୍-ଡାଉନ୍ ତାଲିକାଗୁଡ଼ିକ</translation>
+<translation id="8666733765751421568"><ph name="TYPE" />ର ଶେଷ</translation>
 <translation id="867187640362843212">ଶୀର୍ଷକ 5</translation>
 <translation id="8693391540059827073">ମୋ ପସନ୍ଦର ଋତୁ</translation>
 <translation id="8696284982970258155">ହନିଡ୍ୟୁ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb
index 534baea1..e12bf3f 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_pa.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">ਲਿੰਕ ਸੂਚੀ ਦਿਖਾਓ</translation>
 <translation id="8656888282555543604">ਬ੍ਰੇਲ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="8659501358298941449">ਡ੍ਰੌਪ-ਡਾਊਨ ਸੂਚੀਆਂ</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> ਖਤਮ</translation>
 <translation id="867187640362843212">ਸਿਰਲੇਖ 5</translation>
 <translation id="8693391540059827073">ਮੇਰਾ ਮਨਪਸੰਦ ਮੌਸਮ</translation>
 <translation id="8696284982970258155">ਖਰਬੂਜੇ ਰੰਗੀ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sq.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sq.xtb
index 463d984..608a70a 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sq.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sq.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">Shfaqe listën e lidhjeve</translation>
 <translation id="8656888282555543604">Aktivizo regjistrimin për breil</translation>
 <translation id="8659501358298941449">Listat zbritëse</translation>
+<translation id="8666733765751421568">Fundi i <ph name="TYPE" /></translation>
 <translation id="867187640362843212">Titulli 5</translation>
 <translation id="8693391540059827073">Stina ime e preferuar</translation>
 <translation id="8696284982970258155">Vesë mjalti</translation>
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 2dbcb561..a934ab7 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">இணைப்புகளின் பட்டியலைக் காட்டு</translation>
 <translation id="8656888282555543604">பிரெய்ல் பதிவிடலை இயக்கு</translation>
 <translation id="8659501358298941449">கீழ் தோன்றும் பட்டிகள்</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> முடிந்தது</translation>
 <translation id="867187640362843212">தலைப்பு 5</translation>
 <translation id="8693391540059827073">எனக்குப் பிடித்த பருவகாலம்</translation>
 <translation id="8696284982970258155">ஹனிடியூ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_te.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_te.xtb
index 849e572..fe2bcd4b 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_te.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_te.xtb
@@ -1063,6 +1063,7 @@
 <translation id="8653646212587894517">లింక్‌ల జాబితాను చూపండి</translation>
 <translation id="8656888282555543604">బ్రెయిలీ లాగింగ్‌ను ప్రారంభించు</translation>
 <translation id="8659501358298941449">డ్రాప్-డౌన్ లిస్ట్‌లు</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> ముగింపు</translation>
 <translation id="867187640362843212">శీర్షిక 5</translation>
 <translation id="8693391540059827073">నాకు ఇష్టమైన సీజన్</translation>
 <translation id="8696284982970258155">హనీడ్యూ పండు రంగు</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ur.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ur.xtb
index ef2c9d8..0e72475 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ur.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ur.xtb
@@ -1063,6 +1063,7 @@
 <translation id="8653646212587894517">لنکس کی فہرست دکھائیں</translation>
 <translation id="8656888282555543604">بریل لاگنگ کو فعال کریں</translation>
 <translation id="8659501358298941449">ڈراپ ڈاؤن فہرستیں</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> اختتام</translation>
 <translation id="867187640362843212">سرخی 5</translation>
 <translation id="8693391540059827073">میرا پسندیدہ موسم</translation>
 <translation id="8696284982970258155">ہنی ڈیو</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-CN.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-CN.xtb
index 2d6b2ba..e13a32c 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-CN.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-CN.xtb
@@ -1062,6 +1062,7 @@
 <translation id="8653646212587894517">显示链接列表</translation>
 <translation id="8656888282555543604">启用盲文记录功能</translation>
 <translation id="8659501358298941449">下拉列表</translation>
+<translation id="8666733765751421568">已到<ph name="TYPE" />末尾</translation>
 <translation id="867187640362843212">5 级标题标记</translation>
 <translation id="8693391540059827073">我最喜爱的季节</translation>
 <translation id="8696284982970258155">蜜瓜绿色</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-HK.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-HK.xtb
index 37eadf3f..c786d3e 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-HK.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_zh-HK.xtb
@@ -1061,7 +1061,7 @@
 <translation id="8653646212587894517">顯示連結清單</translation>
 <translation id="8656888282555543604">啟用點字記錄</translation>
 <translation id="8659501358298941449">下拉式清單</translation>
-<translation id="8666733765751421568"><ph name="TYPE" />中已沒有其他項目</translation>
+<translation id="8666733765751421568"><ph name="TYPE" /> 結束</translation>
 <translation id="867187640362843212">標題 5</translation>
 <translation id="8693391540059827073">我的最愛季節</translation>
 <translation id="8696284982970258155">蜜瓜綠色</translation>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html
index 0b25348..a23af26 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.html
@@ -30,7 +30,9 @@
       <div slot="content" id="content-container"
           class="landscape-vertical-centered">
         <div class="content" id="intro-text"></div>
-        <div class="line" hidden$="[[!newLayoutEnabled_]]"></div>
+        <div hidden$="[[!newLayoutEnabled_]]">
+          <div class="line" hidden$="[[isMinorMode_]]"></div>
+        </div>
         <div id="column-container" class="flex layout horizontal">
           <div id="value-prop-container" hidden$="[[newLayoutEnabled_]]">
             <div class="flex layout horizontal center">
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js
index 6315b37..8fe87158 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js
+++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_value_prop.js
@@ -332,6 +332,9 @@
         zippy.setAttribute('step', i);
         if (!this.newLayoutEnabled_) {
           zippy.setAttribute('hide-line', true);
+        } else if (this.isMinorMode_) {
+          zippy.setAttribute('hide-line', true);
+          zippy.setAttribute('card-style', true);
         }
 
         var title = document.createElement('div');
diff --git a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.css b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.css
index dfa04e6..d2c6b805 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.css
+++ b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.css
@@ -50,3 +50,26 @@
 .indent {
   padding: 0 0 6px 36px;
 }
+
+#container[cardStyle] {
+  border-radius: 8px;
+  box-shadow: var(--cr-elevation-1);
+  margin: 10px 10px 10px 0;
+  padding: 20px 0 20px 16px;
+}
+
+#container[cardStyle] .sub-title {
+  font-family: var(--oobe-header-font-family);
+  font-size: 15px;
+  font-weight: 500;
+  line-height: 22px;
+}
+
+#container[cardStyle] #description {
+  line-height: 20px;
+  padding: 0;
+}
+
+#container[cardStyle] .icon {
+  margin: auto 0;
+}
diff --git a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.html b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.html
index e00902d..fb3c9637 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.html
+++ b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.html
@@ -39,7 +39,7 @@
     </template>
     <template is="dom-if" if="[[!expandStyle]]">
       <div id="container" class="flex layout horizontal"
-          expandStyle$="[[expandStyle]]">
+          expandStyle$="[[expandStyle]]" cardStyle$="[[cardStyle]]">
         <div class="icon">
           <webview class="icon-view" src="[[iconSrc]]" tabindex="-1"></webview>
         </div>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.js b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.js
index c1ac84e..38109d43 100644
--- a/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.js
+++ b/chrome/browser/resources/chromeos/assistant_optin/setting_zippy.js
@@ -30,6 +30,11 @@
       type: Boolean,
       value: false,
     },
+
+    cardStyle: {
+      type: Boolean,
+      value: false,
+    },
   },
 
   /**
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html
index 0510198..1be91ea 100644
--- a/chrome/browser/resources/new_tab_page/app.html
+++ b/chrome/browser/resources/new_tab_page/app.html
@@ -5,6 +5,7 @@
     --ntp-one-google-bar-height: 56px;
     --ntp-search-box-width: 337px;
     --ntp-module-width: var(--ntp-search-box-width);
+    --ntp-module-border-radius: 5px;
   }
 
   @media (min-width: 560px) {
@@ -26,6 +27,7 @@
   }
 
   :host([modules-redesigned-enabled_]) {
+    --ntp-module-border-radius: 24px;
     --ntp-module-width: 361px;
   }
 
diff --git a/chrome/browser/resources/new_tab_page/customize_modules.js b/chrome/browser/resources/new_tab_page/customize_modules.js
index acfa29f..8768aa0 100644
--- a/chrome/browser/resources/new_tab_page/customize_modules.js
+++ b/chrome/browser/resources/new_tab_page/customize_modules.js
@@ -167,6 +167,9 @@
             this.discountToggle_.initiallyEnabled) {
       ChromeCartProxy.getInstance().handler.setDiscountEnabled(
           this.discountToggle_.enabled);
+      chrome.metricsPrivate.recordUserAction(`NewTabPage.Carts.${
+          this.discountToggle_.enabled ? 'EnableDiscount' :
+                                         'DisableDiscount'}`);
     }
   }
 
diff --git a/chrome/browser/resources/new_tab_page/modules/cart/module.js b/chrome/browser/resources/new_tab_page/modules/cart/module.js
index fe73d6bc..19b3671 100644
--- a/chrome/browser/resources/new_tab_page/modules/cart/module.js
+++ b/chrome/browser/resources/new_tab_page/modules/cart/module.js
@@ -13,6 +13,7 @@
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {I18nBehavior, loadTimeData} from '../../i18n_setup.js';
+import {recordOccurence} from '../../metrics_utils.js';
 import {$$} from '../../utils.js';
 import {ModuleDescriptor} from '../module_descriptor.js';
 
@@ -403,6 +404,8 @@
         loadTimeData.getString('modulesCartDiscountConsentRejectConfirmation');
     $$(this, '#confirmDiscountConsentToast').show();
     ChromeCartProxy.getInstance().handler.onDiscountConsentAcknowledged(false);
+    chrome.metricsPrivate.recordUserAction(
+        'NewTabPage.Carts.RejectDiscountConsent');
   }
 
   /** @private */
@@ -412,6 +415,8 @@
         loadTimeData.getString('modulesCartDiscountConsentAcceptConfirmation');
     $$(this, '#confirmDiscountConsentToast').show();
     ChromeCartProxy.getInstance().handler.onDiscountConsentAcknowledged(true);
+    chrome.metricsPrivate.recordUserAction(
+        'NewTabPage.Carts.AcceptDiscountConsent');
   }
 
   /** @private */
@@ -437,15 +442,38 @@
   // getWarmWelcomeVisible.
   const {consentVisible} = await ChromeCartProxy.getInstance()
                                .handler.getDiscountConsentCardVisible();
+
   const {welcomeVisible} =
       await ChromeCartProxy.getInstance().handler.getWarmWelcomeVisible();
   const {carts} =
       await ChromeCartProxy.getInstance().handler.getMerchantCarts();
   chrome.metricsPrivate.recordSmallCount(
       'NewTabPage.Carts.CartCount', carts.length);
+
   if (carts.length === 0) {
     return null;
   }
+
+  if (loadTimeData.getBoolean('ruleBasedDiscountEnabled')) {
+    if (consentVisible) {
+      recordOccurence('NewTabPage.Carts.DiscountConsentShow');
+    }
+
+    let discountedCartCount = 0;
+
+    for (let i = 0; i < carts.length; i++) {
+      const cart = carts[i];
+      if (cart.discountText) {
+        discountedCartCount++;
+        chrome.metricsPrivate.recordSmallCount(
+            'NewTabPage.Carts.DiscountAt', i);
+      }
+    }
+
+    chrome.metricsPrivate.recordSmallCount(
+        'NewTabPage.Carts.DiscountCountAtLoad', discountedCartCount);
+  }
+
   const element = new ChromeCartModuleElement();
   if (welcomeVisible) {
     element.headerChipText = loadTimeData.getString('modulesCartHeaderNew');
diff --git a/chrome/browser/resources/new_tab_page/modules/module_wrapper.html b/chrome/browser/resources/new_tab_page/modules/module_wrapper.html
index 1a17f54e..a8d24da 100644
--- a/chrome/browser/resources/new_tab_page/modules/module_wrapper.html
+++ b/chrome/browser/resources/new_tab_page/modules/module_wrapper.html
@@ -2,7 +2,7 @@
   :host {
     background-color: var(--ntp-background-override-color);
     border: solid var(--ntp-border-color) 1px;
-    border-radius: 5px;
+    border-radius: var(--ntp-module-border-radius);
     box-sizing: border-box;
     display: block;
     overflow: hidden;
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js
index 35b862d..c9eed8d 100644
--- a/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -202,9 +202,8 @@
       ],
       [PrinterType.LOCAL_PRINTER, DestinationStorePrinterSearchStatus.START],
     ]);
-
-    // TODO (rbpotter): Remove the code below once this flag and policy are no
-    // longer supported. Remove the privet flag in M90.
+    // TODO (https://crbug.com/1223593): Remove the code below once this policy
+    // is no longer supported.
     if (loadTimeData.getBoolean('forceEnablePrivetPrinting')) {
       this.destinationSearchStatus_.set(
           PrinterType.PRIVET_PRINTER,
@@ -414,6 +413,8 @@
     // fetched by Javascript instead of through the native layer (which
     // startLoadDestinations_ invokes).
     for (const printerType of this.typesToSearch_) {
+      // TODO (https://crbug.com/1223593): Remove the code below once this
+      // policy is no longer supported.
       if (printerType !== PrinterType.CLOUD_PRINTER &&
           (printerType !== PrinterType.PRIVET_PRINTER ||
            loadTimeData.getBoolean('forceEnablePrivetPrinting'))) {
@@ -616,8 +617,8 @@
     const origins = [];
     if (isLocal) {
       origins.push(DestinationOrigin.LOCAL);
-      // TODO (rbpotter): Remove the code below once this flag and policy are no
-      // longer supported. Remove the privet flag in M90.
+      // TODO (https://crbug.com/1223593): Remove the code below once this
+      // policy is no longer supported.
       if (loadTimeData.getBoolean('forceEnablePrivetPrinting')) {
         origins.push(DestinationOrigin.PRIVET);
       }
diff --git a/chrome/browser/resources/print_preview/ui/destination_settings.js b/chrome/browser/resources/print_preview/ui/destination_settings.js
index 1159167e..4dfcd75 100644
--- a/chrome/browser/resources/print_preview/ui/destination_settings.js
+++ b/chrome/browser/resources/print_preview/ui/destination_settings.js
@@ -257,8 +257,8 @@
     let filteredDestinations = recentDestinations;
     // Remove unsupported privet printers from the sticky settings,
     // to free up these spots for supported printers.
-    // TODO(rbpotter): Remove this logic a milestone after the policy and flag
-    // have been removed.
+    // TODO (https://crbug.com/1223593): Remove the code below once this policy
+    // is no longer supported.
     if (!loadTimeData.getBoolean('forceEnablePrivetPrinting')) {
       filteredDestinations = recentDestinations.filter(d => {
         return d.origin !== DestinationOrigin.PRIVET;
diff --git a/chrome/browser/resources/settings/about_page/about_page.js b/chrome/browser/resources/settings/about_page/about_page.js
index 6dab6d1..14e8d1b3 100644
--- a/chrome/browser/resources/settings/about_page/about_page.js
+++ b/chrome/browser/resources/settings/about_page/about_page.js
@@ -125,22 +125,19 @@
   constructor() {
     super();
 
-    /** @private {?AboutPageBrowserProxy} */
-    this.aboutBrowserProxy_ = null;
+    /** @private {!AboutPageBrowserProxy} */
+    this.aboutBrowserProxy_ = AboutPageBrowserProxyImpl.getInstance();
 
-    /** @private {?LifetimeBrowserProxy} */
-    this.lifetimeBrowserProxy_ = null;
+    /** @private {!LifetimeBrowserProxy} */
+    this.lifetimeBrowserProxy_ = LifetimeBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.aboutBrowserProxy_ = AboutPageBrowserProxyImpl.getInstance();
     this.aboutBrowserProxy_.pageReady();
 
-    this.lifetimeBrowserProxy_ = LifetimeBrowserProxyImpl.getInstance();
-
     // <if expr="not chromeos">
     this.startListening_();
     if (Router.getInstance().getQueryParameters().get('checkForUpdate') ===
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js
index 96dc920..ed82c04 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js
+++ b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js
@@ -75,16 +75,14 @@
   constructor() {
     super();
 
-    /** @private {?PasswordManagerProxy} */
-    this.passwordManager_ = null;
+    /** @private {!PasswordManagerProxy} */
+    this.passwordManager_ = PasswordManagerImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    // Set the manager. These can be overridden by tests.
-    this.passwordManager_ = PasswordManagerImpl.getInstance();
     this.$.dialog.showModal();
     focusWithoutInk(this.$.cancel);
   }
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_list_item.js b/chrome/browser/resources/settings/autofill_page/password_check_list_item.js
index af1b5a2..e7f23ff2 100644
--- a/chrome/browser/resources/settings/autofill_page/password_check_list_item.js
+++ b/chrome/browser/resources/settings/autofill_page/password_check_list_item.js
@@ -83,15 +83,7 @@
   constructor() {
     super();
 
-    /** @private {?PasswordManagerProxy} */
-    this.passwordManager_ = null;
-  }
-
-  /** @override */
-  connectedCallback() {
-    super.connectedCallback();
-
-    // Set the manager. These can be overridden by tests.
+    /** @private {!PasswordManagerProxy} */
     this.passwordManager_ = PasswordManagerImpl.getInstance();
   }
 
diff --git a/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.js b/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.js
index 6406a3c..806a618a 100644
--- a/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.js
+++ b/chrome/browser/resources/settings/autofill_page/password_remove_confirmation_dialog.js
@@ -45,18 +45,14 @@
   constructor() {
     super();
 
-    /**
-     * @private {?PasswordManagerProxy}
-     */
-    this.passwordManager_ = null;
+    /** @private {!PasswordManagerProxy} */
+    this.passwordManager_ = PasswordManagerImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    // Set the manager. These can be overridden by tests.
-    this.passwordManager_ = PasswordManagerImpl.getInstance();
     this.$.dialog.showModal();
   }
 
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
index 1501fb3..da94ce0 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_list_handler.js
@@ -149,8 +149,8 @@
   constructor() {
     super();
 
-    /** @private {?PasswordManagerProxy} */
-    this.passwordManager_ = null;
+    /** @private {!PasswordManagerProxy} */
+    this.passwordManager_ = PasswordManagerImpl.getInstance();
   }
 
   /** @override */
@@ -169,8 +169,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.passwordManager_ = PasswordManagerImpl.getInstance();
-
     const extractFirstAccountEmail = accounts => {
       this.firstSignedInAccountEmail_ =
           accounts.length > 0 ? accounts[0].email : '';
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js
index 7eb8293..ec0c007 100644
--- a/chrome/browser/resources/settings/autofill_page/passwords_section.js
+++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -311,8 +311,9 @@
      */
     this.activeDialogAnchorStack_ = [];
 
-    /** @private {?PasswordManagerProxy} */
-    this.passwordManager_ = null;
+    /** @private {!PasswordManagerProxy} */
+    this.passwordManager_ = PasswordManagerImpl.getInstance();
+
 
     /** @private {?function(boolean):void} */
     this.setIsOptedInForAccountStorageListener_ = null;
@@ -354,9 +355,6 @@
     this.setIsOptedInForAccountStorageListener_ =
         setIsOptedInForAccountStorageListener;
 
-    // Set the manager. These can be overridden by tests.
-    this.passwordManager_ = PasswordManagerImpl.getInstance();
-
     // <if expr="chromeos">
     // If the user's account supports the password check, an auth token will be
     // required in order for them to view or export passwords. Otherwise there
diff --git a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
index 26528ded..edb97be 100644
--- a/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
+++ b/chrome/browser/resources/settings/chrome_cleanup_page/chrome_cleanup_page.js
@@ -296,8 +296,8 @@
     /** @private {!ChromeCleanerScannerResults} */
     this.emptyChromeCleanerScannerResults_ = {'files': [], 'registryKeys': []};
 
-    /** @private {?ChromeCleanupProxy} */
-    this.browserProxy_ = null;
+    /** @private {!ChromeCleanupProxy} */
+    this.browserProxy_ = ChromeCleanupProxyImpl.getInstance();
 
     /** @private {?function()} */
     this.doAction_ = null;
@@ -326,7 +326,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = ChromeCleanupProxyImpl.getInstance();
     this.cardStateToComponentsMap_ = this.buildCardStateToComponentsMap_();
 
     this.addWebUIListener('chrome-cleanup-on-idle', this.onIdle_.bind(this));
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index e43fa92..ae2d16b 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -387,6 +387,7 @@
     "chromeos/os_apps_page/app_management_page/app_item.m.js",
     "chromeos/os_apps_page/app_management_page/app_management_page.m.js",
     "chromeos/os_apps_page/app_management_page/arc_detail_view.m.js",
+    "chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.m.js",
     "chromeos/os_apps_page/app_management_page/browser_proxy.m.js",
     "chromeos/os_apps_page/app_management_page/chrome_app_detail_view.m.js",
     "chromeos/os_apps_page/app_management_page/constants.m.js",
@@ -535,6 +536,7 @@
     "os_about_page:closure_compile_module",
     "os_apps_page:closure_compile_module",
     "os_apps_page/app_management_page:closure_compile_module",
+    "os_apps_page/app_management_page/borealis_page:closure_compile_module",
     "os_apps_page/app_management_page/plugin_vm_page:closure_compile_module",
     "os_files_page:closure_compile_module",
     "os_languages_page:closure_compile_module",
@@ -686,6 +688,7 @@
     "os_about_page:polymer3_elements",
     "os_apps_page:polymer3_elements",
     "os_apps_page/app_management_page:polymer3_elements",
+    "os_apps_page/app_management_page/borealis_page:polymer3_elements",
     "os_apps_page/app_management_page/plugin_vm_page:polymer3_elements",
     "os_apps_page/app_notifications_page:web_components",
     "os_files_page:web_components",
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
index bc71360e..7406eaf 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/BUILD.gn
@@ -69,6 +69,7 @@
     ":store_client.m",
     "../..:os_route.m",
     "../../..:router",
+    "./borealis_page:borealis_detail_view.m",
     "./plugin_vm_page:plugin_vm_detail_view.m",
     "//ui/webui/resources/js:assert.m",
   ]
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html
index be2919d4..645236e 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.html
@@ -10,6 +10,7 @@
 <link rel="import" href="util.html">
 <link rel="import" href="chrome_app_detail_view.html">
 <link rel="import" href="plugin_vm_page/plugin_vm_detail_view.html">
+<link rel="import" href="borealis_page/borealis_detail_view.html">
 <link rel="import" href="../../os_route.html">
 <link rel="import" href="../../../router.html">
 <link rel="import" href="../../../settings_shared_css.html">
@@ -30,6 +31,8 @@
         </app-management-chrome-app-detail-view>
         <app-management-plugin-vm-detail-view route-id="plugin-vm-detail-view">
         </app-management-plugin-vm-detail-view>
+        <app-management-borealis-detail-view route-id="borealis-detail-view">
+        </app-management-borealis-detail-view>
       </template>
     </app-management-dom-switch>
   </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js
index 79caf03..e7bb86b 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_detail_view.js
@@ -94,6 +94,8 @@
         return 'arc-detail-view';
       case (AppType.kPluginVm):
         return 'plugin-vm-detail-view';
+      case (AppType.kBorealis):
+        return 'borealis-detail-view';
       default:
         assertNotReached();
     }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js
index 81010a49a..7e66989b 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.js
@@ -54,6 +54,8 @@
         return AppManagementEntryPoint.MainViewWebApp;
       case AppType.kPluginVm:
         return AppManagementEntryPoint.MainViewPluginVm;
+      case AppType.kBorealis:
+        return AppManagementEntryPoint.MainViewBorealis;
       default:
         assertNotReached();
     }
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn
new file mode 100644
index 0000000..b889ec3
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/polymer/polymer.gni")
+import("//ui/webui/resources/tools/js_modulizer.gni")
+import("../../../os_settings.gni")
+
+js_type_check("closure_compile_module") {
+  is_polymer3 = true
+  closure_flags = os_settings_closure_flags
+  deps = [ ":borealis_detail_view.m" ]
+}
+
+js_library("borealis_detail_view.m") {
+  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.m.js" ]
+  deps = [
+    "../:constants.m",
+    "../:permission_item.m",
+    "../:pin_to_shelf_item.m",
+    "../:store_client.m",
+    "../:util.m",
+    "../../..:os_route.m",
+    "../../../..:router",
+    "//ui/webui/resources/js:assert.m",
+  ]
+  extra_deps = [ ":borealis_detail_view_module" ]
+}
+
+group("polymer3_elements") {
+  public_deps = [ ":borealis_detail_view_module" ]
+}
+
+polymer_modulizer("borealis_detail_view") {
+  js_file = "borealis_detail_view.js"
+  html_file = "borealis_detail_view.html"
+  html_type = "dom-module"
+  migrated_imports = os_settings_migrated_imports
+  namespace_rewrites = os_settings_namespace_rewrites
+  auto_imports = os_settings_auto_imports
+}
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.html
new file mode 100644
index 0000000..4d2f21d
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.html
@@ -0,0 +1,44 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="../browser_proxy.html">
+<link rel="import" href="../icons.html">
+<link rel="import" href="../permission_item.html">
+<link rel="import" href="../pin_to_shelf_item.html">
+<link rel="import" href="../shared_style.html">
+<link rel="import" href="../store_client.html">
+<link rel="import" href="../util.html">
+<link rel="import" href="../../../os_route.html">
+<link rel="import" href="../../../../router.html">
+<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
+<link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/html/load_time_data.html">
+<link rel="import" href="chrome://resources/html/assert.html">
+
+<dom-module id="app-management-borealis-detail-view">
+  <template>
+    <style include="app-management-shared-css"></style>
+
+    <div class="permission-list">
+      <app-management-pin-to-shelf-item
+          id="pin-to-shelf-setting"
+          class="permission-card-row separated-row header-text"
+          app="[[app_]]">
+      </app-management-pin-to-shelf-item>
+      <div class="permission-card-row">
+        <div class="permission-section-header">
+          <div class="header-text">$i18n{appManagementPermissionsLabel}</div>
+        </div>
+        <div class="permission-list indented-permission-block">
+          <app-management-permission-item
+              id="microphone-permission"
+              class="subpermission-row" icon="app-management:microphone"
+              permission-label="$i18n{appManagementMicrophonePermissionLabel}"
+              permission-type="MICROPHONE">
+          </app-management-permission-item>
+        </div>
+      </div>
+    </div>
+  </template>
+  <script src="borealis_detail_view.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js
new file mode 100644
index 0000000..2ac4421
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/borealis_page/borealis_detail_view.js
@@ -0,0 +1,23 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Polymer({
+  is: 'app-management-borealis-detail-view',
+
+  behaviors: [
+    app_management.AppManagementStoreClient,
+  ],
+
+  properties: {
+    /** @private {App} */
+    app_: Object,
+  },
+
+  attached() {
+    // When the state is changed, get the new selected app and assign it to
+    // |app_|
+    this.watch('app_', state => app_management.util.getSelectedApp(state));
+    this.updateFromStore();
+  },
+});
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js
index 8c1f8ec..c7150268 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.js
@@ -48,6 +48,9 @@
 
 /* #export */ const ArcPermissionType = appManagement.mojom.ArcPermissionType;
 
+/* #export */ const BorealisPermissionType =
+    appManagement.mojom.BorealisPermissionType;
+
 /* #export */ const AppType = apps.mojom.AppType;
 
 /* #export */ const PermissionValueType = apps.mojom.PermissionValueType;
@@ -83,6 +86,7 @@
   OsSettingsMainPage: 9,
   MainViewPluginVm: 10,
   DBusServicePluginVm: 11,
+  MainViewBorealis: 12,
 };
 
 /**
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
index c4f08e71..f7b27a6b 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.html
@@ -18,9 +18,17 @@
           $i18n{appManagementIntentSharingLabel}
         </div>
       </div>
+      <template is="dom-if" if="[[isInTabMode_(app)]]">
+        <div id="tabModeText">
+          <iron-icon icon="cr:info-outline"></iron-icon>
+          [[getAppNameTabModeExplanation_(app)]]
+          <a href="google.com">$i18n{appManagementIntentSharingTabLearnMore}</a>
+        </div>
+      </template>
       <div class="list-frame">
         <cr-radio-group id="isSupportedRadioGroup"
-          selected="[[getSelectedRadioButtonName_(app)]]">
+          selected="[[getSelectedRadioButtonName_(app)]]"
+          disabled="[[isInTabMode_(app)]]">
           <cr-radio-button id="preferred"
             name="preferred"
             label="[[getAppNameRadioButtonLabel_(app)]]">
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.js
index eee5c7e..03400908 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/supported_links_item.js
@@ -52,7 +52,7 @@
    */
   shouldShowIntentSettings_(app) {
     return this.appManagementIntentSettingsEnabled_ &&
-        this.app.supportedLinks.length > 0;
+        app.supportedLinks.length > 0;
   },
 
   /**
@@ -65,6 +65,26 @@
         'appManagementIntentSharingOpenAppLabel', String(app.title));
   },
 
+  /**
+   * @private
+   * @param {!App} app
+   * @return {boolean}
+   */
+  isInTabMode_(app) {
+    return app.type === AppType.kWeb &&
+        app.windowMode === apps.mojom.WindowMode.kBrowser;
+  },
+
+  /**
+   * @private
+   * @param {App} app
+   * @return {string} label for app name radio button
+   */
+  getAppNameTabModeExplanation_(app) {
+    return this.i18n(
+        'appManagementIntentSharingTabExplanation', String(app.title));
+  },
+
   /** @private */
   onClick_() {
     const newState = !this.app.isPreferredApp;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js
index 6c0513d..1f39fb8 100644
--- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js
+++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.js
@@ -8,7 +8,7 @@
 // #import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 // #import {Route, Router} from '../../../router.js';
 // #import {routes} from '../../os_route.m.js';
-// #import {AppType, AppManagementUserAction, ArcPermissionType, OptionalBool, PermissionValueType, Bool, PwaPermissionType, TriState, PluginVmPermissionType, WindowMode} from "./constants.m.js";
+// #import {AppType, AppManagementUserAction, ArcPermissionType, OptionalBool, PermissionValueType, Bool, PwaPermissionType, TriState, PluginVmPermissionType, WindowMode, BorealisPermissionType} from "./constants.m.js";
 // clang-format on
 
 /**
@@ -140,6 +140,8 @@
         return ArcPermissionType[permissionType];
       case AppType.kPluginVm:
         return PluginVmPermissionType[permissionType];
+      case AppType.kBorealis:
+        return BorealisPermissionType[permissionType];
       default:
         assertNotReached();
     }
@@ -231,6 +233,8 @@
         return 'AppManagement.AppDetailViews.WebApp';
       case AppType.kPluginVm:
         return 'AppManagement.AppDetailViews.PluginVmApp';
+      case AppType.kBorealis:
+        return 'AppManagement.AppDetailViews.BorealisApp';
       default:
         assertNotReached();
     }
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
index 0a2e7aa1..d58af8c 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -2,6 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Some deps are missing from build rules in this file.
+# TODO(crbug.com/1226913): Add the missing deps.
+
 import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/polymer/polymer.gni")
 import("//ui/webui/resources/tools/js_modulizer.gni")
@@ -108,6 +111,7 @@
     "..:os_route.m",
     "../..:i18n_setup",
     "../..:router",
+    "../../controls:settings_toggle_button",
     "../keyboard_shortcut_banner:keyboard_shortcut_banner",
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js:i18n_behavior.m",
@@ -305,7 +309,7 @@
   html_type = "dom-module"
   migrated_imports = os_settings_migrated_imports
   namespace_rewrites = os_settings_namespace_rewrites
-  auto_imports = os_settings_auto_imports
+  auto_imports = os_settings_auto_imports + [ "chrome/browser/resources/settings/controls/settings_toggle_button.html|SettingsToggleButtonElement" ]
 }
 
 polymer_modulizer("shared_style") {
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html
index 99d63cc..c4fa668 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html
@@ -217,7 +217,7 @@
       </div>
       <settings-toggle-button id="enableSpellcheckingToggle" class="hr"
           label="$i18n{spellCheckTitle}"
-          pref="{{prefs.browser.enable_spellchecking}}"
+          pref="{{prefs.browser.enable_spellchecking}}" no-set-pref
           disabled="[[isEnableSpellcheckingDisabled_(
               languageSettingsV2Update2Enabled_, spellCheckLanguages_.length)]]"
           on-settings-boolean-control-change="onSpellcheckToggleChange_"
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
index 4d65a2d8..fbfce78 100644
--- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
@@ -299,11 +299,10 @@
   onAddSpellcheckLanguagesDialogClose_() {
     this.showAddSpellcheckLanguagesDialog_ = false;
 
-    if (this.languages.spellCheckOnLanguages.length === 0) {
-      // User closed the dialog right after turning on spell check without any
-      // existing spell check languages - turn off spell checking if this is
-      // the case.
-      this.setPrefValue('browser.enable_spellchecking', false);
+    if (this.languages.spellCheckOnLanguages.length > 0) {
+      // User has at least one spell check language after closing the dialog.
+      // If spell checking is disabled, enabled it.
+      this.setPrefValue('browser.enable_spellchecking', true);
     }
 
     // Because #addSpellcheckLanguages is not statically created (as it is
@@ -366,23 +365,25 @@
   },
 
   /**
-   * @return {string|undefined}
+   * Called whenever the spell check toggle is changed by the user.
    * @param {!Event} e
    * @private
    */
   onSpellcheckToggleChange_(e) {
-    this.languagesMetricsProxy_.recordToggleSpellCheck(e.target.checked);
+    const toggle = /** @type {SettingsToggleButtonElement} */ (e.target);
 
-    if (this.languageSettingsV2Update2Enabled_ && e.target.checked &&
+    this.languagesMetricsProxy_.recordToggleSpellCheck(toggle.checked);
+
+    if (this.languageSettingsV2Update2Enabled_ && toggle.checked &&
         this.languages.spellCheckOnLanguages.length === 0) {
       // In LSV2 Update 2, we never want to enable spell check without the user
       // having a spell check language. When this happens, we try estimating
       // their expected spell check language (their device language, assuming
       // that the user has an input method which supports that language).
       // If that doesn't work, we fall back on prompting the user to enable a
-      // spell check language. If the user dismisses this dialog without adding
-      // a spell check language, we disable spell check again
-      // (see |onAddSpellcheckLanguagesDialogClose_|).
+      // spell check language and immediately disable spell check before this
+      // happens. If the user then adds a spell check language, we finally
+      // enable spell check (see |onAddSpellcheckLanguagesDialogClose_|).
 
       // This assert is safe as prospectiveUILanguage is always defined in
       // languages.js' |createModel_()|.
@@ -399,8 +400,19 @@
         this.languageHelper.toggleSpellCheck(deviceLanguageCode, true);
       } else {
         this.onAddSpellcheckLanguagesClick_();
+
+        // "Undo" the toggle change by reverting it back to the original pref
+        // value. The toggle will be flipped on once the user finishes adding
+        // a spell check language.
+        toggle.resetToPrefValue();
+        // We don't need to commit the pref change below, so early return.
+        return;
       }
     }
+
+    // Manually commit the pref change as we've set noSetPref on the toggle
+    // button.
+    toggle.sendPrefChange();
   },
 
   /**
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index e83113bf..fb8f92e 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -211,7 +211,7 @@
                              "chrome/browser/resources/settings/chromeos/device_page/device_page_browser_proxy.html|BatteryStatus,DevicePageBrowserProxy,DevicePageBrowserProxyImpl,ExternalStorage,IdleBehavior,LidClosedBehavior,NoteAppInfo,NoteAppLockScreenSupport,PowerManagementSettings,PowerSource,getDisplayApi,StorageSpaceState",
                              "chrome/browser/resources/settings/chromeos/deep_linking_behavior.html|DeepLinkingBehavior",
                              "chrome/browser/resources/settings/chromeos/google_assistant_page/google_assistant_browser_proxy.html|GoogleAssistantBrowserProxy,GoogleAssistantBrowserProxyImpl",
-                             "chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.html|GuestOsBrowserProxy, GuestOsBrowserProxyImpl, GuestOsSharedUsbDevice, CROSTINI_TYPE, PLUGIN_VM_TYPE",
+                             "chrome/browser/resources/settings/chromeos/guest_os/guest_os_browser_proxy.html|GuestOsBrowserProxy, GuestOsBrowserProxyImpl, GuestOsSharedUsbDevice, CROSTINI_TYPE, PLUGIN_VM_TYPE, BOREALIS_TYPE",
                              "chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_accounts_browser_proxy.html|KerberosAccount,KerberosAccountsBrowserProxyImpl,KerberosAccountsBrowserProxy,KerberosErrorType,KerberosConfigErrorCode,ValidateKerberosConfigResult",
                              "chrome/browser/resources/settings/chromeos/metrics_recorder.html|recordSettingChange, recordSearch, setUserActionRecorderForTesting,recordPageFocus,recordPageBlur,recordClick,recordNavigation",
                              "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html|MultiDeviceBrowserProxy,MultiDeviceBrowserProxyImpl",
@@ -282,7 +282,7 @@
                              "chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/util.html|getSelectedApp,openMainPage,recordAppManagementUserAction,openAppDetailPage,getAppIcon,getPermission,getPermissionValueBool,createPermission,permissionTypeHandle,toggleOptionalBool,convertOptionalBoolToBool,alphabeticalSort",
                              "chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/store.html|AppManagementStore",
                              "chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.html|PluginVmBrowserProxyImpl,PluginVmBrowserProxy",
-                             "chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.html|Bool,PwaPermissionType,PluginVmPermissionType,ArcPermissionType,AppType,OptionalBool,PermissionValueType,TriState,InstallSource,AppManagementUserAction,AppManagementEntryPointsHistogramName,AppManagementEntryPoint",
+                             "chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/constants.html|Bool,PwaPermissionType,PluginVmPermissionType,ArcPermissionType,BorealisPermissionType,AppType,OptionalBool,PermissionValueType,TriState,InstallSource,AppManagementUserAction,AppManagementEntryPointsHistogramName,AppManagementEntryPoint",
                              "chrome/browser/resources/settings/chromeos/os_apps_page/android_apps_browser_proxy.html|AndroidAppsBrowserProxyImpl,AndroidAppsInfo",
                              "chrome/browser/resources/settings/chromeos/device_page/drag_behavior.html|DragBehavior,DragPosition",
                              "chrome/browser/resources/settings/chromeos/device_page/layout_behavior.html|LayoutBehavior",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js
index 69741704..bbaf37f2 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.js
+++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -59,6 +59,7 @@
 import './os_apps_page/app_management_page/permission_item.m.js';
 import './os_apps_page/app_management_page/pin_to_shelf_item.m.js';
 import './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.m.js';
+import './os_apps_page/app_management_page/borealis_page/borealis_detail_view.m.js';
 import './os_apps_page/app_management_page/pwa_detail_view.m.js';
 import './os_apps_page/app_management_page/shared_style.m.js';
 import './os_apps_page/app_management_page/shared_vars.m.js';
@@ -120,7 +121,7 @@
 export {AndroidAppsBrowserProxyImpl} from './os_apps_page/android_apps_browser_proxy.m.js';
 export {addApp, changeApp, removeApp, updateSelectedAppId} from './os_apps_page/app_management_page/actions.m.js';
 export {BrowserProxy} from './os_apps_page/app_management_page/browser_proxy.m.js';
-export {ArcPermissionType, Bool, PageType, PermissionValueType, PluginVmPermissionType, PwaPermissionType, TriState, WindowMode} from './os_apps_page/app_management_page/constants.m.js';
+export {ArcPermissionType, Bool, BorealisPermissionType, PageType, PermissionValueType, PluginVmPermissionType, PwaPermissionType, TriState, WindowMode} from './os_apps_page/app_management_page/constants.m.js';
 export {FakePageHandler} from './os_apps_page/app_management_page/fake_page_handler.m.js';
 export {PluginVmBrowserProxyImpl} from './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_browser_proxy.m.js';
 export {AppState, reduceAction} from './os_apps_page/app_management_page/reducers.m.js';
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
index 0f9ee77..424dfcf 100644
--- a/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
+++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/clear_browsing_data_dialog.js
@@ -299,18 +299,17 @@
   constructor() {
     super();
 
-    /** @private {ClearBrowsingDataBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!ClearBrowsingDataBrowserProxy} */
+    this.browserProxy_ = ClearBrowsingDataBrowserProxyImpl.getInstance();
 
-    /** @private {?SyncBrowserProxy} */
-    this.syncBrowserProxy_ = null;
+    /** @private {!SyncBrowserProxy} */
+    this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   ready() {
     super.ready();
 
-    this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance();
     this.syncBrowserProxy_.getSyncStatus().then(
         this.handleSyncStatus_.bind(this));
     this.addWebUIListener(
@@ -329,7 +328,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = ClearBrowsingDataBrowserProxyImpl.getInstance();
     this.browserProxy_.initialize().then(() => {
       this.$.clearBrowsingDataDialog.showModal();
     });
diff --git a/chrome/browser/resources/settings/languages_page/languages.js b/chrome/browser/resources/settings/languages_page/languages.js
index 52f4cbe..f3df5be 100644
--- a/chrome/browser/resources/settings/languages_page/languages.js
+++ b/chrome/browser/resources/settings/languages_page/languages.js
@@ -238,15 +238,16 @@
     this.boundOnSpellcheckDictionariesChanged_ = null;
     // </if>
 
-    /** @private {?LanguagesBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!LanguagesBrowserProxy} */
+    this.browserProxy_ = LanguagesBrowserProxyImpl.getInstance();
 
-    /** @private {?LanguageSettingsPrivate} */
-    this.languageSettingsPrivate_ = null;
+    /** @private {!LanguageSettingsPrivate} */
+    this.languageSettingsPrivate_ =
+        this.browserProxy_.getLanguageSettingsPrivate();
 
     // <if expr="chromeos">
-    /** @private {?InputMethodPrivate} */
-    this.inputMethodPrivate_ = null;
+    /** @private {!InputMethodPrivate} */
+    this.inputMethodPrivate_ = this.browserProxy_.getInputMethodPrivate();
 
     /** @private {?Function} */
     this.boundOnInputMethodAdded_ = null;
@@ -263,13 +264,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = LanguagesBrowserProxyImpl.getInstance();
-    this.languageSettingsPrivate_ =
-        this.browserProxy_.getLanguageSettingsPrivate();
-    // <if expr="chromeos">
-    this.inputMethodPrivate_ = this.browserProxy_.getInputMethodPrivate();
-    // </if>
-
     const promises = [];
 
     /**
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html
index 0f4315d..6cdbac6 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -131,7 +131,7 @@
                 expanded="{{languagesOpened_}}">
               <div>$i18n{languagesListTitle}</div>
 <if expr="chromeos or is_win">
-              <div class="secondary">
+              <div class="secondary" id="languageSectionSecondaryText">
                 [[getProspectiveUILanguageName_(languages.prospectiveUILanguage)]]
               </div>
 </if>
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js
index 5ef46397..f273b373 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.js
+++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -359,16 +359,16 @@
         item.language.code, !item.spellCheckEnabled);
   }
 
-  // <if expr="chromeos">
   /**
-   * @param {string} prospectiveUILanguage
-   * @return {string}
+   * @param {string} languageCode
+   * @return {string} The display name for a given language code.
    * @private
    */
-  getProspectiveUILanguageName_(prospectiveUILanguage) {
-    return this.languageHelper.getLanguage(prospectiveUILanguage).displayName;
+  getProspectiveUILanguageName_(languageCode) {
+    return this.languageHelper.getLanguage(languageCode).displayName;
   }
 
+  // <if expr="chromeos">
   /**
    * @param {!Event} e
    * @private
diff --git a/chrome/browser/resources/settings/lazy_load.js b/chrome/browser/resources/settings/lazy_load.js
index cf36c39..82340de 100644
--- a/chrome/browser/resources/settings/lazy_load.js
+++ b/chrome/browser/resources/settings/lazy_load.js
@@ -97,10 +97,13 @@
 export {LocalDataBrowserProxy, LocalDataBrowserProxyImpl, LocalDataItem} from './site_settings/local_data_browser_proxy.js';
 export {HandlerEntry, ProtocolEntry} from './site_settings/protocol_handlers.js';
 export {SettingsCategoryDefaultRadioGroupElement} from './site_settings/settings_category_default_radio_group.js';
+export {SiteListElement} from './site_settings/site_list.js';
 export {kControlledByLookup} from './site_settings/site_settings_behavior.js';
 export {ContentSettingProvider, DefaultContentSetting, RawChooserException, RawSiteException, RecentSitePermissions, SiteException, SiteGroup, SiteSettingsPrefsBrowserProxy, SiteSettingsPrefsBrowserProxyImpl, ZoomLevelEntry} from './site_settings/site_settings_prefs_browser_proxy.js';
 export {WebsiteUsageBrowserProxyImpl} from './site_settings/website_usage_browser_proxy.js';
+export {SettingsRecentSitePermissionsElement} from './site_settings_page/recent_site_permissions.js';
 export {defaultSettingLabel} from './site_settings_page/site_settings_list.js';
+export {SettingsSiteSettingsPageElement} from './site_settings_page/site_settings_page.js';
 // <if expr="not chromeos and not lacros">
 export {SystemPageBrowserProxyImpl} from './system_page/system_page_browser_proxy.js';
 
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
index 82786bb..810a198a 100644
--- a/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
+++ b/chrome/browser/resources/settings/on_startup_page/startup_url_dialog.js
@@ -78,16 +78,14 @@
   constructor() {
     super();
 
-    /** @private {?StartupUrlsPageBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!StartupUrlsPageBrowserProxy} */
+    this.browserProxy_ = StartupUrlsPageBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = StartupUrlsPageBrowserProxyImpl.getInstance();
-
     if (this.model) {
       this.dialogTitle_ = loadTimeData.getString('onStartupEditPage');
       this.actionButtonText_ = loadTimeData.getString('save');
diff --git a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
index c4544828..ea25546f 100644
--- a/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
+++ b/chrome/browser/resources/settings/on_startup_page/startup_urls_page.js
@@ -75,8 +75,8 @@
   constructor() {
     super();
 
-    /** @private {?StartupUrlsPageBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!StartupUrlsPageBrowserProxy} */
+    this.browserProxy_ = StartupUrlsPageBrowserProxyImpl.getInstance();
 
     /**
      * The element to return focus to, when the startup-url-dialog is closed.
@@ -89,7 +89,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = StartupUrlsPageBrowserProxyImpl.getInstance();
     this.addWebUIListener('update-startup-pages', startupPages => {
       // If an "edit" URL dialog was open, close it, because the underlying page
       // might have just been removed (and model indices have changed anyway).
diff --git a/chrome/browser/resources/settings/people_page/import_data_dialog.js b/chrome/browser/resources/settings/people_page/import_data_dialog.js
index b9744be..e7cdf51 100644
--- a/chrome/browser/resources/settings/people_page/import_data_dialog.js
+++ b/chrome/browser/resources/settings/people_page/import_data_dialog.js
@@ -87,8 +87,8 @@
   constructor() {
     super();
 
-    /** @private {?ImportDataBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!ImportDataBrowserProxy} */
+    this.browserProxy_ = ImportDataBrowserProxyImpl.getInstance();
   }
 
   /** @override */
@@ -102,7 +102,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = ImportDataBrowserProxyImpl.getInstance();
     this.browserProxy_.initializeImportDialog().then(data => {
       this.browserProfiles_ = data;
       this.selected_ = this.browserProfiles_[0];
diff --git a/chrome/browser/resources/settings/people_page/people_page.js b/chrome/browser/resources/settings/people_page/people_page.js
index d459870..dd1a113 100644
--- a/chrome/browser/resources/settings/people_page/people_page.js
+++ b/chrome/browser/resources/settings/people_page/people_page.js
@@ -194,8 +194,8 @@
   constructor() {
     super();
 
-    /** @private {?SyncBrowserProxy} */
-    this.syncBrowserProxy_ = null;
+    /** @private {!SyncBrowserProxy} */
+    this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance();
   }
 
   /** @override */
@@ -222,7 +222,6 @@
           'profile-info-changed', this.handleProfileInfo_.bind(this));
     }
 
-    this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance();
     this.syncBrowserProxy_.getSyncStatus().then(
         this.handleSyncStatus_.bind(this));
     this.addWebUIListener(
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.js b/chrome/browser/resources/settings/privacy_page/cookies_page.js
index ad7ba3e..7f15984 100644
--- a/chrome/browser/resources/settings/privacy_page/cookies_page.js
+++ b/chrome/browser/resources/settings/privacy_page/cookies_page.js
@@ -171,14 +171,7 @@
   constructor() {
     super();
 
-    /** @type {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-
+    /** @type {!MetricsBrowserProxy} */
     this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.js b/chrome/browser/resources/settings/privacy_page/personalization_options.js
index 48308fa..5a8630b 100644
--- a/chrome/browser/resources/settings/privacy_page/personalization_options.js
+++ b/chrome/browser/resources/settings/privacy_page/personalization_options.js
@@ -110,8 +110,8 @@
   constructor() {
     super();
 
-    /** @private {?PrivacyPageBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!PrivacyPageBrowserProxy} */
+    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
   }
 
   /**
@@ -126,8 +126,6 @@
   ready() {
     super.ready();
 
-    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
-
     // <if expr="_google_chrome and not chromeos">
     const setMetricsReportingPref = this.setMetricsReportingPref_.bind(this);
     this.addWebUIListener('metrics-reporting-change', setMetricsReportingPref);
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js
index 7ad5081..550f542f 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.js
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -239,20 +239,18 @@
 
   constructor() {
     super();
-    /** @private {?PrivacyPageBrowserProxy} */
-    this.browserProxy_ = null;
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!PrivacyPageBrowserProxy} */
+    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
+
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   ready() {
     super.ready();
 
-    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     this.onBlockAutoplayStatusChanged_({
       pref: /** @type {chrome.settingsPrivate.PrefObject} */ ({value: false}),
       enabled: false
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js
index 4b9001aa..ba41116 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_bio_enroll_dialog.js
@@ -123,8 +123,8 @@
   constructor() {
     super();
 
-    /** @private {?SecurityKeysBioEnrollProxy} */
-    this.browserProxy_ = null;
+    /** @private {!SecurityKeysBioEnrollProxy} */
+    this.browserProxy_ = SecurityKeysBioEnrollProxyImpl.getInstance();
 
     /** @private {number} */
     this.maxSamples_ = -1;
@@ -149,7 +149,6 @@
         'security-keys-bio-enroll-error', this.onError_.bind(this));
     this.addWebUIListener(
         'security-keys-bio-enroll-status', this.onEnrollmentSample_.bind(this));
-    this.browserProxy_ = SecurityKeysBioEnrollProxyImpl.getInstance();
     this.browserProxy_.startBioEnroll().then(([minPinLength]) => {
       this.minPinLength_ = minPinLength;
       this.dialogPage_ = BioEnrollDialogPage.PIN_PROMPT;
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
index 7b97b05..aa49535 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.js
@@ -106,8 +106,8 @@
   constructor() {
     super();
 
-    /** @private {?SecurityKeysCredentialBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!SecurityKeysCredentialBrowserProxy} */
+    this.browserProxy_ = SecurityKeysCredentialBrowserProxyImpl.getInstance();
 
     /** @private {?Set<string>} */
     this.checkedCredentialIds_ = null;
@@ -125,7 +125,6 @@
         'security-keys-credential-management-finished',
         this.onError_.bind(this));
     this.checkedCredentialIds_ = new Set();
-    this.browserProxy_ = SecurityKeysCredentialBrowserProxyImpl.getInstance();
     this.browserProxy_.startCredentialManagement().then(([minPinLength]) => {
       this.minPinLength_ = minPinLength;
       this.dialogPage_ = CredentialManagementDialogPage.PIN_PROMPT;
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_reset_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_reset_dialog.js
index fa3d992a..98c68885 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_reset_dialog.js
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_reset_dialog.js
@@ -88,8 +88,8 @@
   constructor() {
     super();
 
-    /** @private {?SecurityKeysResetBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!SecurityKeysResetBrowserProxy} */
+    this.browserProxy_ = SecurityKeysResetBrowserProxyImpl.getInstance();
   }
 
   /** @override */
@@ -97,7 +97,6 @@
     super.connectedCallback();
 
     this.title_ = this.i18n('securityKeysResetTitle');
-    this.browserProxy_ = SecurityKeysResetBrowserProxyImpl.getInstance();
     this.$.dialog.showModal();
 
     this.browserProxy_.reset().then(code => {
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
index 6d3c4bd..db07e0d9 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_set_pin_dialog.js
@@ -209,8 +209,8 @@
   constructor() {
     super();
 
-    /** @private {?SecurityKeysPINBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!SecurityKeysPINBrowserProxy} */
+    this.browserProxy_ = SecurityKeysPINBrowserProxyImpl.getInstance();
   }
 
   /** @override */
@@ -218,7 +218,6 @@
     super.connectedCallback();
 
     this.title_ = this.i18n('securityKeysSetPINInitialTitle');
-    this.browserProxy_ = SecurityKeysPINBrowserProxyImpl.getInstance();
     this.$.dialog.showModal();
 
     this.browserProxy_.startSetPIN().then(
diff --git a/chrome/browser/resources/settings/privacy_page/security_page.js b/chrome/browser/resources/settings/privacy_page/security_page.js
index 16b045b..4f6036f 100644
--- a/chrome/browser/resources/settings/privacy_page/security_page.js
+++ b/chrome/browser/resources/settings/privacy_page/security_page.js
@@ -149,11 +149,11 @@
 
   constructor() {
     super();
-    /** @private {?PrivacyPageBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!PrivacyPageBrowserProxy} */
+    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
@@ -168,9 +168,6 @@
     } else if (prefValue === SafeBrowsingSetting.STANDARD) {
       this.$.safeBrowsingStandard.expanded = true;
     }
-    this.browserProxy_ = PrivacyPageBrowserProxyImpl.getInstance();
-
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /**
diff --git a/chrome/browser/resources/settings/privacy_sandbox/app.js b/chrome/browser/resources/settings/privacy_sandbox/app.js
index 02175dba..eb4684f 100644
--- a/chrome/browser/resources/settings/privacy_sandbox/app.js
+++ b/chrome/browser/resources/settings/privacy_sandbox/app.js
@@ -56,23 +56,21 @@
   constructor() {
     super();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
 
-    /** @private {?PrivacySandboxBrowserProxy} */
-    this.privacySandboxBrowserProxy_ = null;
+    /** @private {!PrivacySandboxBrowserProxy} */
+    this.privacySandboxBrowserProxy_ =
+        PrivacySandboxBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   ready() {
     super.ready();
 
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
     chrome.metricsPrivate.recordSparseHashable(
         'WebUI.Settings.PathVisited', '/privacySandbox');
 
-    this.privacySandboxBrowserProxy_ =
-        PrivacySandboxBrowserProxyImpl.getInstance();
     this.privacySandboxBrowserProxy_.getFlocId().then(id => this.flocId_ = id);
     addWebUIListener('floc-id-changed', id => this.flocId_ = id);
 
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
index a8a5c78..a9dd583 100644
--- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
+++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.js
@@ -78,8 +78,8 @@
   constructor() {
     super();
 
-    /** @private {?ResetBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!ResetBrowserProxy} */
+    this.browserProxy_ = ResetBrowserProxyImpl.getInstance();
   }
 
   /**
@@ -118,8 +118,6 @@
   ready() {
     super.ready();
 
-    this.browserProxy_ = ResetBrowserProxyImpl.getInstance();
-
     this.addEventListener('cancel', () => {
       this.browserProxy_.onHideResetProfileDialog();
     });
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js
index 6fea3ab..8b525c9 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_chrome_cleaner_child.js
@@ -90,20 +90,17 @@
   constructor() {
     super();
 
-    /** @private {?ChromeCleanupProxy} */
-    this.chromeCleanupBrowserProxy_ = null;
+    /** @private {!ChromeCleanupProxy} */
+    this.chromeCleanupBrowserProxy_ = ChromeCleanupProxyImpl.getInstance();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.chromeCleanupBrowserProxy_ = ChromeCleanupProxyImpl.getInstance();
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     // Register for safety check status updates.
     this.addWebUIListener(
         SafetyCheckCallbackConstants.CHROME_CLEANER_CHANGED,
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js
index 9b83013..0d209f0b 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_extensions_child.js
@@ -86,16 +86,14 @@
   constructor() {
     super();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     // Register for safety check status updates.
     this.addWebUIListener(
         SafetyCheckCallbackConstants.EXTENSIONS_CHANGED,
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
index 71a5ac61..4746f2b6 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
@@ -90,11 +90,11 @@
   constructor() {
     super();
 
-    /** @private {?SafetyCheckBrowserProxy} */
-    this.safetyCheckBrowserProxy_ = null;
+    /** @private {!SafetyCheckBrowserProxy} */
+    this.safetyCheckBrowserProxy_ = SafetyCheckBrowserProxyImpl.getInstance();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
 
     /**
      * Timer ID for periodic update.
@@ -107,9 +107,6 @@
   connectedCallback() {
     super.connectedCallback();
 
-    this.safetyCheckBrowserProxy_ = SafetyCheckBrowserProxyImpl.getInstance();
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     // Register for safety check status updates.
     this.addWebUIListener(
         SafetyCheckCallbackConstants.PARENT_CHANGED,
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
index 7940f2bcbb..ebe49bf 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_passwords_child.js
@@ -88,14 +88,13 @@
   constructor() {
     super();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
 
     // Register for safety check status updates.
     this.addWebUIListener(
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js
index c956da77..edb586b 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_safe_browsing_child.js
@@ -88,16 +88,14 @@
   constructor() {
     super();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     // Register for safety check status updates.
     this.addWebUIListener(
         SafetyCheckCallbackConstants.SAFE_BROWSING_CHANGED,
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js
index 815e273..4dd5648 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_updates_child.js
@@ -71,20 +71,17 @@
   constructor() {
     super();
 
-    /** @private {?LifetimeBrowserProxy} */
-    this.lifetimeBrowserProxy_ = null;
+    /** @private {!LifetimeBrowserProxy} */
+    this.lifetimeBrowserProxy_ = LifetimeBrowserProxyImpl.getInstance();
 
-    /** @private {?MetricsBrowserProxy} */
-    this.metricsBrowserProxy_ = null;
+    /** @private {!MetricsBrowserProxy} */
+    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.lifetimeBrowserProxy_ = LifetimeBrowserProxyImpl.getInstance();
-    this.metricsBrowserProxy_ = MetricsBrowserProxyImpl.getInstance();
-
     // Register for safety check status updates.
     this.addWebUIListener(
         SafetyCheckCallbackConstants.UPDATES_CHANGED,
diff --git a/chrome/browser/resources/settings/site_settings/BUILD.gn b/chrome/browser/resources/settings/site_settings/BUILD.gn
index f326478..d6e2b06 100644
--- a/chrome/browser/resources/settings/site_settings/BUILD.gn
+++ b/chrome/browser/resources/settings/site_settings/BUILD.gn
@@ -112,7 +112,6 @@
 js_library("chooser_exception_list_entry") {
   deps = [
     ":site_list_entry",
-    ":site_settings_behavior",
     ":site_settings_prefs_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
   ]
@@ -256,12 +255,14 @@
     ":local_data_browser_proxy",
     ":site_settings_behavior",
     ":site_settings_prefs_browser_proxy",
+    "..:base_mixin",
     "..:route",
     "..:router",
     "//third_party/polymer/v3_0/components-chromium/iron-collapse:iron-collapse",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m",
     "//ui/webui/resources/js:assert.m",
+    "//ui/webui/resources/js:event_tracker.m",
     "//ui/webui/resources/js:load_time_data.m",
     "//ui/webui/resources/js/cr/ui:focus_row_behavior.m",
   ]
@@ -291,6 +292,7 @@
   deps = [
     ":constants",
     ":site_settings_behavior",
+    "..:base_mixin",
     "..:route",
     "..:router",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
diff --git a/chrome/browser/resources/settings/site_settings/chooser_exception_list.js b/chrome/browser/resources/settings/site_settings/chooser_exception_list.js
index 6057b3e..bf502fb 100644
--- a/chrome/browser/resources/settings/site_settings/chooser_exception_list.js
+++ b/chrome/browser/resources/settings/site_settings/chooser_exception_list.js
@@ -13,75 +13,92 @@
 import '../settings_shared_css.js';
 import './chooser_exception_list_entry.js';
 
-import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
-import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
-import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {ListPropertyUpdateBehavior, ListPropertyUpdateBehaviorInterface} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {loadTimeData} from '../i18n_setup.js';
 
 import {ChooserType, ContentSettingsTypes} from './constants.js';
-import {SiteSettingsBehavior} from './site_settings_behavior.js';
+import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from './site_settings_behavior.js';
 import {ChooserException, RawChooserException} from './site_settings_prefs_browser_proxy.js';
 
-Polymer({
-  is: 'chooser-exception-list',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ * @implements {ListPropertyUpdateBehaviorInterface}
+ * @implements {SiteSettingsBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const ChooserExceptionListElementBase = mixinBehaviors(
+    [
+      I18nBehavior, ListPropertyUpdateBehavior, SiteSettingsBehavior,
+      WebUIListenerBehavior
+    ],
+    PolymerElement);
 
-  _template: html`{__html_template__}`,
+/** @polymer */
+class ChooserExceptionListElement extends ChooserExceptionListElementBase {
+  static get is() {
+    return 'chooser-exception-list';
+  }
 
-  behaviors: [
-    I18nBehavior,
-    ListPropertyUpdateBehavior,
-    SiteSettingsBehavior,
-    WebUIListenerBehavior,
-  ],
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  properties: {
-    /**
-     * Array of chooser exceptions to display in the widget.
-     * @type {!Array<ChooserException>}
-     */
-    chooserExceptions: {
-      type: Array,
-      value() {
-        return [];
+  static get properties() {
+    return {
+      /**
+       * Array of chooser exceptions to display in the widget.
+       * @type {!Array<ChooserException>}
+       */
+      chooserExceptions: {
+        type: Array,
+        value() {
+          return [];
+        },
       },
-    },
 
-    /**
-     * The string ID of the chooser type that this element is displaying data
-     * for.
-     * See site_settings/constants.js for possible values.
-     * @type {!ChooserType}
-     */
-    chooserType: {
-      observer: 'chooserTypeChanged_',
-      type: String,
-      value: ChooserType.NONE,
-    },
+      /**
+       * The string ID of the chooser type that this element is displaying data
+       * for.
+       * See site_settings/constants.js for possible values.
+       * @type {!ChooserType}
+       */
+      chooserType: {
+        observer: 'chooserTypeChanged_',
+        type: String,
+        value: ChooserType.NONE,
+      },
 
-    /** @private */
-    emptyListMessage_: {
-      type: String,
-      value: '',
-    },
+      /** @private */
+      emptyListMessage_: {
+        type: String,
+        value: '',
+      },
 
-    /** @private */
-    hasIncognito_: Boolean,
+      /** @private */
+      hasIncognito_: Boolean,
 
-    /** @private */
-    tooltipText_: String,
-  },
+      /** @private */
+      tooltipText_: String,
+    };
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.addWebUIListener(
         'contentSettingChooserPermissionChanged',
         this.objectWithinChooserTypeChanged_.bind(this));
     this.addWebUIListener(
         'onIncognitoStatusChanged', this.onIncognitoStatusChanged_.bind(this));
     this.browserProxy.updateIncognitoStatus();
-  },
+  }
 
   /**
    * Called when a chooser exception changes permission and updates the element
@@ -96,7 +113,7 @@
     if (category === this.category && chooserType === this.chooserType) {
       this.chooserTypeChanged_();
     }
-  },
+  }
 
   /**
    * Called for each chooser-exception-list when incognito is enabled or
@@ -107,7 +124,7 @@
   onIncognitoStatusChanged_(hasIncognito) {
     this.hasIncognito_ = hasIncognito;
     this.populateList_();
-  },
+  }
 
   /**
    * Configures the visibility of the widget and shows the list.
@@ -137,7 +154,7 @@
     }
 
     this.populateList_();
-  },
+  }
 
   /**
    * Returns true if there are any chooser exceptions for this chooser type.
@@ -146,7 +163,7 @@
    */
   hasExceptions_() {
     return this.chooserExceptions.length > 0;
-  },
+  }
 
   /**
    * Need to use a common tooltip since the tooltip in the entry is cut off from
@@ -173,7 +190,7 @@
     target.addEventListener('click', hide);
     this.$.tooltip.addEventListener('mouseenter', hide);
     this.$.tooltip.show();
-  },
+  }
 
   /**
    * Populate the chooser exception list for display.
@@ -182,7 +199,7 @@
   populateList_() {
     this.browserProxy.getChooserExceptionList(this.chooserType)
         .then(exceptionList => this.processExceptions_(exceptionList));
-  },
+  }
 
   /**
    * Process the chooser exception list returned from the native layer.
@@ -207,5 +224,8 @@
         this.updateList(propertyPath, siteUidGetter, exception.sites);
       }, this);
     }
-  },
-});
+  }
+}
+
+customElements.define(
+    ChooserExceptionListElement.is, ChooserExceptionListElement);
diff --git a/chrome/browser/resources/settings/site_settings/chooser_exception_list_entry.js b/chrome/browser/resources/settings/site_settings/chooser_exception_list_entry.js
index 1925d86..e6081342 100644
--- a/chrome/browser/resources/settings/site_settings/chooser_exception_list_entry.js
+++ b/chrome/browser/resources/settings/site_settings/chooser_exception_list_entry.js
@@ -15,26 +15,33 @@
 import './site_list_entry.js';
 
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {SiteSettingsBehavior} from './site_settings_behavior.js';
 import {ChooserException} from './site_settings_prefs_browser_proxy.js';
 
-Polymer({
-  is: 'chooser-exception-list-entry',
+/** @polymer */
+class ChooserExceptionListEntryElement extends PolymerElement {
+  static get is() {
+    return 'chooser-exception-list-entry';
+  }
 
-  _template: html`{__html_template__}`,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  behaviors: [SiteSettingsBehavior],
+  static get properties() {
+    return {
+      /**
+       * Chooser exception object to display in the widget.
+       * @type {!ChooserException}
+       */
+      exception: Object,
 
-  properties: {
-    /**
-     * Chooser exception object to display in the widget.
-     * @type {!ChooserException}
-     */
-    exception: Object,
+      /** @private */
+      lastFocused_: Object,
+    };
+  }
+}
 
-    /** @private */
-    lastFocused_: Object,
-  },
-});
+customElements.define(
+    ChooserExceptionListEntryElement.is, ChooserExceptionListEntryElement);
diff --git a/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js b/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js
index fd48da2..bfa2c5c 100644
--- a/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js
+++ b/chrome/browser/resources/settings/site_settings/edit_exception_dialog.js
@@ -61,15 +61,14 @@
   constructor() {
     super();
 
-    /** @private {?SiteSettingsPrefsBrowserProxy} */
-    this.browserProxy_ = null;
+    /** @private {!SiteSettingsPrefsBrowserProxy} */
+    this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
     this.origin_ = this.model.origin;
 
     this.$.dialog.showModal();
diff --git a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
index 7f4fe906..bc63c102 100644
--- a/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
+++ b/chrome/browser/resources/settings/site_settings/site_data_details_subpage.js
@@ -81,17 +81,15 @@
 
     /**
      * The browser proxy used to retrieve and change cookies.
-     * @private {?LocalDataBrowserProxy}
+     * @private {!LocalDataBrowserProxy}
      */
-    this.browserProxy_ = null;
+    this.browserProxy_ = LocalDataBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   ready() {
     super.ready();
 
-    this.browserProxy_ = LocalDataBrowserProxyImpl.getInstance();
-
     this.addWebUIListener(
         'on-tree-item-removed', this.getCookieDetails_.bind(this));
   }
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js
index 02b085f..8a6934e 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.js
+++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -132,15 +132,14 @@
     /** @private {string} */
     this.fetchingForHost_ = '';
 
-    /** @private {?WebsiteUsageBrowserProxy} */
-    this.websiteUsageProxy_ = null;
+    /** @private {!WebsiteUsageBrowserProxy} */
+    this.websiteUsageProxy_ = WebsiteUsageBrowserProxyImpl.getInstance();
   }
 
   /** @override */
   connectedCallback() {
     super.connectedCallback();
 
-    this.websiteUsageProxy_ = WebsiteUsageBrowserProxyImpl.getInstance();
     this.addWebUIListener('usage-total-changed', (host, data, cookies) => {
       this.onUsageTotalChanged_(host, data, cookies);
     });
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.js b/chrome/browser/resources/settings/site_settings/site_entry.js
index f37b7cc..dc63165 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.js
+++ b/chrome/browser/resources/settings/site_settings/site_entry.js
@@ -16,118 +16,139 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {BaseMixin, BaseMixinInterface} from '../base_mixin.js';
 import {loadTimeData} from '../i18n_setup.js';
 import {routes} from '../route.js';
 import {Router} from '../router.js';
 
 import {AllSitesAction2, SortMethod} from './constants.js';
 import {LocalDataBrowserProxy, LocalDataBrowserProxyImpl} from './local_data_browser_proxy.js';
-import {SiteSettingsBehavior} from './site_settings_behavior.js';
+import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from './site_settings_behavior.js';
 import {OriginInfo, SiteGroup} from './site_settings_prefs_browser_proxy.js';
 
-Polymer({
-  is: 'site-entry',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {BaseMixinInterface}
+ * @implements {SiteSettingsBehaviorInterface}
+ */
+const SiteEntryElementBase = mixinBehaviors(
+    [SiteSettingsBehavior, FocusRowBehavior], BaseMixin(PolymerElement));
 
-  _template: html`{__html_template__}`,
+/** @polymer */
+class SiteEntryElement extends SiteEntryElementBase {
+  static get is() {
+    return 'site-entry';
+  }
 
-  behaviors: [SiteSettingsBehavior, FocusRowBehavior],
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  properties: {
-    /**
-     * An object representing a group of sites with the same eTLD+1.
-     * @type {!SiteGroup}
-     */
-    siteGroup: {
-      type: Object,
-      observer: 'onSiteGroupChanged_',
-    },
-
-    /**
-     * The name to display beside the icon. If grouped_() is true, it will be
-     * the eTLD+1 for all the origins, otherwise, it will return the host.
-     * @private
-     */
-    displayName_: String,
-
-    /**
-     * The string to display when there is a non-zero number of cookies.
-     * @private
-     */
-    cookieString_: String,
-
-    /**
-     * The position of this site-entry in its parent list.
-     */
-    listIndex: {
-      type: Number,
-      value: -1,
-    },
-
-    /**
-     * The string to display showing the overall usage of this site-entry.
-     * @private
-     */
-    overallUsageString_: String,
-
-    /**
-     * An array containing the strings to display showing the individual disk
-     * usage for each origin in |siteGroup|.
-     * @type {!Array<string>}
-     * @private
-     */
-    originUsages_: {
-      type: Array,
-      value() {
-        return [];
+  static get properties() {
+    return {
+      /**
+       * An object representing a group of sites with the same eTLD+1.
+       * @type {!SiteGroup}
+       */
+      siteGroup: {
+        type: Object,
+        observer: 'onSiteGroupChanged_',
       },
-    },
 
-    /**
-     * An array containing the strings to display showing the individual cookies
-     * number for each origin in |siteGroup|.
-     * @type {!Array<string>}
-     * @private
-     */
-    cookiesNum_: {
-      type: Array,
-      value() {
-        return [];
+      /**
+       * The name to display beside the icon. If grouped_() is true, it will be
+       * the eTLD+1 for all the origins, otherwise, it will return the host.
+       * @private
+       */
+      displayName_: String,
+
+      /**
+       * The string to display when there is a non-zero number of cookies.
+       * @private
+       */
+      cookieString_: String,
+
+      /**
+       * The position of this site-entry in its parent list.
+       */
+      listIndex: {
+        type: Number,
+        value: -1,
       },
-    },
 
-    /**
-     * The selected sort method.
-     * @type {!SortMethod|undefined}
-     */
-    sortMethod: {type: String, observer: 'updateOrigins_'},
-  },
+      /**
+       * The string to display showing the overall usage of this site-entry.
+       * @private
+       */
+      overallUsageString_: String,
 
-  /** @private {?LocalDataBrowserProxy} */
-  localDataBrowserProxy_: null,
+      /**
+       * An array containing the strings to display showing the individual disk
+       * usage for each origin in |siteGroup|.
+       * @type {!Array<string>}
+       * @private
+       */
+      originUsages_: {
+        type: Array,
+        value() {
+          return [];
+        },
+      },
 
-  /** @private {?Element} */
-  button_: null,
+      /**
+       * An array containing the strings to display showing the individual
+       * cookies number for each origin in |siteGroup|.
+       * @type {!Array<string>}
+       * @private
+       */
+      cookiesNum_: {
+        type: Array,
+        value() {
+          return [];
+        },
+      },
+
+      /**
+       * The selected sort method.
+       * @type {!SortMethod|undefined}
+       */
+      sortMethod: {type: String, observer: 'updateOrigins_'},
+    };
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {?Element} */
+    this.button_ = null;
+
+    /** @private {!LocalDataBrowserProxy} */
     this.localDataBrowserProxy_ = LocalDataBrowserProxyImpl.getInstance();
-  },
+
+    /** @private {!EventTracker} */
+    this.eventTracker_ = new EventTracker();
+  }
 
   /** @override */
-  detached() {
+  disconnectedCallback() {
+    super.disconnectedCallback();
+
     if (this.button_) {
-      this.unlisten(this.button_, 'keydown', 'onButtonKeydown_');
+      this.eventTracker_.remove(this.button_, 'keydown');
     }
-  },
+  }
 
   /** @param {!KeyboardEvent} e */
   onButtonKeydown_(e) {
     if (e.shiftKey && e.key === 'Tab') {
       this.focus();
     }
-  },
+  }
 
   /**
    * Whether the list of origins displayed in this site-entry is a group of
@@ -145,7 +166,7 @@
       return true;
     }
     return false;
-  },
+  }
 
   /**
    * Returns a user-friendly name for the siteGroup.
@@ -167,7 +188,7 @@
       // was computed.
     }
     return this.originRepresentation(siteGroup.origins[0].origin);
-  },
+  }
 
   /**
    * @param {SiteGroup} siteGroup The eTLD+1 group of origins.
@@ -176,11 +197,12 @@
   onSiteGroupChanged_(siteGroup) {
     // Update the button listener.
     if (this.button_) {
-      this.unlisten(this.button_, 'keydown', 'onButtonKeydown_');
+      this.eventTracker_.remove(this.button_, 'keydown');
     }
     this.button_ = /** @type Element */
         (this.root.querySelector('#toggleButton *:not([hidden])'));
-    this.listen(assert(this.button_), 'keydown', 'onButtonKeydown_');
+    this.eventTracker_.add(
+        assert(this.button_), 'keydown', e => this.onButtonKeydown_(e));
 
     if (!this.grouped_(siteGroup)) {
       // Ensure ungrouped |siteGroup|s do not get stuck in an opened state.
@@ -198,7 +220,7 @@
     });
     this.updateOrigins_(this.sortMethod);
     this.displayName_ = this.siteGroupRepresentation_(siteGroup);
-  },
+  }
 
   /**
    * Returns any non-HTTPS scheme/protocol for the siteGroup that only contains
@@ -212,7 +234,7 @@
       return '';
     }
     return this.originScheme_(siteGroup.origins[0]);
-  },
+  }
 
   /**
    * Returns any non-HTTPS scheme/protocol for the origin. Otherwise, returns
@@ -229,7 +251,7 @@
       return '';
     }
     return scheme;
-  },
+  }
 
   /**
    * Get an appropriate favicon that represents this group of eTLD+1 sites as a
@@ -262,7 +284,7 @@
               originInfo);
     };
     return origins.reduce(getMaxStorage, origins[0]).origin;
-  },
+  }
 
   /**
    * Calculates the amount of disk storage used by the given eTLD+1.
@@ -278,7 +300,7 @@
     this.browserProxy.getFormattedBytes(overallUsage).then(string => {
       this.overallUsageString_ = string;
     });
-  },
+  }
 
   /**
    * Get display string for number of cookies.
@@ -290,7 +312,7 @@
       return Promise.resolve('');
     }
     return this.localDataBrowserProxy_.getNumCookiesString(numCookies);
-  },
+  }
 
   /**
    * Array binding for the |originUsages_| array for use in the HTML.
@@ -301,7 +323,7 @@
    */
   originUsagesItem_(change, index) {
     return change.base[index];
-  },
+  }
 
   /**
    * Array binding for the |cookiesNum_| array for use in the HTML.
@@ -312,7 +334,7 @@
    */
   originCookiesItem_(change, index) {
     return change.base[index];
-  },
+  }
 
   /**
    * Navigates to the corresponding Site Details page for the given origin.
@@ -326,7 +348,7 @@
     Router.getInstance().navigateTo(
         routes.SITE_SETTINGS_SITE_DETAILS,
         new URLSearchParams('site=' + origin));
-  },
+  }
 
   /**
    * A handler for selecting a site (by clicking on the origin).
@@ -337,7 +359,7 @@
     this.navigateToSiteDetails_(this.siteGroup.origins[e.model.index].origin);
     this.browserProxy.recordAction(AllSitesAction2.ENTER_SITE_DETAILS);
     chrome.metricsPrivate.recordUserAction('AllSites_EnterSiteDetails');
-  },
+  }
 
   /**
    * A handler for clicking on a site-entry heading. This will either show a
@@ -357,7 +379,7 @@
     // Make sure the expanded origins can be viewed without further scrolling
     // (in case |this| is already at the bottom of the viewport).
     this.scrollIntoViewIfNeeded();
-  },
+  }
 
   /**
    * Toggles open and closed the list of origins if there is more than one.
@@ -371,7 +393,7 @@
     this.$.expandIcon.toggleClass('icon-expand-more');
     this.$.expandIcon.toggleClass('icon-expand-less');
     this.fire('iron-resize');
-  },
+  }
 
   /**
    * Fires a custom event when the menu button is clicked. Sends the details
@@ -387,7 +409,7 @@
       origin: e.target.dataset.origin,
       actionScope: e.target.dataset.context,
     });
-  },
+  }
 
   /**
    * Returns a valid index for an origin contained in |siteGroup.origins| by
@@ -400,7 +422,7 @@
    */
   getIndexBoundToOriginList_(siteGroup, index) {
     return Math.max(0, Math.min(index, siteGroup.origins.length - 1));
-  },
+  }
 
   /**
    * Returns the correct class to apply depending on this site-entry's position
@@ -410,7 +432,7 @@
    */
   getClassForIndex_(index) {
     return index > 0 ? 'hr' : '';
-  },
+  }
 
   /**
    * Update the order and data display text for origins.
@@ -439,7 +461,7 @@
         this.set(`cookiesNum_.${i}`, string);
       });
     });
-  },
+  }
 
   /**
    * Sort functions for sorting origins based on selected method.
@@ -461,5 +483,7 @@
         return origin1.origin.localeCompare(origin2.origin);
       };
     }
-  },
-});
+  }
+}
+
+customElements.define(SiteEntryElement.is, SiteEntryElement);
diff --git a/chrome/browser/resources/settings/site_settings/site_list.js b/chrome/browser/resources/settings/site_settings/site_list.js
index 1d499b5..9c038928 100644
--- a/chrome/browser/resources/settings/site_settings/site_list.js
+++ b/chrome/browser/resources/settings/site_settings/site_list.js
@@ -22,9 +22,9 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
-import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
-import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {ListPropertyUpdateBehavior, ListPropertyUpdateBehaviorInterface} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {loadTimeData} from '../i18n_setup.js';
 
@@ -32,155 +32,183 @@
 import {AndroidInfoBrowserProxyImpl, AndroidSmsInfo} from './android_info_browser_proxy.js';
 // </if>
 import {ContentSetting, ContentSettingsTypes, INVALID_CATEGORY_SUBTYPE} from './constants.js';
-import {SiteSettingsBehavior} from './site_settings_behavior.js';
-import {RawSiteException, SiteException, SiteSettingsPrefsBrowserProxyImpl} from './site_settings_prefs_browser_proxy.js';
+import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from './site_settings_behavior.js';
+import {RawSiteException, SiteException, SiteSettingsPrefsBrowserProxy, SiteSettingsPrefsBrowserProxyImpl} from './site_settings_prefs_browser_proxy.js';
 
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {SiteSettingsBehaviorInterface}
+ * @implements {ListPropertyUpdateBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SiteListElementBase = mixinBehaviors(
+    [
+      SiteSettingsBehavior,
+      WebUIListenerBehavior,
+      ListPropertyUpdateBehavior,
+    ],
+    PolymerElement);
 
-Polymer({
-  is: 'site-list',
+/** @polymer */
+export class SiteListElement extends SiteListElementBase {
+  static get is() {
+    return 'site-list';
+  }
 
-  _template: html`{__html_template__}`,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  behaviors: [
-    SiteSettingsBehavior,
-    WebUIListenerBehavior,
-    ListPropertyUpdateBehavior,
-  ],
-
-  properties: {
-    /**
-     * Some content types (like Location) do not allow the user to manually
-     * edit the exception list from within Settings.
-     */
-    readOnlyList: {
-      type: Boolean,
-      value: false,
-    },
-
-    categoryHeader: String,
-
-    /** @private */
-    enableContentSettingsRedesign_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('enableContentSettingsRedesign');
-      }
-    },
-
-    /**
-     * The site serving as the model for the currently open action menu.
-     * @private {?SiteException}
-     */
-    actionMenuSite_: Object,
-
-    /**
-     * Whether the "edit exception" dialog should be shown.
-     * @private
-     */
-    showEditExceptionDialog_: Boolean,
-
-    /**
-     * Array of sites to display in the widget.
-     * @type {!Array<SiteException>}
-     */
-    sites: {
-      type: Array,
-      value() {
-        return [];
+  static get properties() {
+    return {
+      /**
+       * Some content types (like Location) do not allow the user to manually
+       * edit the exception list from within Settings.
+       */
+      readOnlyList: {
+        type: Boolean,
+        value: false,
       },
-    },
+
+      categoryHeader: String,
+
+      /** @private */
+      enableContentSettingsRedesign_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('enableContentSettingsRedesign');
+        }
+      },
+
+      /**
+       * The site serving as the model for the currently open action menu.
+       * @private {?SiteException}
+       */
+      actionMenuSite_: Object,
+
+      /**
+       * Whether the "edit exception" dialog should be shown.
+       * @private
+       */
+      showEditExceptionDialog_: Boolean,
+
+      /**
+       * Array of sites to display in the widget.
+       * @type {!Array<SiteException>}
+       */
+      sites: {
+        type: Array,
+        value() {
+          return [];
+        },
+      },
+
+      /**
+       * The type of category this widget is displaying data for. Normally
+       * either 'allow' or 'block', representing which sites are allowed or
+       * blocked respectively.
+       */
+      categorySubtype: {
+        type: String,
+        value: INVALID_CATEGORY_SUBTYPE,
+      },
+
+      /** @private */
+      hasIncognito_: Boolean,
+
+      /**
+       * Whether to show the Add button next to the header.
+       * @private
+       */
+      showAddSiteButton_: {
+        type: Boolean,
+        computed: 'computeShowAddSiteButton_(readOnlyList, category, ' +
+            'categorySubtype)',
+      },
+
+      /** @private */
+      showAddSiteDialog_: Boolean,
+
+      /**
+       * Whether to show the Allow action in the action menu.
+       * @private
+       */
+      showAllowAction_: Boolean,
+
+      /**
+       * Whether to show the Block action in the action menu.
+       * @private
+       */
+      showBlockAction_: Boolean,
+
+      /**
+       * Whether to show the 'Clear on exit' action in the action
+       * menu.
+       * @private
+       */
+      showSessionOnlyAction_: Boolean,
+
+      /**
+       * All possible actions in the action menu.
+       * @private
+       */
+      actions_: {
+        readOnly: true,
+        type: Object,
+        values: {
+          ALLOW: 'Allow',
+          BLOCK: 'Block',
+          RESET: 'Reset',
+          SESSION_ONLY: 'SessionOnly',
+        }
+      },
+
+      /** @private */
+      lastFocused_: Object,
+
+      /** @private */
+      listBlurred_: Boolean,
+
+      /** @private */
+      tooltipText_: String,
+
+      searchFilter: String,
+
+    };
+  }
+
+  static get observers() {
+    return ['configureWidget_(category, categorySubtype)'];
+  }
+
+  constructor() {
+    super();
+
+    // <if expr="chromeos">
+    /**
+     * Android messages info object containing messages feature state and
+     * exception origin.
+     * @private {?AndroidSmsInfo}
+     */
+    this.androidSmsInfo_ = null;
+    // </if>
 
     /**
-     * The type of category this widget is displaying data for. Normally
-     * either 'allow' or 'block', representing which sites are allowed or
-     * blocked respectively.
+     * The element to return focus to, when the currently active dialog is
+     * closed.
+     * @private {?HTMLElement}
      */
-    categorySubtype: {
-      type: String,
-      value: INVALID_CATEGORY_SUBTYPE,
-    },
+    this.activeDialogAnchor_ = null;
 
-    /** @private */
-    hasIncognito_: Boolean,
-
-    /**
-     * Whether to show the Add button next to the header.
-     * @private
-     */
-    showAddSiteButton_: {
-      type: Boolean,
-      computed: 'computeShowAddSiteButton_(readOnlyList, category, ' +
-          'categorySubtype)',
-    },
-
-    /** @private */
-    showAddSiteDialog_: Boolean,
-
-    /**
-     * Whether to show the Allow action in the action menu.
-     * @private
-     */
-    showAllowAction_: Boolean,
-
-    /**
-     * Whether to show the Block action in the action menu.
-     * @private
-     */
-    showBlockAction_: Boolean,
-
-    /**
-     * Whether to show the 'Clear on exit' action in the action
-     * menu.
-     * @private
-     */
-    showSessionOnlyAction_: Boolean,
-
-    /**
-     * All possible actions in the action menu.
-     * @private
-     */
-    actions_: {
-      readOnly: true,
-      type: Object,
-      values: {
-        ALLOW: 'Allow',
-        BLOCK: 'Block',
-        RESET: 'Reset',
-        SESSION_ONLY: 'SessionOnly',
-      }
-    },
-
-    /** @private */
-    lastFocused_: Object,
-
-    /** @private */
-    listBlurred_: Boolean,
-
-    /** @private */
-    tooltipText_: String,
-
-    searchFilter: String,
-  },
-
-  // <if expr="chromeos">
-  /**
-   * Android messages info object containing messages feature state and
-   * exception origin.
-   * @private {?AndroidSmsInfo}
-   */
-  androidSmsInfo_: null,
-  // </if>
-
-  /**
-   * The element to return focus to, when the currently active dialog is closed.
-   * @private {?HTMLElement}
-   */
-  activeDialogAnchor_: null,
-
-  observers: ['configureWidget_(category, categorySubtype)'],
+    /** @private {!SiteSettingsPrefsBrowserProxy} */
+    this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
+  }
 
   /** @override */
   ready() {
+    super.ready();
+
     this.addWebUIListener(
         'contentSettingSitePermissionChanged',
         this.siteWithinCategoryChanged_.bind(this));
@@ -193,7 +221,7 @@
     });
     // </if>
     this.browserProxy.updateIncognitoStatus();
-  },
+  }
 
   /**
    * Called when a site changes permission.
@@ -205,7 +233,7 @@
     if (category === this.category) {
       this.configureWidget_();
     }
-  },
+  }
 
   /**
    * Called for each site list when incognito is enabled or disabled. Only
@@ -225,7 +253,7 @@
     // A change notification is not sent for each site. So we repopulate the
     // whole list when the incognito profile is created or destroyed.
     this.populateList_();
-  },
+  }
 
   /**
    * Configures the action menu, visibility of the widget and shows the list.
@@ -236,12 +264,6 @@
       return;
     }
 
-    // The observer for All Sites fires before the attached/ready event, so
-    // initialize this here.
-    if (this.browserProxy_ === undefined) {
-      this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
-    }
-
     this.setUpActionMenu_();
 
     // <if expr="not chromeos">
@@ -256,7 +278,7 @@
     if (this.categorySubtype === ContentSetting.SESSION_ONLY) {
       this.$.category.hidden = this.category !== ContentSettingsTypes.COOKIES;
     }
-  },
+  }
 
   /**
    * Whether there are any site exceptions added for this content setting.
@@ -265,7 +287,7 @@
    */
   hasSites_() {
     return this.sites.length > 0;
-  },
+  }
 
   /**
    * Whether the Add Site button is shown in the header for the current category
@@ -278,7 +300,7 @@
         this.readOnlyList ||
         (this.category === ContentSettingsTypes.FILE_SYSTEM_WRITE &&
          this.categorySubtype === ContentSetting.ALLOW));
-  },
+  }
 
   /**
    * @return {boolean}
@@ -286,7 +308,7 @@
    */
   showNoSearchResults_() {
     return this.sites.length > 0 && this.getFilteredSites_().length === 0;
-  },
+  }
 
   /**
    * A handler for the Add Site button.
@@ -295,13 +317,13 @@
   onAddSiteTap_() {
     assert(!this.readOnlyList);
     this.showAddSiteDialog_ = true;
-  },
+  }
 
   /** @private */
   onAddSiteDialogClosed_() {
     this.showAddSiteDialog_ = false;
     focusWithoutInk(assert(this.$.addSite));
-  },
+  }
 
   /**
    * Need to use common tooltip since the tooltip in the entry is cut off from
@@ -330,7 +352,7 @@
     target.addEventListener('click', hide);
     this.$.tooltip.addEventListener('mouseenter', hide);
     this.$.tooltip.show();
-  },
+  }
 
   // <if expr="chromeos">
   /**
@@ -352,7 +374,7 @@
     }
 
     return Promise.resolve();
-  },
+  }
 
   /**
    * Processes exceptions and adds showAndroidSmsNote field to
@@ -370,7 +392,7 @@
         return site;
       }
     });
-  },
+  }
   // </if>
 
   /**
@@ -382,7 +404,7 @@
       this.processExceptions_(exceptionList);
       this.closeActionMenu_();
     });
-  },
+  }
 
   /**
    * Process the exception list returned from the native layer.
@@ -400,7 +422,7 @@
     sites = this.processExceptionsForAndroidSmsInfo_(sites);
     // </if>
     this.updateList('sites', x => x.origin, sites);
-  },
+  }
 
   /**
    * Set up the values to use for the action menu.
@@ -412,7 +434,7 @@
     this.showSessionOnlyAction_ =
         this.categorySubtype !== ContentSetting.SESSION_ONLY &&
         this.category === ContentSettingsTypes.COOKIES;
-  },
+  }
 
   /**
    * @return {boolean} Whether to show the "Session Only" menu item for the
@@ -428,7 +450,7 @@
     }
 
     return this.showSessionOnlyAction_;
-  },
+  }
 
   /**
    * @param {!ContentSetting} contentSetting
@@ -439,33 +461,35 @@
     this.browserProxy.setCategoryPermissionForPattern(
         this.actionMenuSite_.origin, this.actionMenuSite_.embeddingOrigin,
         this.category, contentSetting, this.actionMenuSite_.incognito);
-  },
+  }
 
   /** @private */
   onAllowTap_() {
     this.setContentSettingForActionMenuSite_(ContentSetting.ALLOW);
     this.closeActionMenu_();
-  },
+  }
 
   /** @private */
   onBlockTap_() {
     this.setContentSettingForActionMenuSite_(ContentSetting.BLOCK);
     this.closeActionMenu_();
-  },
+  }
 
   /** @private */
   onSessionOnlyTap_() {
     this.setContentSettingForActionMenuSite_(ContentSetting.SESSION_ONLY);
     this.closeActionMenu_();
-  },
+  }
 
   /** @private */
   onEditTap_() {
     // Close action menu without resetting |this.actionMenuSite_| since it is
     // bound to the dialog.
-    /** @type {!CrActionMenuElement} */ (this.$$('cr-action-menu')).close();
+    /** @type {!CrActionMenuElement} */ (
+        this.shadowRoot.querySelector('cr-action-menu'))
+        .close();
     this.showEditExceptionDialog_ = true;
-  },
+  }
 
   /** @private */
   onEditExceptionDialogClosed_() {
@@ -475,7 +499,7 @@
       this.activeDialogAnchor_.focus();
       this.activeDialogAnchor_ = null;
     }
-  },
+  }
 
   /** @private */
   onResetTap_() {
@@ -484,7 +508,7 @@
     this.browserProxy.resetCategoryPermissionForPattern(
         site.origin, site.embeddingOrigin, this.category, site.incognito);
     this.closeActionMenu_();
-  },
+  }
 
   /**
    * @param {!Event} e
@@ -493,20 +517,22 @@
   onShowActionMenu_(e) {
     this.activeDialogAnchor_ = /** @type {!HTMLElement} */ (e.detail.anchor);
     this.actionMenuSite_ = e.detail.model;
-    /** @type {!CrActionMenuElement} */ (this.$$('cr-action-menu'))
+    /** @type {!CrActionMenuElement} */ (
+        this.shadowRoot.querySelector('cr-action-menu'))
         .showAt(this.activeDialogAnchor_);
-  },
+  }
 
   /** @private */
   closeActionMenu_() {
     this.actionMenuSite_ = null;
     this.activeDialogAnchor_ = null;
     const actionMenu =
-        /** @type {!CrActionMenuElement} */ (this.$$('cr-action-menu'));
+        /** @type {!CrActionMenuElement} */ (
+            this.shadowRoot.querySelector('cr-action-menu'));
     if (actionMenu.open) {
       actionMenu.close();
     }
-  },
+  }
 
   /**
    * @return {!Array<!SiteException>}
@@ -525,7 +551,7 @@
     return this.sites.filter(
         site => propNames.some(
             propName => site[propName].toLowerCase().includes(searchFilter)));
-  },
+  }
 
   /**
    * @return {string}
@@ -534,4 +560,6 @@
   getCssClass_() {
     return this.enableContentSettingsRedesign_ ? 'secondary' : '';
   }
-});
+}
+
+customElements.define(SiteListElement.is, SiteListElement);
diff --git a/chrome/browser/resources/settings/site_settings/site_list_entry.js b/chrome/browser/resources/settings/site_settings/site_list_entry.js
index 635e912..f5b1aee 100644
--- a/chrome/browser/resources/settings/site_settings/site_list_entry.js
+++ b/chrome/browser/resources/settings/site_settings/site_list_entry.js
@@ -17,100 +17,114 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {FocusRowBehavior} from 'chrome://resources/js/cr/ui/focus_row_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {BaseMixin, BaseMixinInterface} from '../base_mixin.js';
 import {loadTimeData} from '../i18n_setup.js';
 import {routes} from '../route.js';
 import {Router} from '../router.js';
 
 import {ChooserType, ContentSettingsTypes, SITE_EXCEPTION_WILDCARD} from './constants.js';
-import {SiteSettingsBehavior} from './site_settings_behavior.js';
+import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from './site_settings_behavior.js';
 import {SiteException} from './site_settings_prefs_browser_proxy.js';
 
-Polymer({
-  is: 'site-list-entry',
 
-  _template: html`{__html_template__}`,
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {BaseMixinInterface}
+ * @implements {SiteSettingsBehaviorInterface}
+ */
+const SiteListEntryElementBase = mixinBehaviors(
+    [SiteSettingsBehavior, FocusRowBehavior], BaseMixin(PolymerElement));
 
-  behaviors: [
-    SiteSettingsBehavior,
-    FocusRowBehavior,
-  ],
+/** @polymer */
+class SiteListEntryElement extends SiteListEntryElementBase {
+  static get is() {
+    return 'site-list-entry';
+  }
 
-  properties: {
-    /**
-     * Some content types (like Location) do not allow the user to manually
-     * edit the exception list from within Settings.
-     * @private
-     */
-    readOnlyList: {
-      type: Boolean,
-      value: false,
-    },
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /**
-     * Site to display in the widget.
-     * @type {!SiteException}
-     */
-    model: {
-      type: Object,
-      observer: 'onModelChanged_',
-    },
+  static get properties() {
+    return {
+      /**
+       * Some content types (like Location) do not allow the user to manually
+       * edit the exception list from within Settings.
+       * @private
+       */
+      readOnlyList: {
+        type: Boolean,
+        value: false,
+      },
 
-    /**
-     * If the site represented is part of a chooser exception, the chooser type
-     * will be stored here to allow the permission to be manipulated.
-     * @private {!ChooserType}
-     */
-    chooserType: {
-      type: String,
-      value: ChooserType.NONE,
-    },
+      /**
+       * Site to display in the widget.
+       * @type {!SiteException}
+       */
+      model: {
+        type: Object,
+        observer: 'onModelChanged_',
+      },
 
-    /**
-     * If the site represented is part of a chooser exception, the chooser
-     * object will be stored here to allow the permission to be manipulated.
-     * @private
-     */
-    chooserObject: {
-      type: Object,
-      value: null,
-    },
+      /**
+       * If the site represented is part of a chooser exception, the chooser
+       * type will be stored here to allow the permission to be manipulated.
+       * @private {!ChooserType}
+       */
+      chooserType: {
+        type: String,
+        value: ChooserType.NONE,
+      },
 
-    /** @private */
-    showPolicyPrefIndicator_: {
-      type: Boolean,
-      computed: 'computeShowPolicyPrefIndicator_(model)',
-    },
+      /**
+       * If the site represented is part of a chooser exception, the chooser
+       * object will be stored here to allow the permission to be manipulated.
+       * @private
+       */
+      chooserObject: {
+        type: Object,
+        value: null,
+      },
 
-    /** @private */
-    allowNavigateToSiteDetail_: {
-      type: Boolean,
-      value: false,
-    },
-  },
+      /** @private */
+      showPolicyPrefIndicator_: {
+        type: Boolean,
+        computed: 'computeShowPolicyPrefIndicator_(model)',
+      },
+
+      /** @private */
+      allowNavigateToSiteDetail_: {
+        type: Boolean,
+        value: false,
+      },
+    };
+  }
 
   /** @private */
   onShowTooltip_() {
-    const indicator = assert(this.$$('cr-policy-pref-indicator'));
+    const indicator =
+        assert(this.shadowRoot.querySelector('cr-policy-pref-indicator'));
     // The tooltip text is used by an paper-tooltip contained inside the
     // cr-policy-pref-indicator. The text is currently held in a private
     // property. This text is needed here to send up to the common tooltip
     // component.
     const text = indicator.indicatorTooltip_;
     this.fire('show-tooltip', {target: indicator, text});
-  },
+  }
 
   /** @private */
-  onShowIncognitoTooltip_: function() {
-    const tooltip = assert(this.$$('#incognitoTooltip'));
+  onShowIncognitoTooltip_() {
+    const tooltip = assert(this.shadowRoot.querySelector('#incognitoTooltip'));
     // The tooltip text is used by an paper-tooltip contained inside the
     // cr-policy-pref-indicator. The text is currently held in a private
     // property. This text is needed here to send up to the common tooltip
     // component.
     const text = loadTimeData.getString('incognitoSiteExceptionDesc');
     this.fire('show-tooltip', {target: tooltip, text});
-  },
+  }
 
   /**
    * @return {boolean}
@@ -124,7 +138,7 @@
     return this.model.enforcement ===
         chrome.settingsPrivate.Enforcement.ENFORCED ||
         !(this.readOnlyList || !!this.model.embeddingOrigin);
-  },
+  }
 
   /**
    * @return {boolean}
@@ -138,7 +152,7 @@
     return this.model.enforcement ===
         chrome.settingsPrivate.Enforcement.ENFORCED ||
         this.readOnlyList || !!this.model.embeddingOrigin;
-  },
+  }
 
   /**
    * A handler for selecting a site (by clicking on the origin).
@@ -151,7 +165,7 @@
     Router.getInstance().navigateTo(
         routes.SITE_SETTINGS_SITE_DETAILS,
         new URLSearchParams('site=' + this.model.origin));
-  },
+  }
 
   /**
    * Returns the appropriate display name to show for the exception.
@@ -166,7 +180,7 @@
       return this.model.embeddingOrigin;
     }
     return this.model.displayName;
-  },
+  }
 
   /**
    * Returns the appropriate site description to display. This can, for example,
@@ -208,7 +222,7 @@
     // </if>
 
     return description;
-  },
+  }
 
   /**
    * @return {boolean}
@@ -218,7 +232,7 @@
     return this.model.enforcement ===
         chrome.settingsPrivate.Enforcement.ENFORCED &&
         !!this.model.controlledBy;
-  },
+  }
 
   /** @private */
   onResetButtonTap_() {
@@ -233,7 +247,7 @@
     this.browserProxy.resetCategoryPermissionForPattern(
         this.model.origin, this.model.embeddingOrigin, this.model.category,
         this.model.incognito);
-  },
+  }
 
   /** @private */
   onShowActionMenuTap_() {
@@ -245,7 +259,7 @@
     this.fire(
         'show-action-menu',
         {anchor: this.$.actionMenuButton, model: this.model});
-  },
+  }
 
   /** @private */
   onModelChanged_() {
@@ -257,4 +271,6 @@
       this.allowNavigateToSiteDetail_ = valid;
     });
   }
-});
+}
+
+customElements.define(SiteListEntryElement.is, SiteListEntryElement);
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
index da4df9b9..079b73f4 100644
--- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
+++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -207,4 +207,16 @@
    * @return {URL}
    */
   toUrl(originOrPattern) {}
+
+  /**
+   * @param {!RawSiteException} exception
+   * @return {!SiteException}
+   */
+  expandSiteException(exception) {}
+
+  /**
+   * @param {string} url
+   * @return {string}
+   */
+  sanitizePort(url) {}
 }
diff --git a/chrome/browser/resources/settings/site_settings_page/BUILD.gn b/chrome/browser/resources/settings/site_settings_page/BUILD.gn
index 0b64054..77fb059 100644
--- a/chrome/browser/resources/settings/site_settings_page/BUILD.gn
+++ b/chrome/browser/resources/settings/site_settings_page/BUILD.gn
@@ -33,6 +33,7 @@
 
 js_library("site_settings_list") {
   deps = [
+    "..:base_mixin",
     "..:router",
     "../site_settings:constants",
     "../site_settings:site_settings_prefs_browser_proxy",
diff --git a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
index dc52ba48..44d99a2 100644
--- a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
+++ b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.js
@@ -9,67 +9,86 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
-import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {routes} from '../route.js';
 import {Route, RouteObserverBehavior, Router} from '../router.js';
 import {AllSitesAction2, ContentSetting, ContentSettingsTypes, SiteSettingSource} from '../site_settings/constants.js';
-import {SiteSettingsBehavior} from '../site_settings/site_settings_behavior.js';
+import {SiteSettingsBehavior, SiteSettingsBehaviorInterface} from '../site_settings/site_settings_behavior.js';
 import {RawSiteException, RecentSitePermissions} from '../site_settings/site_settings_prefs_browser_proxy.js';
 
-Polymer({
-  is: 'settings-recent-site-permissions',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ * @implements {SiteSettingsBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsRecentSitePermissionsElementBase = mixinBehaviors(
+    [
+      RouteObserverBehavior, SiteSettingsBehavior, WebUIListenerBehavior,
+      I18nBehavior
+    ],
+    PolymerElement);
 
-  _template: html`{__html_template__}`,
+/** @polymer */
+export class SettingsRecentSitePermissionsElement extends
+    SettingsRecentSitePermissionsElementBase {
+  static get is() {
+    return 'settings-recent-site-permissions';
+  }
 
-  behaviors: [
-    RouteObserverBehavior,
-    SiteSettingsBehavior,
-    WebUIListenerBehavior,
-    I18nBehavior,
-  ],
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  properties: {
-    /** @type boolean */
-    noRecentPermissions: {
-      type: Boolean,
-      computed: 'computeNoRecentPermissions_(recentSitePermissionsList_)',
-      notify: true,
-    },
+  static get properties() {
+    return {
+      /** @type boolean */
+      noRecentPermissions: {
+        type: Boolean,
+        computed: 'computeNoRecentPermissions_(recentSitePermissionsList_)',
+        notify: true,
+      },
+
+      /**
+       * @private {boolean}
+       */
+      shouldFocusAfterPopulation_: Boolean,
+
+      /**
+       * List of recent site permissions grouped by source.
+       * @type {!Array<RecentSitePermissions>}
+       * @private
+       */
+      recentSitePermissionsList_: {
+        type: Array,
+        value: () => [],
+      },
+
+      /** @type {!Map<string, (string|Function)>} */
+      focusConfig: {
+        type: Object,
+        observer: 'focusConfigChanged_',
+      },
+    };
+  }
+
+  constructor() {
+    super();
 
     /**
-     * @private {boolean}
+     * When navigating to a site details sub-page, |lastSelected_| holds the
+     * origin and incognito bit associated with the link that sent the user
+     * there, as well as the index in recent permission list for that entry.
+     * This allows for an intelligent re-focus upon a back navigation.
+     * @private {!{origin: string, incognito: boolean, index: number}|null}
      */
-    shouldFocusAfterPopulation_: Boolean,
-
-    /**
-     * List of recent site permissions grouped by source.
-     * @type {!Array<RecentSitePermissions>}
-     * @private
-     */
-    recentSitePermissionsList_: {
-      type: Array,
-      value: () => [],
-    },
-
-    /** @type {!Map<string, (string|Function)>} */
-    focusConfig: {
-      type: Object,
-      observer: 'focusConfigChanged_',
-    },
-  },
-
-  /**
-   * When navigating to a site details sub-page, |lastSelected_| holds the
-   * origin and incognito bit associated with the link that sent the user there,
-   * as well as the index in recent permission list for that entry. This allows
-   * for an intelligent re-focus upon a back navigation.
-   * @private {!{origin: string, incognito: boolean, index: number}|null}
-   */
-  lastSelected_: null,
+    this.lastSelected_ = null;
+  }
 
   /**
    * @param {!Map<string, string>} newConfig
@@ -87,7 +106,7 @@
         () => {
           this.shouldFocusAfterPopulation_ = true;
         });
-  },
+  }
 
   /**
    * Reload the site recent site permission list whenever the user navigates
@@ -99,14 +118,16 @@
     if (currentRoute.path === routes.SITE_SETTINGS.path) {
       this.populateList_();
     }
-  },
+  }
 
   /** @override */
   ready() {
+    super.ready();
+
     this.addWebUIListener(
         'onIncognitoStatusChanged', this.onIncognitoStatusChanged_.bind(this));
     this.browserProxy.updateIncognitoStatus();
-  },
+  }
 
   /**
    * Perform internationalization for the given content settings type.
@@ -183,7 +204,7 @@
       default:
         return '';
     }
-  },
+  }
 
   /**
    * Returns a user-friendly name for the origin a set of recent permissions
@@ -195,7 +216,7 @@
   getDisplayName_(recentSitePermissions) {
     const url = this.toUrl(recentSitePermissions.origin);
     return url.host;
-  },
+  }
 
   /**
    * Returns the site scheme for the origin of a set of recent permissions.
@@ -207,7 +228,7 @@
     const url = this.toUrl(origin);
     const scheme = url.protocol.slice(0, -1);
     return scheme === 'https' ? '' : scheme;
-  },
+  }
 
   /**
    * Returns the display text which describes the set of recent permissions.
@@ -249,7 +270,7 @@
       finalText += this.i18n('sentenceEnd');
     }
     return finalText;
-  },
+  }
 
   /**
    * Returns the display sentence which groups the provided |exceptions|
@@ -276,7 +297,7 @@
     return this.i18n(
         `recentPermission${setting}MoreThanTwoItems`, typeStrings[0],
         exceptions.length - 1);
-  },
+  }
 
   /**
    * Returns the correct class to apply depending on this recent site
@@ -287,7 +308,7 @@
    */
   getClassForIndex_(index) {
     return index === 0 ? 'first' : '';
-  },
+  }
 
   /**
    * Returns true if there are no recent site permissions to display
@@ -296,7 +317,7 @@
    */
   computeNoRecentPermissions_() {
     return this.recentSitePermissionsList_.length === 0;
-  },
+  }
 
   /**
    * Called for when incognito is enabled or disabled. Only called on change
@@ -312,7 +333,7 @@
         this.recentSitePermissionsList_.some(p => p.incognito)) {
       this.populateList_();
     }
-  },
+  }
 
   /**
    * A handler for selecting a recent site permissions entry.
@@ -329,7 +350,7 @@
       origin: e.model.item.origin,
       incognito: e.model.item.incognito,
     };
-  },
+  }
 
   /**
    * @param {!Event} e
@@ -355,7 +376,7 @@
     tooltip.addEventListener('mouseenter', hide);
 
     tooltip.show();
-  },
+  }
 
   /**
    * Called after the list has finished populating and |lastSelected_| contains
@@ -381,13 +402,15 @@
     const index = currentIndex > -1 ? currentIndex : fallbackIndex;
 
     if (this.recentSitePermissionsList_[index].incognito) {
-      focusWithoutInk(assert(/** @type {{getFocusableElement: Function}} */ (
-                                 this.$$(`#incognitoInfoIcon_${index}`))
-                                 .getFocusableElement()));
+      focusWithoutInk(assert(
+          /** @type {{getFocusableElement: Function}} */ (
+              this.shadowRoot.querySelector(`#incognitoInfoIcon_${index}`))
+              .getFocusableElement()));
     } else {
-      focusWithoutInk(assert(this.$$(`#siteEntryButton_${index}`)));
+      focusWithoutInk(
+          assert(this.shadowRoot.querySelector(`#siteEntryButton_${index}`)));
     }
-  },
+  }
 
   /**
    * Retrieve the list of recently changed permissions and implicitly trigger
@@ -397,7 +420,7 @@
   async populateList_() {
     this.recentSitePermissionsList_ =
         await this.browserProxy.getRecentSitePermissions(3);
-  },
+  }
 
   /**
    * Called when the dom-repeat DOM has changed. This allows updating the
@@ -409,5 +432,9 @@
       this.focusLastSelected_();
       this.shouldFocusAfterPopulation_ = false;
     }
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsRecentSitePermissionsElement.is,
+    SettingsRecentSitePermissionsElement);
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_list.js b/chrome/browser/resources/settings/site_settings_page/site_settings_list.js
index 23a67b85..cd69253 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_list.js
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_list.js
@@ -9,12 +9,13 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
-import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
-import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {html, microTask, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {BaseMixin, BaseMixinInterface} from '../base_mixin.js';
 import {loadTimeData} from '../i18n_setup.js';
-import {PrefsBehavior} from '../prefs/prefs_behavior.js';
+import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js';
 import {Route, Router} from '../router.js';
 import {ContentSetting, ContentSettingsTypes, NotificationSetting} from '../site_settings/constants.js';
 import {SiteSettingsPrefsBrowserProxy, SiteSettingsPrefsBrowserProxyImpl} from '../site_settings/site_settings_prefs_browser_proxy.js';
@@ -50,33 +51,58 @@
   return other || enabled;
 }
 
-Polymer({
-  is: 'settings-site-settings-list',
 
-  _template: html`{__html_template__}`,
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {BaseMixinInterface}
+ * @implements {I18nBehaviorInterface}
+ * @implements {PrefsBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsSiteSettingsListElementBase = mixinBehaviors(
+    [WebUIListenerBehavior, I18nBehavior, PrefsBehavior],
+    BaseMixin(PolymerElement));
 
-  behaviors: [WebUIListenerBehavior, I18nBehavior, PrefsBehavior],
+/** @polymer */
+class SettingsSiteSettingsListElement extends
+    SettingsSiteSettingsListElementBase {
+  static get is() {
+    return 'settings-site-settings-list';
+  }
 
-  properties: {
-    /** @type {!Array<!CategoryListItem>} */
-    categoryList: Array,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** @type {!Map<string, (string|Function)>} */
-    focusConfig: {
-      type: Object,
-      observer: 'focusConfigChanged_',
-    },
-  },
+  static get properties() {
+    return {
+      /** @type {!Array<!CategoryListItem>} */
+      categoryList: Array,
 
-  observers: [
-    // The prefs object is only populated for the instance of this element
-    // which contains the notifications link row, avoiding non-actionable
-    // firing of the observer.
-    'updateNotificationsLabel_(prefs.generated.notification.*)'
-  ],
+      /** @type {!Map<string, (string|Function)>} */
+      focusConfig: {
+        type: Object,
+        observer: 'focusConfigChanged_',
+      },
+    };
+  }
 
-  /** @type {?SiteSettingsPrefsBrowserProxy} */
-  browserProxy: null,
+  static get observers() {
+    return [
+      // The prefs object is only populated for the instance of this element
+      // which contains the notifications link row, avoiding non-actionable
+      // firing of the observer.
+      'updateNotificationsLabel_(prefs.generated.notification.*)'
+    ];
+  }
+
+  constructor() {
+    super();
+
+    /** @private {!SiteSettingsPrefsBrowserProxy} */
+    this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
+  }
 
   /**
    * @param {!Map<string, string>} newConfig
@@ -92,15 +118,15 @@
     // element, with additional entries that correspond to subpage trigger
     // elements residing in this element's Shadow DOM.
     for (const item of this.categoryList) {
-      this.focusConfig.set(item.route.path, () => this.async(() => {
-        focusWithoutInk(assert(this.$$(`#${item.id}`)));
+      this.focusConfig.set(item.route.path, () => microTask.run(() => {
+        focusWithoutInk(assert(this.shadowRoot.querySelector(`#${item.id}`)));
       }));
     }
-  },
+  }
 
   /** @override */
   ready() {
-    this.browserProxy_ = SiteSettingsPrefsBrowserProxyImpl.getInstance();
+    super.ready();
 
     Promise
         .all(this.categoryList.map(
@@ -138,7 +164,7 @@
           'cookieSettingDescriptionChanged',
           this.updateCookiesLabel_.bind(this));
     }
-  },
+  }
 
   /**
    * @param {!ContentSettingsTypes} category The category to refresh
@@ -172,7 +198,7 @@
         defaultValue => {
           this.updateDefaultValueLabel_(category, defaultValue.setting);
         });
-  },
+  }
 
   /**
    * Updates the DOM for the given |category| to display a label that
@@ -182,13 +208,14 @@
    * @private
    */
   updateDefaultValueLabel_(category, setting) {
-    const element = this.$$(`#${category}`);
+    const element = this.shadowRoot.querySelector(`#${category}`);
     if (!element) {
       // |category| is not part of this list.
       return;
     }
 
-    const index = this.$$('dom-repeat').indexForElement(element);
+    const index =
+        this.shadowRoot.querySelector('dom-repeat').indexForElement(element);
     const dataItem = this.categoryList[index];
     this.set(
         `categoryList.${index}.subLabel`,
@@ -197,7 +224,7 @@
             dataItem.enabledLabel ? this.i18n(dataItem.enabledLabel) : '',
             dataItem.disabledLabel ? this.i18n(dataItem.disabledLabel) : '',
             dataItem.otherLabel ? this.i18n(dataItem.otherLabel) : null));
-  },
+  }
 
   /**
    * Update the cookies link row label when the cookies setting description
@@ -206,9 +233,11 @@
    * @private
    */
   updateCookiesLabel_(label) {
-    const index = this.$$('dom-repeat').indexForElement(this.$$('#cookies'));
+    const index =
+        this.shadowRoot.querySelector('dom-repeat')
+            .indexForElement(this.shadowRoot.querySelector('#cookies'));
     this.set(`categoryList.${index}.subLabel`, label);
-  },
+  }
 
   /**
    * Update the notifications link row label when the notifications setting
@@ -237,7 +266,7 @@
                                 'siteSettingsAskBeforeSending';
     }
     this.set(`categoryList.${index}.subLabel`, this.i18n(label));
-  },
+  }
 
   /**
    * @param {!Event} event
@@ -245,5 +274,8 @@
    */
   onClick_(event) {
     Router.getInstance().navigateTo(this.categoryList[event.model.index].route);
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsSiteSettingsListElement.is, SettingsSiteSettingsListElement);
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
index 81f3ad01..d4268da0 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -17,7 +17,7 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {loadTimeData} from '../i18n_setup.js';
 import {routes} from '../route.js';
@@ -389,93 +389,100 @@
   return orderedList;
 }
 
-Polymer({
-  is: 'settings-site-settings-page',
+/** @polymer */
+export class SettingsSiteSettingsPageElement extends PolymerElement {
+  static get is() {
+    return 'settings-site-settings-page';
+  }
 
-  _template: html`{__html_template__}`,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  properties: {
-    /**
-     * Preferences state.
-     */
-    prefs: {
-      type: Object,
-      notify: true,
-    },
+  static get properties() {
+    return {
+      /**
+       * Preferences state.
+       */
+      prefs: {
+        type: Object,
+        notify: true,
+      },
 
-    /**
-     * @private {{
-     *   all: (!Array<!CategoryListItem>|undefined),
-     *   permissionsBasic: (!Array<!CategoryListItem>|undefined),
-     *   permissionsAdvanced: (!Array<!CategoryListItem>|undefined),
-     *   contentBasic: (!Array<!CategoryListItem>|undefined),
-     *   contentAdvanced: (!Array<!CategoryListItem>|undefined)
-     * }}
-     */
-    lists_: {
-      type: Object,
-      value: function() {
-        return {
-          permissionsBasic: buildItemListFromIds([
-            Id.GEOLOCATION,
-            Id.CAMERA,
-            Id.MIC,
-            Id.NOTIFICATIONS,
-            Id.BACKGROUND_SYNC,
-          ]),
-          permissionsAdvanced: buildItemListFromIds([
-            Id.SENSORS,
-            Id.AUTOMATIC_DOWNLOADS,
-            Id.PROTOCOL_HANDLERS,
-            Id.MIDI_DEVICES,
-            Id.USB_DEVICES,
-            Id.SERIAL_PORTS,
-            Id.BLUETOOTH_DEVICES,
-            Id.FILE_SYSTEM_WRITE,
-            Id.HID_DEVICES,
-            Id.CLIPBOARD,
-            Id.PAYMENT_HANDLER,
-            Id.BLUETOOTH_SCANNING,
-            Id.AR,
-            Id.VR,
-            Id.IDLE_DETECTION,
-            Id.WINDOW_PLACEMENT,
-            Id.FONT_ACCESS,
-            Id.FILE_HANDLING,
-          ]),
-          contentBasic: buildItemListFromIds([
-            Id.COOKIES,
-            Id.JAVASCRIPT,
-            Id.IMAGES,
-            Id.POPUPS,
-          ]),
-          contentAdvanced: buildItemListFromIds([
-            Id.SOUND,
-            Id.ADS,
-            Id.ZOOM_LEVELS,
-            'pdfDocuments',
-            Id.PROTECTED_CONTENT,
-            Id.MIXEDSCRIPT,
-          ]),
-        };
-      }
-    },
+      /**
+       * @private {{
+       *   all: (!Array<!CategoryListItem>|undefined),
+       *   permissionsBasic: (!Array<!CategoryListItem>|undefined),
+       *   permissionsAdvanced: (!Array<!CategoryListItem>|undefined),
+       *   contentBasic: (!Array<!CategoryListItem>|undefined),
+       *   contentAdvanced: (!Array<!CategoryListItem>|undefined)
+       * }}
+       */
+      lists_: {
+        type: Object,
+        value: function() {
+          return {
+            permissionsBasic: buildItemListFromIds([
+              Id.GEOLOCATION,
+              Id.CAMERA,
+              Id.MIC,
+              Id.NOTIFICATIONS,
+              Id.BACKGROUND_SYNC,
+            ]),
+            permissionsAdvanced: buildItemListFromIds([
+              Id.SENSORS,
+              Id.AUTOMATIC_DOWNLOADS,
+              Id.PROTOCOL_HANDLERS,
+              Id.MIDI_DEVICES,
+              Id.USB_DEVICES,
+              Id.SERIAL_PORTS,
+              Id.BLUETOOTH_DEVICES,
+              Id.FILE_SYSTEM_WRITE,
+              Id.HID_DEVICES,
+              Id.CLIPBOARD,
+              Id.PAYMENT_HANDLER,
+              Id.BLUETOOTH_SCANNING,
+              Id.AR,
+              Id.VR,
+              Id.IDLE_DETECTION,
+              Id.WINDOW_PLACEMENT,
+              Id.FONT_ACCESS,
+              Id.FILE_HANDLING,
+            ]),
+            contentBasic: buildItemListFromIds([
+              Id.COOKIES,
+              Id.JAVASCRIPT,
+              Id.IMAGES,
+              Id.POPUPS,
+            ]),
+            contentAdvanced: buildItemListFromIds([
+              Id.SOUND,
+              Id.ADS,
+              Id.ZOOM_LEVELS,
+              'pdfDocuments',
+              Id.PROTECTED_CONTENT,
+              Id.MIXEDSCRIPT,
+            ]),
+          };
+        }
+      },
 
-    /** @type {!Map<string, (string|Function)>} */
-    focusConfig: {
-      type: Object,
-      observer: 'focusConfigChanged_',
-    },
+      /** @type {!Map<string, (string|Function)>} */
+      focusConfig: {
+        type: Object,
+        observer: 'focusConfigChanged_',
+      },
 
-    /** @private */
-    permissionsExpanded_: Boolean,
+      /** @private */
+      permissionsExpanded_: Boolean,
 
-    /** @private */
-    contentExpanded_: Boolean,
+      /** @private */
+      contentExpanded_: Boolean,
 
-    /* @private */
-    noRecentSitePermissions_: Boolean,
-  },
+      /* @private */
+      noRecentSitePermissions_: Boolean,
+    };
+  }
 
   /**
    * @param {!Map<string, string>} newConfig
@@ -487,14 +494,14 @@
     // only fire once.
     assert(!oldConfig);
     this.focusConfig.set(routes.SITE_SETTINGS_ALL.path, () => {
-      focusWithoutInk(assert(this.$$('#allSites')));
+      focusWithoutInk(assert(this.shadowRoot.querySelector('#allSites')));
     });
-  },
+  }
 
   /** @private */
   onSiteSettingsAllClick_() {
     Router.getInstance().navigateTo(routes.SITE_SETTINGS_ALL);
-  },
+  }
 
   /**
    * @return {string} Class for the all site settings link
@@ -502,5 +509,8 @@
    */
   getClassForSiteSettingsAllLink_() {
     return this.noRecentSitePermissions_ ? '' : 'hr';
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsSiteSettingsPageElement.is, SettingsSiteSettingsPageElement);
diff --git a/chrome/browser/resources/tab_search/app.js b/chrome/browser/resources/tab_search/app.js
index 129482b..434156b 100644
--- a/chrome/browser/resources/tab_search/app.js
+++ b/chrome/browser/resources/tab_search/app.js
@@ -322,7 +322,7 @@
     this.updateFilteredTabs_();
     // Reset the selected item whenever a search query is provided.
     /** @type {!InfiniteList} */ (this.$.tabsList).selected =
-        this.filteredItems_.length > 0 ? 0 : NO_SELECTION;
+        this.selectableItemCount_() > 0 ? 0 : NO_SELECTION;
 
     this.$.searchField.announce(this.getA11ySearchResultText_());
   }
@@ -336,10 +336,7 @@
     // not match as it counts the title items too. Investigate how to
     // programmatically control announcements to avoid this.
 
-    // The number of list items excluding any section title items.
-    const itemCount = this.filteredItems_.reduce((acc, item) => {
-      return acc + (!(item instanceof TitleItem) ? 1 : 0);
-    }, 0);
+    const itemCount = this.selectableItemCount_();
     let text;
     if (this.searchText_.length > 0) {
       text = loadTimeData.getStringF(
@@ -353,6 +350,17 @@
   }
 
   /**
+   * @returns {number} The number of selectable list items, excludes non
+   *     selectable items such as section title items.
+   * @private
+   */
+  selectableItemCount_() {
+    return this.filteredItems_.reduce((acc, item) => {
+      return acc + (item instanceof TitleItem ? 0 : 1);
+    }, 0);
+  }
+
+  /**
    * @param {!Event} e
    * @private
    */
@@ -453,7 +461,7 @@
     // If there are no matching results, set the selected index value to none.
     const tabsList = /** @type {!InfiniteList} */ (this.$.tabsList);
     tabsList.selected = Math.min(
-        Math.max(this.getSelectedIndex(), 0), this.filteredItems_.length - 1);
+        Math.max(this.getSelectedIndex(), 0), this.selectableItemCount_() - 1);
   }
 
   /**
@@ -470,7 +478,7 @@
   /** @private */
   onSearchFocus_() {
     const tabsList = /** @type {!InfiniteList} */ (this.$.tabsList);
-    if (tabsList.selected === NO_SELECTION && this.filteredItems_.length > 0) {
+    if (tabsList.selected === NO_SELECTION && this.selectableItemCount_() > 0) {
       tabsList.selected = 0;
     }
   }
diff --git a/chrome/browser/resources/tab_search/infinite_list.js b/chrome/browser/resources/tab_search/infinite_list.js
index b46a5ca9..073e7fd 100644
--- a/chrome/browser/resources/tab_search/infinite_list.js
+++ b/chrome/browser/resources/tab_search/infinite_list.js
@@ -622,7 +622,9 @@
 
     const selector = /** @type {!IronSelectorElement} */ (this.$.selector);
     if (index !== selector.selected) {
-      assert(index < this.selectableIndexToItemIndex_.size());
+      assert(
+          index < this.selectableIndexToItemIndex_.size(),
+          'Selection index is out of range.');
       this.ensureSelectableDomItemAvailable_(index);
       selector.selected = index;
     }
diff --git a/chrome/browser/resources/web_app_internals/BUILD.gn b/chrome/browser/resources/web_app_internals/BUILD.gn
deleted file mode 100644
index a02c5b4..0000000
--- a/chrome/browser/resources/web_app_internals/BUILD.gn
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2020 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
-
-html_to_js("components") {
-  js_files = [ "web_app_internals.js" ]
-}
-
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  deps = [ ":web_app_internals" ]
-}
-
-js_library("web_app_internals") {
-  deps = [
-    "//chrome/browser/ui/webui/internals/web_app:mojo_bindings_js_library_for_compile",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-}
diff --git a/chrome/browser/resources/web_app_internals/index.html b/chrome/browser/resources/web_app_internals/index.html
index 9cbae31..00ad4de 100644
--- a/chrome/browser/resources/web_app_internals/index.html
+++ b/chrome/browser/resources/web_app_internals/index.html
@@ -1,12 +1,2 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
-    <title>Web App Internals</title>
-  </head>
-  <body>
-    <web-app-internals></web-app-internals>
-    <script type="module" src="web_app_internals.js"></script>
-  </body>
-</html>
+This page has moved to:
+<a href="chrome://web-app-internals">chrome://web-app-internals</a>
diff --git a/chrome/browser/resources/web_app_internals/web_app_internals.html b/chrome/browser/resources/web_app_internals/web_app_internals.html
deleted file mode 100644
index 080ac52..0000000
--- a/chrome/browser/resources/web_app_internals/web_app_internals.html
+++ /dev/null
@@ -1,182 +0,0 @@
-<style>
-  h2 {
-    margin-bottom: 0;
-    margin-top: 10px;
-  }
-
-  h3 {
-    margin-bottom: 0;
-  }
-
-  .section {
-    margin: 10px;
-    margin-bottom: 20px;
-    padding: 5px;
-  }
-
-  .web-app {
-    background-color: var(--highlight, #00000007);
-    border-inline-start-color: rgb(0, 50, 220);
-    border-inline-start-style: solid;
-  }
-
-  .highlight {
-    --highlight: #eff;
-  }
-
-  .web-app-name {
-    font-weight: bold;
-  }
-</style>
-
-<h1>Web App Internals</h1>
-
-<div class="section">
-  <p>Save JSON: <button id="saveButton">Save file</button></p>
-  <p>Load JSON: <input type="file" id="loadButton"></p>
-</div>
-
-<div class="section">
-  <h2>Page Index:</h2>
-  <h3><a href="#installed">Installed Web Apps</a></h3>
-  <h3><a href="#preinstalled">Preinstalled Web Apps</a></h3>
-  <template is="dom-if" if="[[preinstalledWebAppDebugInfo_]]">
-    <div><a href="#preinstalled-errors">Parse Errors</a></div>
-    <div><a href="#preinstalled-enabled">Enabled Configs</a></div>
-    <div><a href="#preinstalled-disabled">Disabled Configs</a></div>
-    <div><a href="#preinstalled-installs">Install Results</a></div>
-    <div><a href="#preinstalled-uninstalls">Uninstall Results</a></div>
-  </template>
-
-  <h3><a href="#external-prefs">Externally Installed Web App Prefs</a></h3>
-  <h3><a href="#icon-error-log">Icon Error Log</a></h3>
-</div>
-
-<div class="section">
-  <h2 id="installed">Installed Web Apps</h2>
-  <template is="dom-repeat" items="[[webAppList_]]">
-    <div>
-      <a href="#[[item.id]]">
-        <img src="chrome://app-icon/[[item.id]]/32" width="32" height="32">
-        [[item.name]]
-      </a>
-    </div>
-  </template>
-  <template is="dom-repeat" items="[[webAppList_]]">
-    <div class="section web-app" id="[[item.id]]">
-      <h2>[[item.name]]</h2>
-      <img src="chrome://app-icon/[[item.id]]/128">
-      <pre>[[item.debugInfo]]</pre>
-    </div>
-  </template>
-</div>
-
-<div class="section">
-  <h2 id="preinstalled">Preinstalled Web Apps</h2>
-  <template is="dom-if" if="[[!preinstalledWebAppDebugInfo_]]">
-    <p>
-      No debugging info available! Please enable
-      <a href="chrome://flags/#record-web-app-debug-info">
-        chrome://flags/#record-web-app-debug-info
-      </a>.
-    </p>
-  </template>
-
-  <template is="dom-if" if="[[preinstalledWebAppDebugInfo_]]">
-    <p>
-      <a href="chrome://flags/#record-web-app-debug-info">
-        chrome://flags/#record-web-app-debug-info
-      </a>
-      flag is enabled, debugging info is being captured.
-    </p>
-
-    <p>
-      Is start up task complete (also required for debug info):
-      <b>[[preinstalledWebAppDebugInfo_.isStartUpTaskComplete]]</b>
-    </p>
-
-    <h3 id="preinstalled-errors">Parse Errors</h3>
-    <ul>
-      <template is="dom-repeat"
-          items="[[preinstalledWebAppDebugInfo_.parseErrors]]">
-        <li>[[item]]</li>
-      </template>
-    </ul>
-
-    <h3 id="preinstalled-enabled">Enabled Configs</h3>
-    <ul>
-      <template is="dom-repeat"
-          items="[[preinstalledWebAppDebugInfo_.enabledConfigs]]">
-        <li><pre>[[item]]</pre></li>
-      </template>
-    </ul>
-
-    <h3 id="preinstalled-disabled">Disabled Configs</h3>
-    <ul>
-      <template is="dom-repeat"
-          items="[[preinstalledWebAppDebugInfo_.disabledConfigs]]">
-        <li>
-          <b>[[item.reason]]</b>
-          <pre>[[item.config]]</pre>
-        </li>
-      </template>
-    </ul>
-
-    <h3 id="preinstalled-installs">Install Results</h3>
-    <ul>
-      <template is="dom-repeat"
-          items="[[preinstalledWebAppDebugInfo_.installResults]]">
-        <li>
-          <div>Install URL: [[item.installUrl]]</div>
-          <div>InstallResultCode: [[item.installResultCode]]</div>
-          <div>Did uninstall_and_replace: [[item.didUninstallAndReplace]]</div>
-        </li>
-      </template>
-    </ul>
-
-    <h3 id="preinstalled-uninstalls">Uninstall Results</h3>
-    <ul>
-      <template is="dom-repeat"
-          items="[[preinstalledWebAppDebugInfo_.uninstallResults]]">
-        <li>
-          <div>Install URL: [[item.installUrl]]</div>
-          <div>Success: [[item.isSuccess]]</div>
-        </li>
-      </template>
-    </ul>
-  </template>
-</div>
-
-<div class="section">
-  <h2 id="external-prefs">Externally Installed Web App Prefs</h2>
-  <pre>[[externallyInstalledWebAppPrefs_]]</pre>
-</div>
-
-<div class="section">
-  <h2 id="icon-error-log">Icon Error Log</h2>
-  <template is="dom-if" if="[[!iconErrorLog_]]">
-    <p>
-      Icon error log unavailable! Please enable
-      <a href="chrome://flags/#record-web-app-debug-info">
-        chrome://flags/#record-web-app-debug-info
-      </a>.
-    </p>
-  </template>
-
-  <template is="dom-if" if="[[iconErrorLog_]]">
-    <p>
-      <a href="chrome://flags/#record-web-app-debug-info">
-        chrome://flags/#record-web-app-debug-info
-      </a>
-      flag is enabled, icon error log is being captured.
-    </p>
-  </template>
-
-  <template is="dom-if" if="[[iconErrorLog_]]">
-    <ul>
-      <template is="dom-repeat" items="[[iconErrorLog_]]">
-        <li>[[item]]</li>
-      </template>
-    </ul>
-  </template>
-</div>
diff --git a/chrome/browser/resources/web_app_internals/web_app_internals.js b/chrome/browser/resources/web_app_internals/web_app_internals.js
deleted file mode 100644
index 99e434b..0000000
--- a/chrome/browser/resources/web_app_internals/web_app_internals.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js';
-import './web_app_internals.mojom-lite.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-Polymer({
-  is: 'web-app-internals',
-
-  _template: html`{__html_template__}`,
-
-  properties: {
-    /**
-     * List of internal details about installed web apps.
-     * @private {!Array<!mojom.webAppInternals.WebApp>}
-     */
-    webAppList_: Array,
-
-    /**
-     * Debug information about preinstalled web apps.
-     * @private {!mojom.webAppInternals.PreinstalledWebAppDebugInfo|null}
-     */
-    preinstalledWebAppDebugInfo_: Object,
-
-    /**
-     * Prefs associated with non-user installed web apps.
-     * @private {!string}
-     */
-    externallyInstalledWebAppPrefs_: String,
-
-    /**
-     * List of error messages generated by icon reading/writing.
-     * @private {!Array<!string>|null}
-     */
-    iconErrorLog_: Array,
-  },
-
-  /**
-   * @override
-   * Fetches internal data about installed web apps from the browser.
-   */
-  ready() {
-    (async () => {
-      const remote =
-          mojom.webAppInternals.WebAppInternalsPageHandler.getRemote();
-
-      this.webAppList_ = (await remote.getWebApps()).webAppList;
-      this.webAppList_.sort((a, b) => a.name.localeCompare(b.name));
-
-      this.preinstalledWebAppDebugInfo_ =
-          (await remote.getPreinstalledWebAppDebugInfo()).status;
-
-      this.externallyInstalledWebAppPrefs_ =
-          (await remote.getExternallyInstalledWebAppPrefs())
-              .externallyInstalledWebAppPrefs;
-
-      this.iconErrorLog_ = (await remote.getIconErrorLog()).iconErrorLog;
-
-      this.highlightHashedId_();
-      this.hashChangeListener_ = () => this.highlightHashedId_();
-      window.addEventListener('hashchange', this.hashChangeListener_);
-
-      this.$.saveButton.addEventListener('click', () => this.save());
-      this.$.loadButton.addEventListener(
-          'change', event => this.load(event.target.files[0]));
-    })();
-  },
-
-  /**
-   * @override
-   * Cleans up global event listeners.
-   */
-  detached() {
-    window.removeEventListener('hashchange', this.hashChangeListener_);
-  },
-
-  /**
-   * Reads the current URL hash, scrolls the targeted element into view and
-   * highlights it.
-   * @private
-   */
-  highlightHashedId_() {
-    for (const element of this.shadowRoot.querySelectorAll('.highlight')) {
-      element.classList.remove('highlight');
-    }
-
-    if (!location.hash) {
-      return;
-    }
-
-    const highlighted = this.shadowRoot.querySelector(location.hash);
-    if (!highlighted) {
-      return;
-    }
-
-    highlighted.scrollIntoView();
-    highlighted.classList.add('highlight');
-  },
-
-  /**
-   * Saves the data contents of the page to a JSON file.
-   * @private
-   */
-  save() {
-    const data = Object.fromEntries(
-        Object.keys(this.properties).map(key => [key, this[key]]));
-    const file = new Blob(
-        [JSON.stringify(data, null, '  ')], {type: 'application/json'});
-    const a = document.createElement('a');
-    a.href = URL.createObjectURL(file);
-    a.download = 'web-app-internals.json';
-    a.click();
-    URL.revokeObjectURL(a.href);
-  },
-
-  /**
-   * Loads the given JSON file as the data contents of the page.
-   * @param {File} file
-   * @private
-   * @suppress {checkTypes} Closure doesn't know about
-         FileReader.readAsText(File).
-   */
-  load(file) {
-    const reader = new FileReader();
-    reader.addEventListener('load', event => {
-      const json = JSON.parse(event.target.result);
-      for (const key of Object.keys(this.properties)) {
-        this[key] = json[key];
-      }
-    });
-    reader.readAsText(file);
-  },
-});
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index aae3576..8ccefad 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -397,8 +397,6 @@
 
 source_set("metrics_collector") {
   sources = [
-    "safe_browsing_metrics_collector.cc",
-    "safe_browsing_metrics_collector.h",
     "safe_browsing_metrics_collector_factory.cc",
     "safe_browsing_metrics_collector_factory.h",
   ]
@@ -409,6 +407,7 @@
     "//chrome/common",
     "//components/keyed_service/content",
     "//components/prefs",
+    "//components/safe_browsing/content/browser",
     "//components/safe_browsing/core/common",
     "//components/safe_browsing/core/common:safe_browsing_prefs",
     "//content/public/browser",
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
index 7c874d8..cc517c2 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
@@ -54,6 +53,7 @@
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_navigation_throttle.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_request_content.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_throttler.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/browser/db/database_manager.h"
@@ -1422,7 +1422,8 @@
   // Determines how many recent navigation events to append to referrer chain.
   size_t recent_navigations_to_collect =
       profile_ ? SafeBrowsingNavigationObserverManager::
-                     CountOfRecentNavigationsToAppend(*profile_, result)
+                     CountOfRecentNavigationsToAppend(
+                         profile_, profile_->GetPrefs(), result)
                : 0u;
   navigation_observer_manager->AppendRecentNavigations(
       recent_navigations_to_collect, frame->mutable_referrer_chain());
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
index da57e00c..3a51848 100644
--- a/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
+++ b/chrome/browser/safe_browsing/client_side_detection_host_delegate.cc
@@ -115,11 +115,11 @@
 
 size_t ClientSideDetectionHostDelegate::CountOfRecentNavigationsToAppend(
     SafeBrowsingNavigationObserverManager::AttributionResult result) {
+  auto* profile =
+      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
   return web_contents_ ? SafeBrowsingNavigationObserverManager::
                              CountOfRecentNavigationsToAppend(
-                                 *Profile::FromBrowserContext(
-                                     web_contents_->GetBrowserContext()),
-                                 result)
+                                 profile, profile->GetPrefs(), result)
                        : 0u;
 }
 
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
index 6688569..a9c3b2b 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -498,12 +498,12 @@
 
   // Determines how many recent navigation events to append to referrer chain
   // if any.
+  auto* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
   size_t recent_navigations_to_collect =
       web_contents ? SafeBrowsingNavigationObserverManager::
                          CountOfRecentNavigationsToAppend(
-                             *Profile::FromBrowserContext(
-                                 web_contents->GetBrowserContext()),
-                             result)
+                             profile, profile->GetPrefs(), result)
                    : 0u;
   GetNavigationObserverManager(web_contents)
       ->AppendRecentNavigations(recent_navigations_to_collect,
@@ -543,12 +543,12 @@
 
   // Determines how many recent navigation events to append to referrer chain
   // if any.
+  auto* profile = Profile::FromBrowserContext(item.browser_context);
   size_t recent_navigations_to_collect =
-      item.browser_context
-          ? SafeBrowsingNavigationObserverManager::
-                CountOfRecentNavigationsToAppend(
-                    *Profile::FromBrowserContext(item.browser_context), result)
-          : 0u;
+      item.browser_context ? SafeBrowsingNavigationObserverManager::
+                                 CountOfRecentNavigationsToAppend(
+                                     profile, profile->GetPrefs(), result)
+                           : 0u;
   GetNavigationObserverManager(item.web_contents)
       ->AppendRecentNavigations(recent_navigations_to_collect,
                                 referrer_chain.get());
diff --git a/chrome/browser/safe_browsing/download_protection/download_reporter.cc b/chrome/browser/safe_browsing/download_protection/download_reporter.cc
index 45fece2..a359af2 100644
--- a/chrome/browser/safe_browsing/download_protection/download_reporter.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_reporter.cc
@@ -13,13 +13,13 @@
 #include "chrome/browser/profiles/profile_key.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/download/public/common/download_danger_type.h"
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/simple_download_manager_coordinator.h"
 #include "components/safe_browsing/content/browser/download/download_stats.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/download_item_utils.h"
 #include "url/url_constants.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index dd219cf..74a7759 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -14,17 +14,14 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/interstitials/chrome_settings_page_helper.h"
-#include "chrome/browser/interstitials/enterprise_util.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/renderer_preferences_util.h"
 #include "chrome/browser/safe_browsing/chrome_controller_client.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "components/safe_browsing/content/browser/threat_details.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/core/common/features.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc b/chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc
index f05b339..9a1e843 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.cc
@@ -6,8 +6,8 @@
 
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "content/public/browser/browser_context.h"
 
 namespace safe_browsing {
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
index 860d757..04d19853 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -88,7 +88,9 @@
     return;
 
   if (safe_browsing::SafeBrowsingNavigationObserverManager::IsEnabledAndReady(
-          Profile::FromBrowserContext(web_contents->GetBrowserContext()))) {
+          Profile::FromBrowserContext(web_contents->GetBrowserContext())
+              ->GetPrefs(),
+          g_browser_process->safe_browsing_service())) {
     web_contents->SetUserData(
         kWebContentsUserDataKey,
         std::make_unique<SafeBrowsingNavigationObserver>(web_contents));
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
index 2accfa7..e7b57e7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -527,12 +527,13 @@
                                      extended_reporting_enabled);
     browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled,
                                                  extended_reporting_enabled);
+    auto* maybe_otr_profile = is_incognito
+                                  ? browser()->profile()->GetPrimaryOTRProfile(
+                                        /*create_if_needed=*/true)
+                                  : browser()->profile();
     return SafeBrowsingNavigationObserverManager::
-        CountOfRecentNavigationsToAppend(
-            is_incognito ? *browser()->profile()->GetPrimaryOTRProfile(
-                               /*create_if_needed=*/true)
-                         : *browser()->profile(),
-            result);
+        CountOfRecentNavigationsToAppend(maybe_otr_profile,
+                                         maybe_otr_profile->GetPrefs(), result);
   }
 
   void AppendRecentNavigations(int recent_navigation_count,
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
index f04e1fa..80a75cb 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
@@ -13,11 +13,7 @@
 #include "base/rand_util.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer.h"
-#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
 #include "components/safe_browsing/core/common/features.h"
@@ -299,9 +295,9 @@
 
 // static
 bool SafeBrowsingNavigationObserverManager::IsEnabledAndReady(
-    Profile* profile) {
-  return IsSafeBrowsingEnabled(*profile->GetPrefs()) &&
-         g_browser_process->safe_browsing_service();
+    PrefService* prefs,
+    SafeBrowsingServiceInterface* safe_browsing_service) {
+  return IsSafeBrowsingEnabled(*prefs) && safe_browsing_service;
 }
 
 // static
@@ -606,10 +602,11 @@
 
 // static
 size_t SafeBrowsingNavigationObserverManager::CountOfRecentNavigationsToAppend(
-    const Profile& profile,
+    content::BrowserContext* browser_context,
+    PrefService* prefs,
     AttributionResult result) {
-  if (!IsExtendedReportingEnabled(*profile.GetPrefs()) ||
-      profile.IsOffTheRecord() || result == SUCCESS_LANDING_REFERRER) {
+  if (!IsExtendedReportingEnabled(*prefs) ||
+      browser_context->IsOffTheRecord() || result == SUCCESS_LANDING_REFERRER) {
     return 0u;
   }
   return kMaxNumberOfNavigationsToAppend;
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
index d1d28f7..c2292ef 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
@@ -12,6 +12,7 @@
 #include "base/supports_user_data.h"
 #include "base/timer/timer.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/safe_browsing/content/browser/safe_browsing_service_interface.h"
 #include "components/safe_browsing/core/browser/referrer_chain_provider.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
 #include "components/sessions/core/session_id.h"
@@ -20,7 +21,6 @@
 #include "url/gurl.h"
 
 class PrefService;
-class Profile;
 
 namespace content {
 class NavigationHandle;
@@ -171,7 +171,9 @@
   // Checks if we should enable observing navigations for safe browsing purpose.
   // Return true if the safe browsing safe browsing service is enabled and
   // initialized.
-  static bool IsEnabledAndReady(Profile* profile);
+  static bool IsEnabledAndReady(
+      PrefService* prefs,
+      SafeBrowsingServiceInterface* safe_browsing_service);
 
   // Sanitize referrer chain by only keeping origin information of all URLs.
   static void SanitizeReferrerChain(ReferrerChain* referrer_chain);
@@ -265,8 +267,10 @@
 
   // Based on user state, attribution result and finch parameter, calculates the
   // number of recent navigations we want to append to the referrer chain.
-  static size_t CountOfRecentNavigationsToAppend(const Profile& profile,
-                                                 AttributionResult result);
+  static size_t CountOfRecentNavigationsToAppend(
+      content::BrowserContext* browser_context,
+      PrefService* prefs,
+      AttributionResult result);
 
   // Appends |recent_navigation_count| number of recent navigation events to
   // referrer chain in reverse chronological order.
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index c8960cf..95e4e3f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
 #include "chrome/browser/safe_browsing/chrome_password_protection_service_factory.h"
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
 #include "chrome/browser/safe_browsing/safe_browsing_metrics_collector_factory.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h"
@@ -42,6 +41,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/buildflags.h"
 #include "components/safe_browsing/content/browser/client_side_phishing_model.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include "components/safe_browsing/content/browser/safe_browsing_network_context.h"
 #include "components/safe_browsing/content/browser/triggers/trigger_manager.h"
 #include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
diff --git a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
index 8685228..9e0ff84 100644
--- a/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
+++ b/chrome/browser/safe_browsing/telemetry/android/android_telemetry_service.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/download/simple_download_manager_coordinator_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -171,7 +172,8 @@
 void AndroidTelemetryService::FillReferrerChain(
     content::WebContents* web_contents,
     ClientSafeBrowsingReportRequest* report) {
-  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(profile_)) {
+  if (!SafeBrowsingNavigationObserverManager::IsEnabledAndReady(
+          profile_->GetPrefs(), g_browser_process->safe_browsing_service())) {
     RecordApkDownloadTelemetryIncompleteReason(
         ApkDownloadTelemetryIncompleteReason::SB_NAVIGATION_MANAGER_NOT_READY);
     return;
@@ -204,7 +206,8 @@
   // Determines how many recent navigation events to append to referrer chain.
   size_t recent_navigations_to_collect =
       profile_ ? SafeBrowsingNavigationObserverManager::
-                     CountOfRecentNavigationsToAppend(*profile_, result)
+                     CountOfRecentNavigationsToAppend(
+                         profile_, profile_->GetPrefs(), result)
                : 0u;
   if (observer_manager) {
     observer_manager->AppendRecentNavigations(recent_navigations_to_collect,
diff --git a/chrome/browser/search/ntp_custom_background_enabled_policy_handler.cc b/chrome/browser/search/ntp_custom_background_enabled_policy_handler.cc
index f9c2d25..3e8d184 100644
--- a/chrome/browser/search/ntp_custom_background_enabled_policy_handler.cc
+++ b/chrome/browser/search/ntp_custom_background_enabled_policy_handler.cc
@@ -22,9 +22,7 @@
     const policy::PolicyMap& policies,
     PrefValueMap* prefs) {
   const base::Value* value = policies.GetValue(policy_name());
-  bool ntp_custom_background_enabled = true;
-  if (value && value->GetAsBoolean(&ntp_custom_background_enabled) &&
-      !ntp_custom_background_enabled) {
+  if (value && value->is_bool() && !value->GetBool()) {
     prefs->SetValue(prefs::kNtpCustomBackgroundDict,
                     base::Value(base::Value::Type::DICTIONARY));
   }
diff --git a/chrome/browser/sessions/restore_on_startup_policy_handler.cc b/chrome/browser/sessions/restore_on_startup_policy_handler.cc
index f4eaa65..e00b6014 100644
--- a/chrome/browser/sessions/restore_on_startup_policy_handler.cc
+++ b/chrome/browser/sessions/restore_on_startup_policy_handler.cc
@@ -58,7 +58,7 @@
             policies.GetValue(key::kCookiesSessionOnlyForUrls);
         const base::ListValue* cookies_value;
         if (cookies_policy && cookies_policy->GetAsList(&cookies_value) &&
-            !cookies_value->empty()) {
+            !cookies_value->GetList().empty()) {
           errors->AddError(key::kCookiesSessionOnlyForUrls,
                            IDS_POLICY_OVERRIDDEN,
                            key::kRestoreOnStartup);
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationManager.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationManager.java
index 2bb5da4..3f459df 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationManager.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/NotificationManager.java
@@ -191,8 +191,9 @@
                                            .setAction(NOTIFICATION_ACTION_TIMEOUT)
                                            .putExtra(NOTIFICATION_GUID_EXTRA, guid);
             alarmManager.set(AlarmManager.RTC, timeoutAtMillis,
-                    PendingIntent.getBroadcast(
-                            context, nextId, timeoutIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+                    PendingIntent.getBroadcast(context, nextId, timeoutIntent,
+                            PendingIntent.FLAG_UPDATE_CURRENT
+                                    | IntentUtils.getPendingIntentMutabilityFlag(false)));
         }
         MetricsRecorder.recordNotificationShown();
         return true;
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc
index 4562983..98d4d68 100644
--- a/chrome/browser/sharesheet/sharesheet_service.cc
+++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -56,25 +56,27 @@
 void SharesheetService::ShowBubble(content::WebContents* web_contents,
                                    apps::mojom::IntentPtr intent,
                                    SharesheetMetrics::LaunchSource source,
-                                   DeliveredCallback delivered_callback) {
+                                   DeliveredCallback delivered_callback,
+                                   CloseCallback close_callback) {
   ShowBubble(web_contents, std::move(intent),
              /*contains_hosted_document=*/false, source,
-             std::move(delivered_callback));
+             std::move(delivered_callback), std::move(close_callback));
 }
 
 void SharesheetService::ShowBubble(content::WebContents* web_contents,
                                    apps::mojom::IntentPtr intent,
                                    bool contains_hosted_document,
                                    SharesheetMetrics::LaunchSource source,
-                                   DeliveredCallback delivered_callback) {
+                                   DeliveredCallback delivered_callback,
+                                   CloseCallback close_callback) {
   DCHECK(intent->action == apps_util::kIntentActionSend ||
          intent->action == apps_util::kIntentActionSendMultiple);
   SharesheetMetrics::RecordSharesheetLaunchSource(source);
   auto* sharesheet_service_delegate =
       GetOrCreateDelegate(web_contents->GetTopLevelNativeWindow());
-  ShowBubbleWithDelegate(sharesheet_service_delegate, std::move(intent),
-                         contains_hosted_document,
-                         std::move(delivered_callback));
+  ShowBubbleWithDelegate(
+      sharesheet_service_delegate, std::move(intent), contains_hosted_document,
+      std::move(delivered_callback), std::move(close_callback));
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -281,6 +283,7 @@
 void SharesheetService::OnAppIconsLoaded(SharesheetServiceDelegate* delegate,
                                          apps::mojom::IntentPtr intent,
                                          DeliveredCallback delivered_callback,
+                                         CloseCallback close_callback,
                                          std::vector<TargetInfo> targets) {
   RecordTargetCountMetrics(targets);
   RecordShareDataMetrics(intent);
@@ -301,19 +304,24 @@
     }
 
     std::move(delivered_callback).Run(result);
+    // Can be null in tests.
+    if (close_callback)
+      std::move(close_callback).Run();
     delegate->OnBubbleClosed(/*active_action=*/std::u16string());
     return;
   }
 
   delegate->ShowBubble(std::move(targets), std::move(intent),
-                       std::move(delivered_callback));
+                       std::move(delivered_callback),
+                       std::move(close_callback));
 }
 
 void SharesheetService::ShowBubbleWithDelegate(
     SharesheetServiceDelegate* delegate,
     apps::mojom::IntentPtr intent,
     bool contains_hosted_document,
-    DeliveredCallback delivered_callback) {
+    DeliveredCallback delivered_callback,
+    CloseCallback close_callback) {
   std::vector<TargetInfo> targets;
   auto& actions = sharesheet_action_cache_->GetShareActions();
   auto iter = actions.begin();
@@ -334,7 +342,7 @@
       std::move(intent_launch_info), std::move(targets), 0,
       base::BindOnce(&SharesheetService::OnAppIconsLoaded,
                      weak_factory_.GetWeakPtr(), delegate, std::move(intent),
-                     std::move(delivered_callback)));
+                     std::move(delivered_callback), std::move(close_callback)));
 }
 
 void SharesheetService::RecordUserActionMetrics(
diff --git a/chrome/browser/sharesheet/sharesheet_service.h b/chrome/browser/sharesheet/sharesheet_service.h
index 5839aac..68222d3a 100644
--- a/chrome/browser/sharesheet/sharesheet_service.h
+++ b/chrome/browser/sharesheet/sharesheet_service.h
@@ -59,16 +59,20 @@
   //
   // |delivered_callback| is run to signify that the intent has been
   // delivered to the target selected by the user (which may then show its own
-  // separate UI, e.g. for Nearby Sharing)
+  // separate UI, e.g. for Nearby Sharing).
+  // |close_callback| is run to signify that the share flow has finished and the
+  // dialog has closed (this includes separate UI, e.g. Nearby Sharing).
   void ShowBubble(content::WebContents* web_contents,
                   apps::mojom::IntentPtr intent,
                   SharesheetMetrics::LaunchSource source,
-                  DeliveredCallback delivered_callback);
+                  DeliveredCallback delivered_callback,
+                  CloseCallback close_callback = base::NullCallback());
   void ShowBubble(content::WebContents* web_contents,
                   apps::mojom::IntentPtr intent,
                   bool contains_hosted_document,
                   SharesheetMetrics::LaunchSource source,
-                  DeliveredCallback delivered_callback);
+                  DeliveredCallback delivered_callback,
+                  CloseCallback close_callback = base::NullCallback());
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Skips the generic Sharesheet bubble and directly displays the
   // NearbyShare bubble dialog.
@@ -121,12 +125,14 @@
   void OnAppIconsLoaded(SharesheetServiceDelegate* delegate,
                         apps::mojom::IntentPtr intent,
                         DeliveredCallback delivered_callback,
+                        CloseCallback close_callback,
                         std::vector<TargetInfo> targets);
 
   void ShowBubbleWithDelegate(SharesheetServiceDelegate* delegate,
                               apps::mojom::IntentPtr intent,
                               bool contains_hosted_document,
-                              DeliveredCallback delivered_callback);
+                              DeliveredCallback delivered_callback,
+                              CloseCallback close_callback);
 
   void RecordUserActionMetrics(const std::u16string& target_name);
   void RecordTargetCountMetrics(const std::vector<TargetInfo>& targets);
diff --git a/chrome/browser/sharesheet/sharesheet_service_delegate.cc b/chrome/browser/sharesheet/sharesheet_service_delegate.cc
index 3188417..85e8b6e1 100644
--- a/chrome/browser/sharesheet/sharesheet_service_delegate.cc
+++ b/chrome/browser/sharesheet/sharesheet_service_delegate.cc
@@ -21,7 +21,8 @@
 void SharesheetServiceDelegate::ShowBubble(
     std::vector<TargetInfo> targets,
     apps::mojom::IntentPtr intent,
-    sharesheet::DeliveredCallback delivered_callback) {
+    sharesheet::DeliveredCallback delivered_callback,
+    sharesheet::CloseCallback close_callback) {
   NOTIMPLEMENTED();
 }
 
diff --git a/chrome/browser/sharesheet/sharesheet_service_delegate.h b/chrome/browser/sharesheet/sharesheet_service_delegate.h
index 82ef146..5992c63 100644
--- a/chrome/browser/sharesheet/sharesheet_service_delegate.h
+++ b/chrome/browser/sharesheet/sharesheet_service_delegate.h
@@ -44,7 +44,9 @@
   // The following are called by the ShareService to communicate with the UI.
   virtual void ShowBubble(std::vector<TargetInfo> targets,
                           apps::mojom::IntentPtr intent,
-                          sharesheet::DeliveredCallback delivered_callback);
+                          sharesheet::DeliveredCallback delivered_callback,
+                          sharesheet::CloseCallback close_callback);
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   virtual void ShowNearbyShareBubble(
       apps::mojom::IntentPtr intent,
diff --git a/chrome/browser/signin/OWNERS b/chrome/browser/signin/OWNERS
index 407a748..546ef53a 100644
--- a/chrome/browser/signin/OWNERS
+++ b/chrome/browser/signin/OWNERS
@@ -1,11 +1,9 @@
 file://components/signin/OWNERS
 
 per-file chrome_proximity_auth_*=tbarzic@chromium.org
-per-file chrome_proximity_auth_*=tengs@chromium.org
 per-file chrome_proximity_auth_*=xiyuan@chromium.org
 
 per-file easy_unlock_*=tbarzic@chromium.org
-per-file easy_unlock_*=tengs@chromium.org
 per-file easy_unlock_*=xiyuan@chromium.org
 
 per-file signin_profile_attributes_updater*=msalama@chromium.org
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc
index ce2b1f3..6192b0a 100644
--- a/chrome/browser/signin/chrome_signin_helper.cc
+++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -66,10 +66,6 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/supervised_user/supervised_user_service.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/ui/settings_window_manager_chromeos.h"
-#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
-#include "chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h"
-#include "components/signin/public/base/signin_switches.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
@@ -331,13 +327,6 @@
   }
 
   // 4. Displaying the Account Manager for managing accounts.
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (!base::FeatureList::IsEnabled(switches::kUseAccountManagerFacade)) {
-    chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
-        profile, chromeos::settings::mojom::kMyAccountsSubpagePath);
-    return;
-  }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   ::GetAccountManagerFacade(profile->GetPath().value())
       ->ShowManageAccountsSettings();
   return;
diff --git a/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc b/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
index ac20aec..43b72d2 100644
--- a/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
+++ b/chrome/browser/signin/dice_signed_in_profile_creator_unittest.cc
@@ -190,7 +190,6 @@
   ProfileAttributesEntry* entry =
       storage.GetProfileAttributesWithPath(signed_in_profile()->GetPath());
   ASSERT_TRUE(entry);
-  ASSERT_EQ(entry->IsGuest(), use_guest_profile());
   if (!use_guest_profile()) {
     EXPECT_EQ(kProfileTestName, entry->GetLocalProfileName());
     EXPECT_EQ(kTestIcon, entry->GetAvatarIconIndex());
diff --git a/chrome/browser/signin/e2e_tests/live_sign_in_test.cc b/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
index 94dc79d..326ccdb 100644
--- a/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
+++ b/chrome/browser/signin/e2e_tests/live_sign_in_test.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/run_loop.h"
+#include "base/scoped_observation.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -21,10 +22,12 @@
 #include "chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/signin/core/browser/account_reconcilor.h"
+#include "components/signin/public/identity_manager/account_capabilities.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
 #include "components/signin/public/identity_manager/consent_level.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
 #include "components/sync/driver/sync_service.h"
 #include "content/public/test/browser_test.h"
 #include "google_apis/gaia/core_account_id.h"
@@ -56,13 +59,10 @@
   explicit SignInTestObserver(IdentityManager* identity_manager,
                               AccountReconcilor* reconcilor)
       : identity_manager_(identity_manager), reconcilor_(reconcilor) {
-    identity_manager_->AddObserver(this);
-    reconcilor_->AddObserver(this);
+    identity_manager_observation_.Observe(identity_manager_);
+    account_reconcilor_observation_.Observe(reconcilor_);
   }
-  ~SignInTestObserver() override {
-    identity_manager_->RemoveObserver(this);
-    reconcilor_->RemoveObserver(this);
-  }
+  ~SignInTestObserver() override = default;
 
   // IdentityManager::Observer:
   void OnPrimaryAccountChanged(
@@ -172,6 +172,10 @@
 
   signin::IdentityManager* const identity_manager_;
   AccountReconcilor* const reconcilor_;
+  base::ScopedObservation<IdentityManager, IdentityManager::Observer>
+      identity_manager_observation_{this};
+  base::ScopedObservation<AccountReconcilor, AccountReconcilor::Observer>
+      account_reconcilor_observation_{this};
   base::RunLoop run_loop_;
 
   bool are_expectations_set = false;
@@ -180,6 +184,44 @@
       PrimarySyncAccountWait::kNotWait;
 };
 
+// Observer class allowing to wait for account capabilities to be known.
+class AccountCapabilitiesObserver : public IdentityManager::Observer {
+ public:
+  explicit AccountCapabilitiesObserver(IdentityManager* identity_manager)
+      : identity_manager_(identity_manager) {
+    identity_manager_observation_.Observe(identity_manager);
+  }
+
+  // IdentityManager::Observer:
+  void OnExtendedAccountInfoUpdated(const AccountInfo& info) override {
+    if (info.account_id != account_id_)
+      return;
+
+    if (info.capabilities.AreAllCapabilitiesKnown())
+      run_loop_.Quit();
+  }
+
+  // This should be called only once per AccountCapabilitiesObserver instance.
+  void WaitForAllCapabilitiesToBeKnown(CoreAccountId account_id) {
+    DCHECK(identity_manager_observation_.IsObservingSource(identity_manager_));
+    AccountInfo info =
+        identity_manager_->FindExtendedAccountInfoByAccountId(account_id);
+    if (info.capabilities.AreAllCapabilitiesKnown())
+      return;
+
+    account_id_ = account_id;
+    run_loop_.Run();
+    identity_manager_observation_.Reset();
+  }
+
+ private:
+  IdentityManager* identity_manager_ = nullptr;
+  CoreAccountId account_id_;
+  base::RunLoop run_loop_;
+  base::ScopedObservation<IdentityManager, IdentityManager::Observer>
+      identity_manager_observation_{this};
+};
+
 // Live tests for SignIn.
 // These tests can be run with:
 // browser_tests --gtest_filter=LiveSignInTest.* --run-live-tests --run-manual
@@ -680,5 +722,27 @@
       identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSync));
 }
 
+IN_PROC_BROWSER_TEST_F(LiveSignInTest,
+                       MANUAL_AccountCapabilities_FetchedOnSignIn) {
+  EnableAccountCapabilitiesFetches(identity_manager());
+  AccountCapabilitiesObserver capabilities_observer(identity_manager());
+
+  TestAccount ta;
+  CHECK(GetTestAccountsUtil()->GetAccount("TEST_ACCOUNT_1", ta));
+  SignInFromSettings(ta, 0);
+
+  CoreAccountInfo core_account_info =
+      identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kSignin);
+  EXPECT_TRUE(gaia::AreEmailsSame(core_account_info.email, ta.user));
+
+  capabilities_observer.WaitForAllCapabilitiesToBeKnown(
+      core_account_info.account_id);
+  AccountInfo account_info =
+      identity_manager()->FindExtendedAccountInfoByAccountId(
+          core_account_info.account_id);
+  EXPECT_EQ(account_info.capabilities.can_offer_extended_chrome_sync_promos(),
+            AccountCapabilities::Tribool::kTrue);
+}
+
 }  // namespace test
 }  // namespace signin
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheWithBadgeRenderTest.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheWithBadgeRenderTest.java
index 50d26e1..022dbe73 100644
--- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheWithBadgeRenderTest.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCacheWithBadgeRenderTest.java
@@ -9,13 +9,13 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.text.TextUtils;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
 import androidx.test.filters.MediumTest;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -27,19 +27,15 @@
 import org.mockito.quality.Strictness;
 
 import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
-import org.chromium.components.signin.ProfileDataSource;
-import org.chromium.components.signin.identitymanager.AccountInfoServiceProvider;
-import org.chromium.components.signin.identitymanager.AccountTrackerService;
-import org.chromium.components.signin.identitymanager.IdentityManager;
-import org.chromium.components.signin.test.util.FakeProfileDataSource;
+import org.chromium.components.signin.test.util.FakeAccountInfoService;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.DummyUiActivityTestCase;
 import org.chromium.ui.widget.ChromeImageView;
@@ -52,9 +48,9 @@
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @Batch(ProfileDataCacheRenderTest.PROFILE_DATA_BATCH_NAME)
-@DisableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API})
+@Features.EnableFeatures({ChromeFeatureList.DEPRECATE_MENAGERIE_API})
 public class ProfileDataCacheWithBadgeRenderTest extends DummyUiActivityTestCase {
-    private static final long NATIVE_IDENTITY_MANAGER = 10002L;
+    private static final String TEST_ACCOUNT_NAME = "test@example.com";
 
     @Rule
     public final ChromeRenderTestRule mRenderTestRule =
@@ -65,32 +61,22 @@
 
     @Rule
     public final AccountManagerTestRule mAccountManagerTestRule =
-            new AccountManagerTestRule(new FakeProfileDataSource());
+            new AccountManagerTestRule(new FakeAccountInfoService());
 
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
 
     @Mock
-    private AccountTrackerService mAccountTrackerServiceMock;
-
-    @Mock
     private ProfileDataCache.Observer mObserver;
 
-    private static final String TEST_ACCOUNT_NAME = "test@example.com";
-
-    private final IdentityManager mIdentityManager =
-            IdentityManager.create(NATIVE_IDENTITY_MANAGER, null /* OAuth2TokenService */);
-
     private FrameLayout mContentView;
     private ImageView mImageView;
     private ProfileDataCache mProfileDataCache;
 
     @Before
     public void setUp() {
-        AccountInfoServiceProvider.init(mIdentityManager, mAccountTrackerServiceMock);
-        final ProfileDataSource.ProfileData profileData = new ProfileDataSource.ProfileData(
-                TEST_ACCOUNT_NAME, createAvatar(), "Full Name", "Given Name");
-        mAccountManagerTestRule.addAccount(profileData);
+        mAccountManagerTestRule.addAccount(
+                TEST_ACCOUNT_NAME, "Full Name", "Given Name", createAvatar());
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             Activity activity = getActivity();
@@ -102,11 +88,6 @@
         });
     }
 
-    @After
-    public void tearDown() {
-        AccountInfoServiceProvider.resetForTests();
-    }
-
     @Test
     @MediumTest
     @Feature("RenderTest")
@@ -129,8 +110,10 @@
                     ? ProfileDataCache.createWithDefaultImageSize(
                             getActivity(), R.drawable.ic_account_child_20dp)
                     : ProfileDataCache.createWithoutBadge(getActivity(), R.dimen.user_picture_size);
-            // ProfileDataCache only populates the cache when an observer is added.
-            mProfileDataCache.addObserver(mObserver);
+        });
+        CriteriaHelper.pollUiThread(() -> {
+            return !TextUtils.isEmpty(
+                    mProfileDataCache.getProfileDataOrDefault(TEST_ACCOUNT_NAME).getFullName());
         });
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mImageView.setImageDrawable(
diff --git a/chrome/browser/signin/ui/android/BUILD.gn b/chrome/browser/signin/ui/android/BUILD.gn
index fc25697..b355803 100644
--- a/chrome/browser/signin/ui/android/BUILD.gn
+++ b/chrome/browser/signin/ui/android/BUILD.gn
@@ -119,6 +119,7 @@
     "junit/src/org/chromium/chrome/browser/signin/ui/ConfirmSyncDataStateMachineDelegateTest.java",
     "junit/src/org/chromium/chrome/browser/signin/ui/ConfirmSyncDataStateMachineTest.java",
     "junit/src/org/chromium/chrome/browser/signin/ui/SignOutDialogFragmentTest.java",
+    "junit/src/org/chromium/chrome/browser/signin/ui/SigninPromoControllerTest.java",
     "junit/src/org/chromium/chrome/browser/signin/ui/SigninPromoUtilLaunchSigninPromoTest.java",
     "junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerDelegateImplTest.java",
     "junit/src/org/chromium/chrome/browser/signin/ui/account_picker/AccountPickerMediatorTest.java",
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java
index d386c9c..0b75f45 100644
--- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java
+++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoController.java
@@ -114,13 +114,15 @@
         final @Nullable Account visibleAccount = getVisibleAccount();
         final AccountManagerFacade accountManagerFacade =
                 AccountManagerFacadeProvider.getInstance();
-        boolean canNotOfferPromoForMinorAccount =
+        if (visibleAccount == null) {
+            return false;
+        }
+        final boolean canNotOfferPromoForMinorAccount =
                 ChromeFeatureList.isEnabled(ChromeFeatureList.MINOR_MODE_SUPPORT)
                 && !accountManagerFacade.canOfferExtendedSyncPromos(visibleAccount).or(true);
-        boolean isPromoDisabledByForce =
-                ChromeFeatureList.isEnabled(ChromeFeatureList.FORCE_DISABLE_EXTENDED_SYNC_PROMOS);
-        return visibleAccount != null
-                && (canNotOfferPromoForMinorAccount || isPromoDisabledByForce);
+        return canNotOfferPromoForMinorAccount
+                || ChromeFeatureList.isEnabled(
+                        ChromeFeatureList.FORCE_DISABLE_EXTENDED_SYNC_PROMOS);
     }
 
     // Find the visible account for sync promos
diff --git a/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/SigninPromoControllerTest.java b/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/SigninPromoControllerTest.java
new file mode 100644
index 0000000..be14392
--- /dev/null
+++ b/chrome/browser/signin/ui/android/junit/src/org/chromium/chrome/browser/signin/ui/SigninPromoControllerTest.java
@@ -0,0 +1,101 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.signin.ui;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+
+import com.google.common.base.Optional;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
+import org.chromium.components.signin.AccountUtils;
+import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
+import org.chromium.components.signin.test.util.FakeAccountManagerFacade;
+
+/**
+ * Tests for {@link SigninPromoController}..
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Features.EnableFeatures({ChromeFeatureList.MINOR_MODE_SUPPORT})
+@Features.DisableFeatures({ChromeFeatureList.FORCE_DISABLE_EXTENDED_SYNC_PROMOS})
+public class SigninPromoControllerTest {
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
+    @Rule
+    public final Features.JUnitProcessor processor = new Features.JUnitProcessor();
+
+    private final FakeAccountManagerFacade mFakeAccountManagerFacade =
+            spy(new FakeAccountManagerFacade(null));
+
+    @Rule
+    public final AccountManagerTestRule mAccountManagerTestRule =
+            new AccountManagerTestRule(mFakeAccountManagerFacade);
+
+    @Mock
+    private IdentityManager mIdentityManagerMock;
+
+    @Before
+    public void setUp() {
+        Profile.setLastUsedProfileForTesting(mock(Profile.class));
+        IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class));
+        when(IdentityServicesProvider.get().getIdentityManager(Profile.getLastUsedRegularProfile()))
+                .thenReturn(mIdentityManagerMock);
+    }
+
+    @Test
+    public void shouldShowSyncPromoForNTPWhenNoAccountOnDevice() {
+        Assert.assertFalse(SigninPromoController.shouldHideSyncPromoForNTP(
+                SigninAccessPoint.NTP_CONTENT_SUGGESTIONS));
+    }
+
+    @Test
+    public void shouldHideSyncPromoForNTPWhenDefaultAccountCannotOfferSyncPromos() {
+        final Account account =
+                AccountUtils.createAccountFromName("test.account.default@gmail.com");
+        mAccountManagerTestRule.addAccount(account);
+        mAccountManagerTestRule.addAccount("test.account.secondary@gmail.com");
+        doReturn(Optional.of(false))
+                .when(mFakeAccountManagerFacade)
+                .canOfferExtendedSyncPromos(account);
+
+        Assert.assertTrue(SigninPromoController.shouldHideSyncPromoForNTP(
+                SigninAccessPoint.NTP_CONTENT_SUGGESTIONS));
+    }
+
+    @Test
+    public void shouldShowSyncPromoForNTPWhenSecondaryAccountCannotOfferSyncPromos() {
+        final Account account =
+                AccountUtils.createAccountFromName("test.account.secondary@gmail.com");
+        mAccountManagerTestRule.addAccount("test.account.default@gmail.com");
+        mAccountManagerTestRule.addAccount(account);
+        doReturn(Optional.of(false))
+                .when(mFakeAccountManagerFacade)
+                .canOfferExtendedSyncPromos(account);
+
+        Assert.assertFalse(SigninPromoController.shouldHideSyncPromoForNTP(
+                SigninAccessPoint.NTP_CONTENT_SUGGESTIONS));
+    }
+}
diff --git a/chrome/browser/speech/OWNERS b/chrome/browser/speech/OWNERS
index 9d2997a0..3184304 100644
--- a/chrome/browser/speech/OWNERS
+++ b/chrome/browser/speech/OWNERS
@@ -1,10 +1,7 @@
 # Speech recognition
-tommi@chromium.org
+evliu@google.com
 
 # Text-to-speech
 per-file *tts_*=dmazzoni@chromium.org
 per-file *tts_*=dtseng@chromium.org
 per-file *tts_*=katie@chromium.org
-
-# Speech recognition service
-per-file *speech_recognition_*=evliu@google.com
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index d8a8e410..df449a2f0 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -170,9 +170,8 @@
         prefs_->GetList(spellcheck::prefs::kSpellCheckDictionaries);
     std::vector<base::StringPiece> dictionaries;
     for (const auto& item_value : list_value->GetList()) {
-      base::StringPiece dictionary;
-      EXPECT_TRUE(item_value.GetAsString(&dictionary));
-      dictionaries.push_back(dictionary);
+      EXPECT_TRUE(item_value.is_string());
+      dictionaries.push_back(item_value.GetString());
     }
     return base::JoinString(dictionaries, ",");
   }
diff --git a/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc b/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
index f7693c2..b8931da9 100644
--- a/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
+++ b/chrome/browser/sync/sync_encryption_keys_tab_helper_unittest.cc
@@ -6,6 +6,8 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/common/sync_encryption_keys_extension.mojom.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
@@ -48,7 +50,9 @@
 
   TestingProfile::TestingFactories GetTestingFactories() const override {
     return {{SyncServiceFactory::GetInstance(),
-             SyncServiceFactory::GetDefaultFactory()}};
+             SyncServiceFactory::GetDefaultFactory()},
+            {ChromeSigninClientFactory::GetInstance(),
+             base::BindRepeating(&signin::BuildTestSigninClient)}};
   }
 
  private:
diff --git a/chrome/browser/sync/test/integration/password_manager_sync_test.cc b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
index c9f5c86..7150379 100644
--- a/chrome/browser/sync/test/integration/password_manager_sync_test.cc
+++ b/chrome/browser/sync/test/integration/password_manager_sync_test.cc
@@ -30,9 +30,11 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_features_util.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_store_factory_util.h"
+#include "components/password_manager/core/browser/password_store_interface.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/identity_manager/account_info.h"
@@ -253,6 +255,12 @@
     form.username_value = base::UTF8ToUTF16(username);
     form.password_value = base::UTF8ToUTF16(password);
     form.date_created = base::Time::Now();
+    // TODO(crbug.com/1223022): Once all places that operate changes on forms
+    // via UpdateLogin properly set |password_issues|, setting them to an empty
+    // map should be part of the default constructor.
+    form.password_issues =
+        base::flat_map<password_manager::InsecureType,
+                       password_manager::InsecurityMetadata>();
     return form;
   }
 
@@ -285,8 +293,8 @@
 
   // Adds a credential to the local store.
   void AddLocalCredential(const password_manager::PasswordForm& form) {
-    scoped_refptr<password_manager::PasswordStore> password_store =
-        passwords_helper::GetPasswordStore(0);
+    scoped_refptr<password_manager::PasswordStoreInterface> password_store =
+        passwords_helper::GetProfilePasswordStoreInterface(0);
     password_store->AddLogin(form);
     // Do a roundtrip to the DB thread, to make sure the new password is stored
     // before doing anything else that might depend on it.
@@ -297,8 +305,8 @@
   // returns them.
   std::vector<std::unique_ptr<password_manager::PasswordForm>>
   GetAllLoginsFromProfilePasswordStore() {
-    scoped_refptr<password_manager::PasswordStore> password_store =
-        passwords_helper::GetPasswordStore(0);
+    scoped_refptr<password_manager::PasswordStoreInterface> password_store =
+        passwords_helper::GetProfilePasswordStoreInterface(0);
     PasswordStoreResultsObserver syncer;
     password_store->GetAllLoginsWithAffiliationAndBrandingInformation(&syncer);
     return syncer.WaitForResults();
@@ -308,8 +316,8 @@
   // returns them.
   std::vector<std::unique_ptr<password_manager::PasswordForm>>
   GetAllLoginsFromAccountPasswordStore() {
-    scoped_refptr<password_manager::PasswordStore> password_store =
-        passwords_helper::GetAccountPasswordStore(0);
+    scoped_refptr<password_manager::PasswordStoreInterface> password_store =
+        passwords_helper::GetAccountPasswordStoreInterface(0);
     PasswordStoreResultsObserver syncer;
     password_store->GetAllLoginsWithAffiliationAndBrandingInformation(&syncer);
     return syncer.WaitForResults();
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc
index 9ba20b1..874e817c 100644
--- a/chrome/browser/sync/test/integration/passwords_helper.cc
+++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/password_manager/password_store_factory.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
 #include "components/password_manager/core/browser/insecure_credentials_consumer.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -167,16 +168,6 @@
 
 namespace passwords_helper {
 
-void AddLogin(PasswordStore* store, const PasswordForm& form) {
-  ASSERT_TRUE(store);
-  base::WaitableEvent wait_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  store->AddLogin(form);
-  store->ScheduleTask(base::BindOnce(&PasswordStoreCallback, &wait_event));
-  wait_event.Wait();
-}
-
 void AddInsecureCredential(PasswordStore* store,
                            const InsecureCredential& issue) {
   ASSERT_TRUE(store);
@@ -188,28 +179,6 @@
   wait_event.Wait();
 }
 
-void UpdateLogin(PasswordStore* store, const PasswordForm& form) {
-  ASSERT_TRUE(store);
-  base::WaitableEvent wait_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  store->UpdateLogin(form);
-  store->ScheduleTask(base::BindOnce(&PasswordStoreCallback, &wait_event));
-  wait_event.Wait();
-}
-
-void UpdateLoginWithPrimaryKey(PasswordStore* store,
-                               const PasswordForm& new_form,
-                               const PasswordForm& old_form) {
-  ASSERT_TRUE(store);
-  base::WaitableEvent wait_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  store->UpdateLoginWithPrimaryKey(new_form, old_form);
-  store->ScheduleTask(base::BindOnce(&PasswordStoreCallback, &wait_event));
-  wait_event.Wait();
-}
-
 std::vector<std::unique_ptr<PasswordForm>> GetLogins(
     PasswordStoreInterface* store) {
   EXPECT_TRUE(store);
@@ -387,6 +356,11 @@
       base::ASCIIToUTF16(base::StringPrintf("password%d", index));
   form.date_created = base::Time::Now();
   form.in_store = password_manager::PasswordForm::Store::kProfileStore;
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<password_manager::InsecureType,
+                                        password_manager::InsecurityMetadata>();
   return form;
 }
 
diff --git a/chrome/browser/sync/test/integration/passwords_helper.h b/chrome/browser/sync/test/integration/passwords_helper.h
index 0a17fd40..cbd4d6c 100644
--- a/chrome/browser/sync/test/integration/passwords_helper.h
+++ b/chrome/browser/sync/test/integration/passwords_helper.h
@@ -27,27 +27,10 @@
 
 namespace passwords_helper {
 
-// Adds the login held in |form| to the password store |store|. Even though
-// logins are normally added asynchronously, this method will block until the
-// login is added.
-void AddLogin(password_manager::PasswordStore* store,
-              const password_manager::PasswordForm& form);
-
 // Adds |issue| to the password store |store|.
 void AddInsecureCredential(password_manager::PasswordStore* store,
                            const password_manager::InsecureCredential& issue);
 
-// Update the data held in password store |store| with a modified |form|.
-// This method blocks until the operation is complete.
-void UpdateLogin(password_manager::PasswordStore* store,
-                 const password_manager::PasswordForm& form);
-
-// Removes |old_form| from password store |store| and immediately adds
-// |new_form|. This method blocks until the operation is complete.
-void UpdateLoginWithPrimaryKey(password_manager::PasswordStore* store,
-                               const password_manager::PasswordForm& new_form,
-                               const password_manager::PasswordForm& old_form);
-
 // Returns all logins from |store| matching a fake signon realm (see
 // CreateTestPasswordForm()).
 // TODO(treib): Rename this to make clear how specific it is.
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
index 4bb0bb7..188f6605 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -286,4 +286,9 @@
      * The default value when a Tab is initialized is false.
      */
     void setIsTabSaveEnabled(boolean isSaveEnabled);
+
+    /**
+     * @return true if the {@link Tab} is a custom tab.
+     */
+    boolean isCustomTab();
 }
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLogger.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLogger.java
index 588ab6e..5d7ad9cea 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLogger.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/PriceDropMetricsLogger.java
@@ -4,8 +4,11 @@
 
 package org.chromium.chrome.browser.tab.state;
 
+import android.text.TextUtils;
+
+import androidx.annotation.VisibleForTesting;
+
 import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.tab.proto.PriceTracking.PriceTrackingData;
 
 import java.util.Locale;
 
@@ -16,12 +19,12 @@
     private MetricsResult mMetrics;
 
     /**
-     * Log metrics related to our price drops feature
-     * @param priceTrackingDataProto price tracking data proto acquired from OptimizationGuide to
-     *         power the price drops experimence
+     * Log metrics related to our price drops feature.
+     * @param shoppingPersistedTabData {@link ShoppingPersistedTabData} associated with price drop
+     *         data.
      */
-    PriceDropMetricsLogger(PriceTrackingData priceTrackingDataProto) {
-        mMetrics = deriveMetrics(priceTrackingDataProto);
+    PriceDropMetricsLogger(ShoppingPersistedTabData shoppingPersistedTabData) {
+        mMetrics = deriveMetrics(shoppingPersistedTabData);
     }
 
     /**
@@ -44,17 +47,20 @@
                 mMetrics.containsPriceDrop);
     }
 
-    private static MetricsResult deriveMetrics(PriceTrackingData priceTrackingDataProto) {
-        return new MetricsResult(priceTrackingDataProto.hasBuyableProduct()
-                        && priceTrackingDataProto.getBuyableProduct().hasOfferId(),
-                priceTrackingDataProto.hasBuyableProduct()
-                        && priceTrackingDataProto.getBuyableProduct().hasCurrentPrice(),
-                priceTrackingDataProto.hasProductUpdate()
-                        && priceTrackingDataProto.getProductUpdate().hasOldPrice()
-                        && priceTrackingDataProto.getProductUpdate().hasNewPrice());
+    @VisibleForTesting
+    protected MetricsResult getMetricsResultForTesting() {
+        return mMetrics;
     }
 
-    private static class MetricsResult {
+    private static MetricsResult deriveMetrics(ShoppingPersistedTabData shoppingPersistedTabData) {
+        return new MetricsResult(!TextUtils.isEmpty(shoppingPersistedTabData.getMainOfferId()),
+                shoppingPersistedTabData.hasPriceMicros(),
+                shoppingPersistedTabData.hasPriceMicros()
+                        && shoppingPersistedTabData.hasPreviousPriceMicros());
+    }
+
+    @VisibleForTesting
+    protected static class MetricsResult {
         public final boolean isProductDetailPage;
         public final boolean containsPrice;
         public final boolean containsPriceDrop;
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
index f96d27e3..f527ffd 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabData.java
@@ -16,6 +16,7 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.base.supplier.Supplier;
+import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeFactory;
 import org.chromium.chrome.browser.page_annotations.BuyableProductPageAnnotation;
@@ -33,6 +34,7 @@
 import org.chromium.components.optimization_guide.proto.HintsProto;
 import org.chromium.components.payments.CurrencyFormatter;
 import org.chromium.content_public.browser.NavigationHandle;
+import org.chromium.content_public.browser.UiThreadTaskTraits;
 import org.chromium.url.GURL;
 
 import java.lang.annotation.Retention;
@@ -230,8 +232,7 @@
                                         PriceTrackingData.parseFrom(metadata.getValue());
                                 parsePriceTrackingDataProto(tab, priceTrackingDataProto, null);
                                 setLastUpdatedMs(System.currentTimeMillis());
-                                mPriceDropMetricsLogger =
-                                        new PriceDropMetricsLogger(priceTrackingDataProto);
+                                mPriceDropMetricsLogger = new PriceDropMetricsLogger(this);
                                 mPriceDropMetricsLogger.logPriceDropMetrics(
                                         METRICS_IDENTIFIER_PREFIX);
                             } catch (InvalidProtocolBufferException e) {
@@ -262,6 +263,11 @@
     }
 
     @VisibleForTesting
+    protected PriceDropMetricsLogger getPriceDropMetricsLoggerForTesting() {
+        return mPriceDropMetricsLogger;
+    }
+
+    @VisibleForTesting
     protected ShoppingPersistedTabData(
             Tab tab, ByteBuffer data, PersistedTabDataStorage storage, String persistedTabDataId) {
         super(tab, storage, persistedTabDataId);
@@ -307,9 +313,21 @@
     /**
      * Acquire {@link ShoppingPersistedTabData} for a {@link Tab}
      * @param tab {@link Tab} ShoppingPersistedTabData is acquired for
-     * @param callback {@link Callback} {@link ShoppingPersistedTabData is passed back in}
+     * @param callback {@link Callback} receiving the Tab's {@link ShoppingPersistedTabData}
+     * The result in the callback wil be null for a:
+     * - Custom Tab
+     * - Incognito Tab
+     * - Tab greater than 90 days old
+     * - Tab with a non-shopping related page currently navigated to
+     * - Tab with a shopping related page for which no shopping related data was found
      */
     public static void from(Tab tab, Callback<ShoppingPersistedTabData> callback) {
+        // Shopping related data is not available for incognito or Custom Tabs. For example,
+        // for incognito Tabs it is not possible to call a backend service with the user's URL.
+        if (tab.isIncognito() || tab.isCustomTab()) {
+            PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> { callback.onResult(null); });
+            return;
+        }
         PersistedTabData.from(tab,
                 (data, storage, id)
                         -> { return new ShoppingPersistedTabData(tab, data, storage, id); },
@@ -390,6 +408,19 @@
     }
 
     /**
+     * @param tab {@link Tab} of interest.
+     * @return true if the {@link Tab} has a price drop associated with it.
+     */
+    public static boolean hasPriceDrop(Tab tab) {
+        ShoppingPersistedTabData shoppingPersistedTabData =
+                PersistedTabData.from(tab, USER_DATA_KEY);
+        if (shoppingPersistedTabData == null) {
+            return false;
+        }
+        return shoppingPersistedTabData.getPriceDrop() != null;
+    }
+
+    /**
      * Whether a BuyableProductAnnotation was found or not
      */
     @IntDef({FoundBuyableProduct.NOT_FOUND, FoundBuyableProduct.FOUND,
@@ -591,11 +622,25 @@
         return mPriceDropData.priceMicros;
     }
 
+    /**
+     * @return true if there is a price
+     */
+    protected boolean hasPriceMicros() {
+        return mPriceDropData.priceMicros != NO_PRICE_KNOWN;
+    }
+
     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
     public long getPreviousPriceMicros() {
         return mPriceDropData.previousPriceMicros;
     }
 
+    /**
+     * @return true if there is a previous price
+     */
+    protected boolean hasPreviousPriceMicros() {
+        return mPriceDropData.previousPriceMicros != NO_PRICE_KNOWN;
+    }
+
     @VisibleForTesting
     public void setPriceMicrosForTesting(long priceMicros) {
         mPriceDropData.priceMicros = priceMicros;
@@ -741,6 +786,7 @@
             setLastUpdatedMs(shoppingPersistedTabDataProto.getLastUpdatedMs());
             mLastPriceChangeTimeMs = shoppingPersistedTabDataProto.getLastPriceChangeTimeMs();
             mPriceDropData.offerId = shoppingPersistedTabDataProto.getMainOfferId();
+            mPriceDropMetricsLogger = new PriceDropMetricsLogger(this);
             return true;
         } catch (InvalidProtocolBufferException e) {
             Log.e(TAG,
diff --git a/chrome/browser/task_manager/sampling/shared_sampler_win.cc b/chrome/browser/task_manager/sampling/shared_sampler_win.cc
index 079612f..ec882e2 100644
--- a/chrome/browser/task_manager/sampling/shared_sampler_win.cc
+++ b/chrome/browser/task_manager/sampling/shared_sampler_win.cc
@@ -13,6 +13,7 @@
 #include "base/bit_cast.h"
 #include "base/command_line.h"
 #include "base/path_service.h"
+#include "base/threading/platform_thread.h"
 #include "base/time/time.h"
 #include "chrome/browser/task_manager/sampling/shared_sampler_win_defines.h"
 #include "chrome/browser/task_manager/task_manager_observer.h"
diff --git a/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc b/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc
index 193fcb1..b200ef6 100644
--- a/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc
+++ b/chrome/browser/tracing/background_tracing_metrics_provider_unittest.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/tracing/background_tracing_metrics_provider.h"
 
 #include "base/bind.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "components/tracing/common/trace_startup_config.h"
 #include "content/public/browser/background_tracing_config.h"
 #include "content/public/browser/background_tracing_manager.h"
@@ -20,7 +22,8 @@
 
 class BackgroundTracingMetricsProviderTest : public testing::Test {
  public:
-  BackgroundTracingMetricsProviderTest() = default;
+  BackgroundTracingMetricsProviderTest()
+      : local_state_(TestingBrowserProcess::GetGlobal()) {}
 
   void SetUp() override {
     base::DictionaryValue dict;
@@ -51,6 +54,7 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
+  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(BackgroundTracingMetricsProviderTest, NoTraceData) {
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.cc b/chrome/browser/tracing/chrome_tracing_delegate.cc
index 08845c5..243c1d3 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate.cc
+++ b/chrome/browser/tracing/chrome_tracing_delegate.cc
@@ -11,8 +11,12 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
 #include "base/time/time.h"
+#include "base/util/values/values_util.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -31,9 +35,9 @@
 #include "content/public/browser/background_tracing_config.h"
 #include "content/public/browser/browser_thread.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/tracing/public/cpp/tracing_features.h"
 
 #if defined(OS_ANDROID)
-#include "chrome/browser/crash_upload_list/crash_upload_list_android.h"
 #include "chrome/browser/ui/android/tab_model/tab_model.h"
 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
 #else
@@ -48,6 +52,11 @@
 
 namespace {
 
+constexpr char kTracingStateKey[] = "state";
+constexpr char kUploadTimesKey[] = "upload_times";
+constexpr char kScenarioKey[] = "scenario";
+constexpr char kUploadTimestampKey[] = "time";
+
 const int kMinDaysUntilNextUpload = 7;
 
 // These values are logged to UMA. Entries should not be renumbered and numeric
@@ -61,7 +70,8 @@
   kLastSessionCrashed = 3,
   kMetricsReportingDisabled = 4,
   kTraceUploadedRecently = 5,
-  kMaxValue = kTraceUploadedRecently
+  kLastTracingSessionDidNotEnd = 6,
+  kMaxValue = kLastTracingSessionDidNotEnd
 };
 
 void RecordDisallowedMetric(TracingFinalizationDisallowedReason reason) {
@@ -69,13 +79,205 @@
                             reason);
 }
 
-}  // namespace
-
-void ChromeTracingDelegate::RegisterPrefs(PrefRegistrySimple* registry) {
-  registry->RegisterInt64Pref(prefs::kBackgroundTracingLastUpload, 0);
+bool IsBackgroundTracingCommandLine() {
+  if (tracing::GetBackgroundTracingSetupMode() ==
+      tracing::BackgroundTracingSetupMode::kFromConfigFile) {
+    return true;
+  }
+  return false;
 }
 
-ChromeTracingDelegate::ChromeTracingDelegate() : incognito_launched_(false) {
+bool IsMetricsReportingEnabled() {
+  // No need to check for metrics reporting for proto uploads, the metrics
+  // service will check before uploading.
+  if (base::FeatureList::IsEnabled(features::kBackgroundTracingProtoOutput))
+    return true;
+
+#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(OFFICIAL_BUILD)
+  PrefService* local_state = g_browser_process->local_state();
+  if (!local_state->GetBoolean(metrics::prefs::kMetricsReportingEnabled)) {
+    return false;
+  }
+#elif BUILDFLAG(IS_CHROMEOS_ASH)
+  // TODO(chinglinyu): Fix if JSON traces are needed for ChromeOS-ASH.
+  return false;
+#endif
+  return true;
+}
+
+// Removes any version numbers from the scenario name.
+std::string StripScenarioName(const std::string& scenario_name) {
+  std::string stripped_scenario_name;
+  base::RemoveChars(scenario_name, "1234567890", &stripped_scenario_name);
+  return stripped_scenario_name;
+}
+
+}  // namespace
+
+ChromeTracingDelegate::BackgroundTracingStateManager::
+    BackgroundTracingStateManager() = default;
+ChromeTracingDelegate::BackgroundTracingStateManager::
+    ~BackgroundTracingStateManager() = default;
+
+ChromeTracingDelegate::BackgroundTracingStateManager&
+ChromeTracingDelegate::BackgroundTracingStateManager::GetInstance() {
+  static base::NoDestructor<BackgroundTracingStateManager> instance;
+  return *instance;
+}
+
+void ChromeTracingDelegate::BackgroundTracingStateManager::Initialize() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (initialized_)
+    return;
+  initialized_ = true;
+
+  PrefService* local_state = g_browser_process->local_state();
+  DCHECK(local_state);
+  const base::DictionaryValue* dict =
+      local_state->GetDictionary(prefs::kBackgroundTracingSessionState);
+  if (!dict) {
+    SaveState();
+    return;
+  }
+  absl::optional<int> state = dict->FindIntKey(kTracingStateKey);
+  if (state) {
+    if (*state >= 0 &&
+        *state <= static_cast<int>(BackgroundTracingState::LAST)) {
+      last_session_end_state_ = static_cast<BackgroundTracingState>(*state);
+    } else {
+      last_session_end_state_ = BackgroundTracingState::NOT_ACTIVATED;
+    }
+  }
+
+  const base::Value* upload_times = dict->FindListKey(kUploadTimesKey);
+  if (upload_times) {
+    for (const auto& it : upload_times->GetList()) {
+      const auto& scenario_dict = base::Value::AsDictionaryValue(it);
+      const std::string* scenario = scenario_dict.FindStringKey(kScenarioKey);
+      const base::Value* timestamp_val =
+          scenario_dict.FindKey(kUploadTimestampKey);
+      if (!scenario || !timestamp_val) {
+        continue;
+      }
+      absl::optional<base::Time> upload_time = util::ValueToTime(timestamp_val);
+      if (!upload_time) {
+        continue;
+      }
+      if ((base::Time::Now() - *upload_time) >
+          base::TimeDelta::FromDays(kMinDaysUntilNextUpload)) {
+        continue;
+      }
+      scenario_last_upload_timestamp_[*scenario] = *upload_time;
+    }
+  }
+
+  // Save state to update the current session state, replacing the previous
+  // session state.
+  SaveState();
+}
+
+void ChromeTracingDelegate::BackgroundTracingStateManager::SaveState() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(initialized_);
+  SaveState(scenario_last_upload_timestamp_, state_);
+}
+
+// static
+void ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+    const ChromeTracingDelegate::ScenarioUploadTimestampMap&
+        scenario_upload_times,
+    ChromeTracingDelegate::BackgroundTracingState state) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  base::DictionaryValue dict;
+  dict.SetInteger(kTracingStateKey, static_cast<int>(state));
+  base::ListValue upload_times;
+  for (const auto& it : scenario_upload_times) {
+    base::DictionaryValue scenario;
+    scenario.SetString(kScenarioKey, StripScenarioName(it.first));
+    scenario.SetKey(kUploadTimestampKey, util::TimeToValue(it.second));
+    upload_times.Append(std::move(scenario));
+  }
+  dict.SetKey(kUploadTimesKey, std::move(upload_times));
+
+  PrefService* local_state = g_browser_process->local_state();
+  local_state->Set(prefs::kBackgroundTracingSessionState, std::move(dict));
+  local_state->CommitPendingWrite();
+}
+
+bool ChromeTracingDelegate::BackgroundTracingStateManager::
+    DidLastSessionEndUnexpectedly() const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(initialized_);
+  switch (last_session_end_state_) {
+    case BackgroundTracingState::NOT_ACTIVATED:
+    case BackgroundTracingState::RAN_30_SECONDS:
+    case BackgroundTracingState::FINALIZATION_STARTED:
+      return false;
+    case BackgroundTracingState::STARTED:
+      // If Chrome did not run for 30 seconds after tracing started in previous
+      // session then do not start tracing in current session as a safeguard.
+      // This would be impacted by short sessions (eg: on Android), but worth
+      // the tradeoff of crashing loop on startup. Checking for previous session
+      // crash status is platform dependent and the crash status is initialized
+      // at later point than when tracing begins. So, this check is safer than
+      // waiting for crash metrics to be available. Note that this setting only
+      // checks for last session and not sessions before that. So, the next
+      // session might still crash due to tracing if the user has another
+      // tracing experiment. But, meanwhile we would be able to turn off tracing
+      // experiments based on uploaded crash metrics.
+      return true;
+  }
+}
+
+bool ChromeTracingDelegate::BackgroundTracingStateManager::
+    DidRecentlyUploadForScenario(
+        const content::BackgroundTracingConfig& config) const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(initialized_);
+  std::string stripped_scenario_name =
+      StripScenarioName(config.scenario_name());
+  auto it = scenario_last_upload_timestamp_.find(stripped_scenario_name);
+  if (it != scenario_last_upload_timestamp_.end()) {
+    return (base::Time::Now() - it->second) <=
+           base::TimeDelta::FromDays(kMinDaysUntilNextUpload);
+  }
+  return false;
+}
+
+void ChromeTracingDelegate::BackgroundTracingStateManager::SetState(
+    BackgroundTracingState new_state) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(initialized_);
+  if (state_ == new_state) {
+    return;
+  }
+  // If finalization started before 30 seconds, skip recording the new state.
+  if (new_state == BackgroundTracingState::RAN_30_SECONDS &&
+      state_ == BackgroundTracingState::FINALIZATION_STARTED) {
+    return;
+  }
+  state_ = new_state;
+  SaveState();
+}
+
+void ChromeTracingDelegate::BackgroundTracingStateManager::OnScenarioUploaded(
+    const std::string& scenario_name) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(initialized_);
+
+  scenario_last_upload_timestamp_[StripScenarioName(scenario_name)] =
+      base::Time::Now();
+  SaveState();
+}
+
+void ChromeTracingDelegate::RegisterPrefs(PrefRegistrySimple* registry) {
+  // TODO(ssid): This is no longer used, remove the pref once the new one is
+  // stable.
+  registry->RegisterInt64Pref(prefs::kBackgroundTracingLastUpload, 0);
+  registry->RegisterDictionaryPref(prefs::kBackgroundTracingSessionState);
+}
+
+ChromeTracingDelegate::ChromeTracingDelegate() {
   // Ensure that this code is called on the UI thread, except for
   // tests where a UI thread might not have been initialized at this point.
   DCHECK(
@@ -121,120 +323,74 @@
       new TraceCrashServiceUploader(std::move(factory)));
 }
 
-namespace {
-
-enum PermitMissingProfile { PROFILE_REQUIRED, PROFILE_NOT_REQUIRED };
-
-Profile* GetProfile() {
-  ProfileManager* profile_manager = g_browser_process->profile_manager();
-  if (!profile_manager)
-    return nullptr;
-
-  return profile_manager->GetLastUsedProfileIfLoaded();
-}
-
-bool ProfileAllowsScenario(const content::BackgroundTracingConfig& config,
-                           PermitMissingProfile profile_permission,
-                           bool is_crash_scenario) {
+bool ChromeTracingDelegate::IsAllowedToBeginBackgroundScenarioInternal(
+    const content::BackgroundTracingConfig& config,
+    bool requires_anonymized_data) const {
   // If the background tracing is specified on the command-line, we allow
   // any scenario to be traced.
-  if (tracing::GetBackgroundTracingSetupMode() ==
-      tracing::BackgroundTracingSetupMode::kFromConfigFile) {
+  if (IsBackgroundTracingCommandLine()) {
     return true;
   }
-
-  // If the profile hasn't loaded or been created yet, we allow the scenario
-  // to start up, but not be finalized.
-  Profile* profile = GetProfile();
-  if (!profile) {
-    if (profile_permission == PROFILE_REQUIRED) {
-      RecordDisallowedMetric(
-          TracingFinalizationDisallowedReason::kProfileNotLoaded);
-    }
-    return profile_permission != PROFILE_REQUIRED;
+  if (requires_anonymized_data && chrome::IsOffTheRecordSessionActive()) {
+    RecordDisallowedMetric(
+        TracingFinalizationDisallowedReason::kIncognitoLaunched);
+    return false;
   }
 
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && defined(OFFICIAL_BUILD)
-  if (!local_state->GetBoolean(metrics::prefs::kMetricsReportingEnabled)) {
+  BackgroundTracingStateManager& state =
+      BackgroundTracingStateManager::GetInstance();
+  if (state.DidLastSessionEndUnexpectedly()) {
+    RecordDisallowedMetric(
+        TracingFinalizationDisallowedReason::kLastTracingSessionDidNotEnd);
+    return false;
+  }
+  if (!IsMetricsReportingEnabled()) {
     RecordDisallowedMetric(
         TracingFinalizationDisallowedReason::kMetricsReportingDisabled);
     return false;
   }
-#endif  // !OS_CHROMEOS && OFFICIAL_BUILD
 
-  // Skip the rest of the checks, we know that the scenario does not have
-  // incognito profile and metrics reporting is enabled. Skip the upload limit
-  // checks.
-  if (is_crash_scenario) {
-    // Maybe we shouldn't skip the browser crash test when session begins (when
-    // PROFILE_NOT_REQUIRED).
-    DCHECK_EQ(PROFILE_REQUIRED, profile_permission);
-    return true;
-  }
-
-// Safeguard, in case background tracing is responsible for a crash on
-// startup.
-#if !defined(OS_ANDROID)
-  if (profile->GetLastSessionExitType() == Profile::EXIT_CRASHED) {
+  // If it is a crash scenario then ignore the trace upload limit and continue
+  // uploading. We again check if the trigger was due to crash later before
+  // uploading.
+  if (!config.has_crash_scenario() &&
+      state.DidRecentlyUploadForScenario(config)) {
     RecordDisallowedMetric(
-        TracingFinalizationDisallowedReason::kLastSessionCrashed);
+        TracingFinalizationDisallowedReason::kTraceUploadedRecently);
     return false;
   }
-#else
-  // If the metrics haven't loaded, we allow the scenario to start up, but not
-  // be finalized.
-  if (!CrashUploadListAndroid::BrowserCrashMetricsInitialized()) {
-    if (profile_permission == PROFILE_REQUIRED) {
-      RecordDisallowedMetric(
-          TracingFinalizationDisallowedReason::kCrashMetricsNotLoaded);
-    }
-    return profile_permission != PROFILE_REQUIRED;
-  }
-
-  if (CrashUploadListAndroid::DidBrowserCrashRecently()) {
-    RecordDisallowedMetric(
-        TracingFinalizationDisallowedReason::kLastSessionCrashed);
-    return false;
-  }
-#endif
-
-  if (config.tracing_mode() == content::BackgroundTracingConfig::PREEMPTIVE) {
-    const base::Time last_upload_time = base::Time::FromInternalValue(
-        local_state->GetInt64(prefs::kBackgroundTracingLastUpload));
-    if (!last_upload_time.is_null()) {
-      base::Time computed_next_allowed_time =
-          last_upload_time + base::TimeDelta::FromDays(kMinDaysUntilNextUpload);
-      if (computed_next_allowed_time > base::Time::Now()) {
-        RecordDisallowedMetric(
-            TracingFinalizationDisallowedReason::kTraceUploadedRecently);
-        return false;
-      }
-    }
-  }
-
   return true;
 }
 
-}  // namespace
-
 bool ChromeTracingDelegate::IsAllowedToBeginBackgroundScenario(
     const content::BackgroundTracingConfig& config,
     bool requires_anonymized_data) {
-  // For crash-triggered traces, we can only support preemptive tracing. For
-  // such preemptive traces, the profile will not be loaded yet, and calling
-  // ProfileAllowsScenario() will return true to allow the trace to start,
-  // regardless of the value of is_crash_scenario.
-  if (!ProfileAllowsScenario(config, PROFILE_NOT_REQUIRED,
-                             /*is_crash_scenario=*/false)) {
+  // We call Initialize() only when a tracing scenario tries to start, and
+  // unless this happens we never save state. In particular, if the background
+  // tracing experiment is disabled, Initialize() will never be called, and we
+  // will thus not save state. This means that when we save the background
+  // tracing session state for one session, and then later read the state in a
+  // future session, there might have been sessions between these two where
+  // tracing was disabled. Therefore, when we record
+  // TracingFinalizationDisallowedReason::kLastTracingSessionDidNotEnd, it might
+  // not be the directly preceding session, but instead it is the previous
+  // session where tracing was enabled.
+  BackgroundTracingStateManager& state =
+      BackgroundTracingStateManager::GetInstance();
+  state.Initialize();
+
+  if (!IsAllowedToBeginBackgroundScenarioInternal(config,
+                                                  requires_anonymized_data)) {
     return false;
   }
 
-  if (requires_anonymized_data && chrome::IsOffTheRecordSessionActive())
-    return false;
-
+  state.SetState(BackgroundTracingState::STARTED);
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, base::BindOnce([]() {
+        BackgroundTracingStateManager::GetInstance().SetState(
+            BackgroundTracingState::RAN_30_SECONDS);
+      }),
+      base::TimeDelta::FromSeconds(30));
   return true;
 }
 
@@ -242,6 +398,17 @@
     const content::BackgroundTracingConfig& config,
     bool requires_anonymized_data,
     bool is_crash_scenario) {
+  BackgroundTracingStateManager& state =
+      BackgroundTracingStateManager::GetInstance();
+  state.SetState(BackgroundTracingState::FINALIZATION_STARTED);
+  // If it is a crash scenario then ignore the trace upload limit and continue
+  // uploading.
+  if (!is_crash_scenario && state.DidRecentlyUploadForScenario(config)) {
+    RecordDisallowedMetric(
+        TracingFinalizationDisallowedReason::kTraceUploadedRecently);
+    return false;
+  }
+
   if (requires_anonymized_data &&
       (incognito_launched_ || chrome::IsOffTheRecordSessionActive())) {
     RecordDisallowedMetric(
@@ -249,27 +416,10 @@
     return false;
   }
 
-  if (!ProfileAllowsScenario(config, PROFILE_REQUIRED, is_crash_scenario))
-    return false;
-
-  if (config.tracing_mode() == content::BackgroundTracingConfig::PREEMPTIVE) {
-    PrefService* local_state = g_browser_process->local_state();
-    DCHECK(local_state);
-    local_state->SetInt64(prefs::kBackgroundTracingLastUpload,
-                          base::Time::Now().ToInternalValue());
-
-    // We make sure we've persisted the value in case finalizing the tracing
-    // causes a crash.
-    local_state->CommitPendingWrite();
-  }
-
+  state.OnScenarioUploaded(config.scenario_name());
   return true;
 }
 
-bool ChromeTracingDelegate::IsProfileLoaded() {
-  return GetProfile() != nullptr;
-}
-
 bool ChromeTracingDelegate::IsSystemWideTracingEnabled() {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Always allow system tracing in dev mode images.
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.h b/chrome/browser/tracing/chrome_tracing_delegate.h
index 69cb03c..3cfdf0f 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate.h
+++ b/chrome/browser/tracing/chrome_tracing_delegate.h
@@ -7,6 +7,9 @@
 
 #include <memory>
 
+#include "base/containers/flat_map.h"
+#include "base/gtest_prod_util.h"
+#include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "content/public/browser/tracing_delegate.h"
 
@@ -18,6 +21,10 @@
 
 class PrefRegistrySimple;
 
+namespace base {
+class Time;
+}
+
 namespace network {
 class SharedURLLoaderFactory;
 }
@@ -38,22 +45,109 @@
   std::unique_ptr<content::TraceUploader> GetTraceUploader(
       scoped_refptr<network::SharedURLLoaderFactory> factory) override;
 
+  // Returns if the tracing session is allowed to begin. Also updates the
+  // background tracing state in prefs using BackgroundTracingStateManager. So,
+  // this is required to be called exactly once per background tracing session
+  // before tracing is started. If this returns true, a tasks is posted 30
+  // seconds into the future that will mark a successful startup / run of a
+  // trace and will allow tracing to run next time.
   bool IsAllowedToBeginBackgroundScenario(
       const content::BackgroundTracingConfig& config,
       bool requires_anonymized_data) override;
 
+  // Returns true if tracing is allowed to end. Also updates the background
+  // tracing state in prefs using BackgroundTracingStateManager when returning
+  // true. This is required to be called before stopping background tracing.
   bool IsAllowedToEndBackgroundScenario(
       const content::BackgroundTracingConfig& config,
       bool requires_anonymized_data,
       bool is_crash_scenario) override;
 
-  bool IsProfileLoaded() override;
-
   bool IsSystemWideTracingEnabled() override;
 
   std::unique_ptr<base::DictionaryValue> GenerateMetadataDict() override;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingThrottleTimeElapsed);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingTimeThrottledAfterPreviousDay);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingUnexpectedSessionEnd);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingSessionRanLong);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingTimeThrottledUpdatedScenario);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingTimeThrottledDifferentScenario);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingFinalizationStarted);
+  FRIEND_TEST_ALL_PREFIXES(ChromeTracingDelegateBrowserTest,
+                           BackgroundTracingFinalizationBefore30Seconds);
+
+  // Do not remove or change the order of enum fields since it is stored in
+  // preferences.
+  enum class BackgroundTracingState : int {
+    // Default state when tracing is not started in previous session, or when
+    // state is not found or invalid.
+    NOT_ACTIVATED = 0,
+    STARTED = 1,
+    RAN_30_SECONDS = 2,
+    FINALIZATION_STARTED = 3,
+    LAST = FINALIZATION_STARTED,
+  };
+
+  using ScenarioUploadTimestampMap = base::flat_map<std::string, base::Time>;
+
+  // Manages local state prefs for background tracing, and tracks state from
+  // previous background tracing session(s). This is a singleton, but there
+  // could be many instances of ChromeTracingDelegate. All the calls are
+  // expected to run on UI thread.
+  class BackgroundTracingStateManager {
+   public:
+    static BackgroundTracingStateManager& GetInstance();
+
+    // Initializes state from previous session and writes current state to
+    // prefs, when called the first time. NOOP on any calls after that. It also
+    // deletes any expired entries from prefs.
+    void Initialize();
+
+    // True if last session potentially crashed and it is unsafe to turn on
+    // background tracing in current session.
+    bool DidLastSessionEndUnexpectedly() const;
+    // True if chrome uploaded a trace for the given |config| recently, and
+    // uploads should be throttled for the |config|.
+    bool DidRecentlyUploadForScenario(
+        const content::BackgroundTracingConfig& config) const;
+
+    // Updates the current tracing state and saves it to prefs.
+    void SetState(BackgroundTracingState new_state);
+    // Updates the state to include the upload time for |scenario_name|, and
+    // saves it to prefs.
+    void OnScenarioUploaded(const std::string& scenario_name);
+
+    // Saves the given state to prefs, public for testing.
+    static void SaveState(const ScenarioUploadTimestampMap& upload_times,
+                          BackgroundTracingState state);
+
+   private:
+    friend base::NoDestructor<BackgroundTracingStateManager>;
+
+    BackgroundTracingStateManager();
+    ~BackgroundTracingStateManager();
+
+    void SaveState();
+
+    BackgroundTracingState state_ = BackgroundTracingState::NOT_ACTIVATED;
+
+    bool initialized_ = false;
+
+    // Following are valid only when |initialized_| = true.
+    BackgroundTracingState last_session_end_state_ =
+        BackgroundTracingState::NOT_ACTIVATED;
+    base::flat_map<std::string, base::Time> scenario_last_upload_timestamp_;
+  };
+
 #if defined(OS_ANDROID)
   // TabModelListObserver implementation.
   void OnTabModelAdded() override;
@@ -63,7 +157,11 @@
   void OnBrowserAdded(Browser* browser) override;
 #endif
 
-  bool incognito_launched_;
+  bool IsAllowedToBeginBackgroundScenarioInternal(
+      const content::BackgroundTracingConfig& config,
+      bool requires_anonymized_data) const;
+
+  bool incognito_launched_ = false;
 };
 
 #endif  // CHROME_BROWSER_TRACING_CHROME_TRACING_DELEGATE_H_
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
index 0a33a0a..d053e383 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
+++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -6,11 +6,14 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/json/json_writer.h"
 #include "base/run_loop.h"
+#include "base/strings/pattern.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/tracing/chrome_tracing_delegate.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/common/pref_names.h"
@@ -28,8 +31,6 @@
 #include "content/public/test/test_utils.h"
 #include "services/tracing/public/cpp/tracing_features.h"
 
-namespace {
-
 class ChromeTracingDelegateBrowserTest : public InProcessBrowserTest {
  public:
   ChromeTracingDelegateBrowserTest()
@@ -47,9 +48,11 @@
 #endif
 
   bool StartPreemptiveScenario(
-      content::BackgroundTracingManager::DataFiltering data_filtering) {
+      content::BackgroundTracingManager::DataFiltering data_filtering,
+      base::StringPiece scenario_name = "TestScenario") {
     base::DictionaryValue dict;
 
+    dict.SetString("scenario_name", scenario_name);
     dict.SetString("mode", "PREEMPTIVE_TRACING_MODE");
     dict.SetString("custom_categories",
                    tracing::TraceStartupConfig::kDefaultStartupCategories);
@@ -158,6 +161,16 @@
   bool last_on_started_finalizing_success_;
 };
 
+std::string GetSessionStateJson() {
+  PrefService* local_state = g_browser_process->local_state();
+  DCHECK(local_state);
+  const base::DictionaryValue* state =
+      local_state->GetDictionary(prefs::kBackgroundTracingSessionState);
+  std::string json;
+  EXPECT_TRUE(base::JSONWriter::Write(*state, &json));
+  return json;
+}
+
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
                        BackgroundTracingTimeThrottled) {
   EXPECT_TRUE(StartPreemptiveScenario(
@@ -166,14 +179,13 @@
   TriggerPreemptiveScenario(base::OnceClosure());
 
   WaitForUpload();
-
   EXPECT_TRUE(get_receive_count() == 1);
 
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-  const base::Time last_upload_time = base::Time::FromInternalValue(
-      local_state->GetInt64(prefs::kBackgroundTracingLastUpload));
-  EXPECT_FALSE(last_upload_time.is_null());
+  std::string state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":3,"upload_times":[{"scenario":"TestScenario","time":"*"}]})"))
+      << "Actual: " << state;
 
   content::BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
   base::RunLoop wait_for_abort;
@@ -192,41 +204,164 @@
 }
 
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
-                       BackgroundTracingThrottleTimeElapsed) {
-  EXPECT_TRUE(StartPreemptiveScenario(
-      content::BackgroundTracingManager::NO_DATA_FILTERING));
+                       BackgroundTracingTimeThrottledAfterPreviousDay) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
 
-  TriggerPreemptiveScenario(base::OnceClosure());
-
-  WaitForUpload();
-
-  EXPECT_TRUE(get_receive_count() == 1);
-
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-  const base::Time last_upload_time = base::Time::FromInternalValue(
-      local_state->GetInt64(prefs::kBackgroundTracingLastUpload));
-  EXPECT_FALSE(last_upload_time.is_null());
-
-  content::BackgroundTracingManager::GetInstance()->AbortScenarioForTesting();
-  base::RunLoop wait_for_abort;
-  content::BackgroundTracingManager::GetInstance()->WhenIdle(
-      wait_for_abort.QuitClosure());
-  wait_for_abort.Run();
-  EXPECT_FALSE(
-      content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
-  EXPECT_FALSE(base::trace_event::TraceLog::GetInstance()->IsEnabled());
+  base::Time upload_time = base::Time::Now() - base::TimeDelta::FromDays(1);
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  upload_times["TestScenario"] = upload_time;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::NOT_ACTIVATED);
 
   EXPECT_FALSE(StartPreemptiveScenario(
       content::BackgroundTracingManager::NO_DATA_FILTERING));
 
-  // We move the last upload time to eight days in the past,
-  // and at that point should be able to start a scenario again.
-  base::Time new_upload_time = last_upload_time - base::TimeDelta::FromDays(8);
-  local_state->SetInt64(prefs::kBackgroundTracingLastUpload,
-                        new_upload_time.ToInternalValue());
+  state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":0,"upload_times":[{"scenario":"TestScenario","time":"*"}]})"))
+      << "Actual: " << state;
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingTimeThrottledUpdatedScenario) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  base::Time upload_time = base::Time::Now() - base::TimeDelta::FromDays(1);
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  upload_times["TestScenario10"] = upload_time;
+  upload_times["TestingScenario1"] = upload_time;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::NOT_ACTIVATED);
+
+  EXPECT_FALSE(StartPreemptiveScenario(
+      content::BackgroundTracingManager::NO_DATA_FILTERING, "TestScenario12"));
+
+  state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":0,"upload_times":[{"scenario":"TestScenario","time":"*"},)"
+      R"({"scenario":"TestingScenario","time":"*"}]})"))
+      << "Actual: " << state;
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingTimeThrottledDifferentScenario) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  base::Time upload_time = base::Time::Now() - base::TimeDelta::FromDays(1);
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  upload_times["TestScenario10"] = upload_time;
+  upload_times["TestingScenario1"] = upload_time;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::NOT_ACTIVATED);
+
+  EXPECT_TRUE(StartPreemptiveScenario(
+      content::BackgroundTracingManager::NO_DATA_FILTERING, "OtherScenario"));
+
+  state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":1,"upload_times":[{"scenario":"TestScenario","time":"*"},)"
+      R"({"scenario":"TestingScenario","time":"*"}]})"))
+      << "Actual: " << state;
+
+  TriggerPreemptiveScenario(base::OnceClosure());
+
+  WaitForUpload();
+  EXPECT_TRUE(get_receive_count() == 1);
+
+  state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":3,"upload_times":[{"scenario":"OtherScenario","time":"*"},)"
+      R"({"scenario":"TestScenario","time":"*"},)"
+      R"({"scenario":"TestingScenario","time":"*"}]})"))
+      << "Actual: " << state;
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingThrottleTimeElapsed) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  base::Time upload_time = base::Time::Now() - base::TimeDelta::FromDays(8);
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  upload_times["TestScenario"] = upload_time;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::NOT_ACTIVATED);
+
   EXPECT_TRUE(StartPreemptiveScenario(
       content::BackgroundTracingManager::NO_DATA_FILTERING));
+  state = GetSessionStateJson();
+  // Older entries are discarded.
+  EXPECT_EQ(state, R"({"state":1,"upload_times":[]})");
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingUnexpectedSessionEnd) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times, ChromeTracingDelegate::BackgroundTracingState::STARTED);
+
+  EXPECT_FALSE(StartPreemptiveScenario(
+      content::BackgroundTracingManager::NO_DATA_FILTERING));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingSessionRanLong) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::RAN_30_SECONDS);
+
+  EXPECT_TRUE(StartPreemptiveScenario(
+      content::BackgroundTracingManager::NO_DATA_FILTERING));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingFinalizationStarted) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::FINALIZATION_STARTED);
+
+  EXPECT_TRUE(StartPreemptiveScenario(
+      content::BackgroundTracingManager::NO_DATA_FILTERING));
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
+                       BackgroundTracingFinalizationBefore30Seconds) {
+  std::string state = GetSessionStateJson();
+  EXPECT_EQ(state, "{}");
+
+  ChromeTracingDelegate::ScenarioUploadTimestampMap upload_times;
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::FINALIZATION_STARTED);
+
+  // State does not update from finalization started to ran 30 seconds.
+  ChromeTracingDelegate::BackgroundTracingStateManager::SaveState(
+      upload_times,
+      ChromeTracingDelegate::BackgroundTracingState::RAN_30_SECONDS);
+  state = GetSessionStateJson();
+  EXPECT_EQ(state, R"({"state":2,"upload_times":[]})");
 }
 
 // If we need a PII-stripped trace, any existing OTR session should block the
@@ -267,10 +402,13 @@
     // We need to replace the config JSON with the full one here, as we can't
     // pass JSON through the fieldtrial switch parsing.
     if (config_text == "default_config_for_testing") {
-      return "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"custom_categories\": "
-             "\"base,toplevel\",\"configs\": [{\"rule\": "
-             "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\",\"trigger_name\":"
-             "\"test\"}]}";
+      return R"({
+        "mode": "PREEMPTIVE_TRACING_MODE",
+        "scenario_name": "TestScenario",
+        "custom_categories": "base,toplevel",
+        "configs": [{"rule": "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED",
+                     "trigger_name": "test"}]
+        })";
     }
     return config_text;
   }
@@ -291,49 +429,52 @@
 
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
                        PRE_ScenarioSetFromFieldtrial) {
-  // This test exists just to make sure the browser is created at least once and
-  // so a default profile is created. Then, the next time the browser is
-  // created, kMetricsReportingEnabled is explicitly read from the profile and
-  // the startup scenario can be activated.
+  // This test would enable tracing and shutdown browser before 30 seconds
+  // elapses. So, the profile would store incomplete state for next session.
+  EXPECT_TRUE(
+      content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
+  // State 1 = STARTED.
+  EXPECT_EQ(GetSessionStateJson(), R"({"state":1,"upload_times":[]})");
 }
 
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
                        ScenarioSetFromFieldtrial) {
-  // We should reach this point without crashing.
+  // Scenario should be inactive even though we have a config because last
+  // session shut down unexpectedly.
+  EXPECT_FALSE(
+      content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
+  // State 0 = NOT_ACTIVATED, current session is inactive.
+  EXPECT_EQ(GetSessionStateJson(), R"({"state":0,"upload_times":[]})");
+}
+
+IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
+                       PRE_StartupTracingThrottle) {
   EXPECT_TRUE(
       content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
-}
+  EXPECT_EQ(GetSessionStateJson(), R"({"state":1,"upload_times":[]})");
 
-// TODO(crbug.com/1134793): Test is disabled after failing on multiple mac
-// builders.
-IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
-                       DISABLED_PRE_PRE_StartupTracingThrottle) {
-  // This test exists just to make sure the browser is created at least once and
-  // so a default profile is created. Then, the next time the browser is
-  // created, kMetricsReportingEnabled is explicitly read from the profile and
-  // the startup scenario can be activated.
+  TriggerPreemptiveScenario(base::OnceClosure());
+
+  // This updates the upload time for the test scenario to current time.
+  WaitForUpload();
+  EXPECT_TRUE(get_receive_count() == 1);
+
+  std::string state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":3,"upload_times":[{"scenario":"TestScenario","time":"*"}]})"))
+      << "Actual: " << state;
 }
 
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
-                       DISABLED_PRE_StartupTracingThrottle) {
-  EXPECT_TRUE(
-      content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
-
-  // Simulate a trace upload.
-  PrefService* local_state = g_browser_process->local_state();
-  DCHECK(local_state);
-  local_state->SetInt64(prefs::kBackgroundTracingLastUpload,
-                        base::Time::Now().ToInternalValue());
-}
-
-// https://crbug.com/832981: The test is reenabled to check if flakiness still
-// exists.
-IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTestOnStartup,
-                       DISABLED_StartupTracingThrottle) {
+                       StartupTracingThrottle) {
   // The startup scenario should *not* be started, since not enough
   // time has elapsed since the last upload (set in the PRE_ above).
   EXPECT_FALSE(
       content::BackgroundTracingManager::GetInstance()->HasActiveScenario());
+  std::string state = GetSessionStateJson();
+  EXPECT_TRUE(base::MatchPattern(
+      state,
+      R"({"state":0,"upload_times":[{"scenario":"TestScenario","time":"*"}]})"))
+      << "Actual: " << state;
 }
-
-}  // namespace
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index a4809b6..4ff17c7 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1411,8 +1411,6 @@
       "webui/inspect_ui.h",
       "webui/internals/user_education/user_education_internals_page_handler_impl.cc",
       "webui/internals/user_education/user_education_internals_page_handler_impl.h",
-      "webui/internals/web_app/web_app_internals_page_handler_impl.cc",
-      "webui/internals/web_app/web_app_internals_page_handler_impl.h",
       "webui/managed_ui_handler.cc",
       "webui/managed_ui_handler.h",
       "webui/management/management_ui.cc",
@@ -1574,6 +1572,8 @@
       "webui/theme_source.h",
       "webui/util/image_util.cc",
       "webui/util/image_util.h",
+      "webui/web_app_internals/web_app_internals_source.cc",
+      "webui/web_app_internals/web_app_internals_source.h",
       "webui/web_footer_experiment_ui.cc",
       "webui/web_footer_experiment_ui.h",
       "webui/whats_new/whats_new_ui.cc",
@@ -1612,7 +1612,6 @@
       "//chrome/browser/ui/commander:fuzzy_finder",
       "//chrome/browser/ui/webui/app_management:mojo_bindings",
       "//chrome/browser/ui/webui/internals/user_education:mojo_bindings",
-      "//chrome/browser/ui/webui/internals/web_app:mojo_bindings",
       "//chrome/browser/web_applications/components",
       "//chrome/common:buildflags",
       "//chrome/common/search:generate_chrome_colors_info",
@@ -3992,6 +3991,8 @@
       "views/location_bar/omnibox_chip_button.h",
       "views/location_bar/permission_chip.cc",
       "views/location_bar/permission_chip.h",
+      "views/location_bar/permission_quiet_chip.cc",
+      "views/location_bar/permission_quiet_chip.h",
       "views/location_bar/permission_request_chip.cc",
       "views/location_bar/permission_request_chip.h",
       "views/location_bar/selected_keyword_view.cc",
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
index 651fe25..98061d6 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Bereken tans …</translation>
 <translation id="1383876407941801731">Soek</translation>
 <translation id="1384704387250346179">Vertaal prent met Google Lens <ph name="BEGIN_NEW" />Nuut<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stileer hoogtepunt</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> dae gelede aktief</translation>
 <translation id="1397811292916898096">Soek met <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Moenie naspoor nie”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knoppie</translation>
 <translation id="2000419248597011803">Stuur 'n paar webkoekies en soektogte vanaf die adresbalk en soekkassie na jou versteksoekenjin toe</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# lêer}other{# lêers}}</translation>
-<translation id="2017836877785168846">Vee geskiedenis en outovoltooiings in die adresbalk uit.</translation>
 <translation id="2021896219286479412">Volskermwerfkontroles</translation>
 <translation id="2038563949887743358">Skakel Versoek rekenaarwerf aan</translation>
 <translation id="2039379262107991683">Voeg bladsye by jou leeslys om 'n onthounota te kry</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Tale</translation>
 <translation id="4183868528246477015">Soek met Google Lens <ph name="BEGIN_NEW" />Nuut<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Maak in nuwe oortjie oop</translation>
+<translation id="4196597275619698563">Skep kaart</translation>
 <translation id="4198423547019359126">Geen beskikbare aflaailiggings nie</translation>
-<translation id="4206707945726604465">Besoek <ph name="BEGIN_LINK1" />My Google-aktiwiteit<ph name="END_LINK1" /> om ander vorme van geskiedenis uit te vee</translation>
 <translation id="4209895695669353772">Skakel sinkronisering aan om gepersonaliseerde inhoud wat deur Google voorgestel is, te kry</translation>
 <translation id="4225895483398857530">Nutsbalkkortpad</translation>
 <translation id="4242533952199664413">Maak instellings oop</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – laai tans af …</translation>
 <translation id="4404568932422911380">Geen boekmerke nie</translation>
 <translation id="4405224443901389797">Skuif na …</translation>
+<translation id="4409271659088619928">Jou soekenjin is <ph name="DSE" />. Sien hul instruksies om jou soekgeskiedenis uit te vee, indien nodig.</translation>
 <translation id="4411535500181276704">Ligte modus</translation>
 <translation id="4415276339145661267">Bestuur jou Google-rekening</translation>
 <translation id="4427306783828095590">Verbeterde beskerming doen meer om uitvissing en wanware te blokkeer</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">Gaan wagwoorde na</translation>
 <translation id="6000066717592683814">Hou Google</translation>
 <translation id="6000203700195075278">Volg weer</translation>
-<translation id="6002623704405939939">Besoek <ph name="BEGIN_LINK2" />My Google-aktiwiteit<ph name="END_LINK2" /> om <ph name="BEGIN_LINK1" />soektog<ph name="END_LINK1" /> of ander vorme van geskiedenis uit te vee</translation>
 <translation id="6005538289190791541">Voorgestelde wagwoord</translation>
 <translation id="6032091552407840792">Hierdie proeflopie is net in <ph name="BEGIN_LINK" />sommige streke<ph name="END_LINK" /> aktief.</translation>
 <translation id="6033245666633565791">Met <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> ontwikkel Chrome nuwe tegnologieë om jou teen kruiswerfnasporing te beveilig terwyl dit die oop web in stand hou.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">Verbeter sekuriteit vir jou en almal op die web.</translation>
 <translation id="6618554661997243500">Tik op die Tuisknoppie om topwerwe en -berigte te sien</translation>
 <translation id="6627583120233659107">Wysig vouer</translation>
-<translation id="6635718764393004944">Jou soekenjin is <ph name="DSE" />. Sien hulle instruksies om jou soekgeskiedenis uit te vee, indien nodig.</translation>
 <translation id="663674369910034433">Raadpleeg <ph name="BEGIN_LINK1" />Sinkronisering<ph name="END_LINK1" /> en <ph name="BEGIN_LINK2" />Google-dienste<ph name="END_LINK2" /> vir meer instellings wat verband hou met privaatheid, sekuriteit en data-insameling</translation>
 <translation id="6643016212128521049">Vee uit</translation>
 <translation id="6643649862576733715">Rangskik volgens hoeveelheid data bespaar</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">Outovoltooi soektogte en URL'e</translation>
 <translation id="7707922173985738739">Gebruik mobiele data</translation>
 <translation id="7725024127233776428">Bladsye wat jy boekmerk, verskyn hier</translation>
+<translation id="7731260005404856143"><ph name="BEGIN_LINK1" />Ander soorte aktiwiteit<ph name="END_LINK1" /> sal dalk in jou Google-rekening gestoor word wanneer jy aangemeld is. Jy kan dit enige tyd uitvee.</translation>
 <translation id="7757787379047923882">Teks gedeel vanaf <ph name="DEVICE_NAME" /></translation>
 <translation id="7761849928583394409">Kies datum en tyd</translation>
 <translation id="7762668264895820836">SD-kaart <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">Sien jou vanlyn lêers</translation>
 <translation id="8856607253650333758">Kry beskrywings</translation>
 <translation id="8873817150012960745">Tik hier om te begin</translation>
+<translation id="8881973373982641723">Vee geskiedenis uit, ook in die soekkassie.</translation>
 <translation id="889338405075704026">Gaan na Chrome-instellings</translation>
 <translation id="8898822736010347272">Stuur URL'e van sommige bladsye wat jy besoek, beperkte stelselinligting en sekere bladsyinhoud na Google toe om te help om nuwe bedreigings te ontdek en almal op die web te beskerm.</translation>
 <translation id="8909135823018751308">Deel …</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">Kan nie oproepe maak nie</translation>
 <translation id="9212845824145208577">Kan nie laer gaan nie. Probeer om laer op die bladsy te begin.</translation>
 <translation id="9219103736887031265">Prente</translation>
+<translation id="923957533152125119"><ph name="BEGIN_LINK1" />Soekgeskiedenis<ph name="END_LINK1" /> en <ph name="BEGIN_LINK2" />ander soorte aktiwiteit<ph name="END_LINK2" /> sal dalk in jou Google-rekening gestoor word wanneer jy aangemeld is. Jy kan dit enige tyd uitvee.</translation>
 <translation id="926205370408745186">Verwyder jou Chrome-aktiwiteit van Digitale Welstand</translation>
 <translation id="927968626442779827">Gebruik Ligte Modus op Google Chrome</translation>
 <translation id="932327136139879170">Tuis</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
index 6aad7b07..0f4c8cb8 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">በማስላት ላይ…</translation>
 <translation id="1383876407941801731">ፍለጋ </translation>
 <translation id="1384704387250346179">ምስልን በGoogle ሌንስ <ph name="BEGIN_NEW" />አዲስ<ph name="END_NEW" /> ያስተርጉሙ</translation>
-<translation id="1385855801883526502">ቅጥ ያለው ድምቀት</translation>
 <translation id="1386674309198842382">ገባሪ ከ<ph name="LAST_UPDATED" /> ቀናት በፊት</translation>
 <translation id="1397811292916898096">በ<ph name="PRODUCT_NAME" /> ይፈልጉ</translation>
 <translation id="1406000523432664303">«አትከታተል»</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> አዝራር</translation>
 <translation id="2000419248597011803">ፍለጋዎችን ከአድራሻ አሞሌው እና ከፍለጋ ሳጥኑ እና አንዳንድ ኩኪዎችን ወደ ነባሪው የፍለጋ ፕሮግራምዎ ይልካል</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ፋይል}one{# ፋይሎች}other{# ፋይሎች}}</translation>
-<translation id="2017836877785168846">በአድራሻ አሞሌው ውስጥ ታሪክን እና ራስ-ሰር ማጠናቀቆችን ያጸዳል።</translation>
 <translation id="2021896219286479412">የሙሉ ማያ ገጽ ጣቢያ መቆጣጠሪያዎች</translation>
 <translation id="2038563949887743358">የዴስክቶፕ ጣቢያን ጠይቅን አብራ</translation>
 <translation id="2039379262107991683">አስታዋሽ ለማግኘት ገጾችን ወደ ንባብ ዝርዝርዎ ያክሉ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">በGoogle Lens ይፈልጉ <ph name="BEGIN_NEW" />አዲስ<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">በአዲስ ትር ክፈት</translation>
 <translation id="4198423547019359126">ምንም የማውረጃ አካባቢዎች የሉም</translation>
-<translation id="4206707945726604465">ሌሎች የታሪክ ዓይነቶችን ለማጽዳት <ph name="BEGIN_LINK1" />የእኔ የGoogle እንቅስቃሴ<ph name="END_LINK1" />ን ይጎብኙ</translation>
 <translation id="4209895695669353772">በGoogle የተጠቆመ ግላዊነት የተላበሰ ይዘትን ስምረትን ማብራት ለማግኘት</translation>
 <translation id="4225895483398857530">የመሣሪያ አሞሌ አቋራጭ</translation>
 <translation id="4242533952199664413">ቅንብሮችን ክፈት</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - በማውረድ ላይ…</translation>
 <translation id="4404568932422911380">ምንም ዕልባቶች የሉም</translation>
 <translation id="4405224443901389797">ውሰድ ወደ…</translation>
+<translation id="4409271659088619928">የእርስዎ የፍለጋ ፕሮግራም <ph name="DSE" /> ነው። መተግበር የሚችል ከሆነ የፍለጋ ታሪክዎን ለመሰረዝ መመሪያዎቻቸውን ይመልከቱ።</translation>
 <translation id="4411535500181276704">ቀላል ሁነታ</translation>
 <translation id="4415276339145661267">የGoogle መለያዎን ያቀናብሩ</translation>
 <translation id="4427306783828095590">የተሻሻለ ጥበቃ ማስገር እና ተንኮል-አዘል ዌር ለማገድ የበለጠ ይሠራል</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">የይለፍ ቃላትዎን ይፈትሹ</translation>
 <translation id="6000066717592683814">Googleን አቆየው</translation>
 <translation id="6000203700195075278">እንደገና ይከተሉ</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ፍለጋ<ph name="END_LINK1" />ን ወይም ሌሎች የታሪክ ቅርጾችን ለማጽዳት <ph name="BEGIN_LINK2" />የእኔ የGoogle እንቅስቃሴ<ph name="END_LINK2" />ን ይጎብኙ</translation>
 <translation id="6005538289190791541">የተጠቆመ የይለፍ ቃል</translation>
 <translation id="6032091552407840792">ይህ ሙከራ ንቁ የሆነው <ph name="BEGIN_LINK" />በአንዳንድ ክልሎች<ph name="END_LINK" /> ውስጥ ብቻ ነው።</translation>
 <translation id="6033245666633565791">በ<ph name="BEGIN_LINK" />የግላዊነት Sandbox<ph name="END_LINK" /> አማካኝነት Chrome ክፍት ድርን በሚጠብቁበት ጊዜ እርስዎን ከጣቢያ-ተሻጋሪ መከታተያ ለመጠበቅ አዲስ ቴክኖሎጂዎችን እየገነባ ነው።
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">ለእርስዎ እና ለማናቸውም በድር ላይ ያለ ሁሉም ሰው ደህንነትን ያሻሽላል።</translation>
 <translation id="6618554661997243500">ለእርስዎ የሚሆኑ ከፍተኛዎቹን ጣቢያዎች እና ዘገባዎች ለማየት የመነሻ አዝራሩን መታ ያድርጉ</translation>
 <translation id="6627583120233659107">አቃፊ አርትዕ</translation>
-<translation id="6635718764393004944">የእርስዎ የፍለጋ ፕሮግራም <ph name="DSE" /> ነው። መተግበር የሚችል ከሆነ የፍለጋ ታሪክዎን ለመሰረዝ መመሪያዎቻቸውን ይመልከቱ።</translation>
 <translation id="663674369910034433">ከግላዊነት፣ ደህንነት እና የውሂብ ስብስብ ጋር ለሚዛመዱ ተጨማሪ ቅንብሮች <ph name="BEGIN_LINK1" />ስምረት<ph name="END_LINK1" /> እና <ph name="BEGIN_LINK2" />የGoogle አገልግሎቶች<ph name="END_LINK2" />ን ይመልከቱ</translation>
 <translation id="6643016212128521049">አጽዳ</translation>
 <translation id="6643649862576733715">በተቆጠበው የውሂብ መጠን ደርድር</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
index 4672d9ff..2e9524b3 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">جارٍ الحوسبة...</translation>
 <translation id="1383876407941801731">البحث</translation>
 <translation id="1384704387250346179">ترجمة الصور مع "عدسة" <ph name="BEGIN_NEW" />جديد<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">تنميط التمييز</translation>
 <translation id="1386674309198842382">نشط قبل <ph name="LAST_UPDATED" /> من الأيام</translation>
 <translation id="1397811292916898096">البحث باستخدام <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"عدم التعقب"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">زر <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">يُرسِل بعض ملفات تعريف الارتباط وعمليات البحث من شريط العناوين ومربّع البحث إلى محرِّك البحث التلقائي.</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{ملف واحد (#)}zero{# ملف}two{ملفان (#)}few{# ملفات}many{# ملفًا}other{# ملف}}</translation>
-<translation id="2017836877785168846">محو السجلّ وعمليات الإكمال التلقائي في شريط العناوين.</translation>
 <translation id="2021896219286479412">عناصر التحكم لموقع في وضع ملء الشاشة</translation>
 <translation id="2038563949887743358">تفعيل طلب الموقع الإلكتروني لسطح المكتب</translation>
 <translation id="2039379262107991683">يمكنك إضافة صفحات إلى "قائمة القراءة" لتلقّي تذكير.</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">‏البحث باستخدام "عدسة Google" <ph name="BEGIN_NEW" />جديد<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">الفتح في علامة تبويب جديدة</translation>
 <translation id="4198423547019359126">ما من مواقع تنزيل متاحة</translation>
-<translation id="4206707945726604465">‏لمحو أنواع السجلّات الأخرى، انتقِل إلى صفحة <ph name="BEGIN_LINK1" />نشاطي على Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">‏للحصول على محتوى مُخصَّص اقترحته Google، يُرجى تفعيل المزامنة.</translation>
 <translation id="4225895483398857530">اختصارات شريط الأدوات</translation>
 <translation id="4242533952199664413">فتح الإعدادات</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546">جارٍ تنزيل حزمة اللغة <ph name="LANG" />…</translation>
 <translation id="4404568932422911380">ليست هناك إشارات مرجعية</translation>
 <translation id="4405224443901389797">نقل إلى...</translation>
+<translation id="4409271659088619928">محرّك البحث المستخدَم لديك هو <ph name="DSE" />. يمكنك الاطّلاع على تعليمات محرّك البحث الذي تستخدمه بشأن حذف سجلّ البحث إذا كان يوفّر هذه الميزة.</translation>
 <translation id="4411535500181276704">الوضع البسيط</translation>
 <translation id="4415276339145661267">‏إدارة حسابك على Google</translation>
 <translation id="4427306783828095590">يؤدي تفعيل إعداد "الحماية المُحسَّنة" إلى حظر التصيّد الاحتيالي والبرامج الضارّة.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">التحقق من كلمات المرور</translation>
 <translation id="6000066717592683814">‏الاستمرار في استخدام محرك Google</translation>
 <translation id="6000203700195075278">المتابعة مجدّدًا</translation>
-<translation id="6002623704405939939">‏لمحو <ph name="BEGIN_LINK1" />سجلّ البحث<ph name="END_LINK1" /> أو غيره من السجلّات، انتقِل إلى صفحة <ph name="BEGIN_LINK2" />نشاطي على Google<ph name="END_LINK2" />.</translation>
 <translation id="6005538289190791541">كلمة المرور المُقترحَة</translation>
 <translation id="6032091552407840792">لا يتوفّر هذا الإصدار التجريبي سوى في <ph name="BEGIN_LINK" />بعض المناطق<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">‏من خلال <ph name="BEGIN_LINK" />مبادرة حماية الخصوصية<ph name="END_LINK" />، نعمل في Chrome على تطوير تقنيات جديدة لحمايتك من آليات التتبُّع في جميع المواقع الإلكترونية مع الحفاظ على محتوى شبكة الإنترنت المفتوحة المتاحة للجميع.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">الاسم طويل جدًا</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{صورة واحدة (#)}zero{# صورة}two{صورتان (#)}few{# صور}many{# صورةً}other{# صورة}}</translation>
 <translation id="6447558397796644647">تعذّر العثور على هذه الإشارة. تحقّق من الإملاء أو أضِف إشارة جديدة.</translation>
+<translation id="6459045781120991510">استطلاعات الرأي</translation>
 <translation id="6461962085415701688">يتعذر فتح الملف</translation>
 <translation id="6464977750820128603">‏يمكنك الاطِّلاع على المواقع الإلكترونية التي تزورها في Chrome وتحديد موقِّتات لها.\n\nتحصل Google على معلومات عن المواقع الإلكترونية التي ضبطت موقِّتات لها ومدة زيارتك لها. تُستخدم هذه المعلومات لتحسين الرفاهية الرقمية.</translation>
 <translation id="6475951671322991020">تنزيل الفيديو</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">تحسين الأمان من أجلك ومن أجل جميع المستخدمين على الإنترنت</translation>
 <translation id="6618554661997243500">للاطّلاع على أهم المواقع الإلكترونية والأخبار، انقر على زر "الشاشة الرئيسية".</translation>
 <translation id="6627583120233659107">تعديل مجلد</translation>
-<translation id="6635718764393004944">محرّك بحثك هو <ph name="DSE" />. يمكنك الاطّلاع على التعليمات التي يوفّرها محرّك البحث الذي تستخدمه حول حذف سجلّ بحثك، إن أمكن ذلك.</translation>
 <translation id="663674369910034433">‏لعرض مزيد من الإعدادات المتعلّقة بالخصوصية والأمان وجمع البيانات، يُرجى الاطّلاع على <ph name="BEGIN_LINK1" />المزامنة<ph name="END_LINK1" /> و<ph name="BEGIN_LINK2" />خدمات Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">محو</translation>
 <translation id="6643649862576733715">الترتيب حسب مقدار البيانات التي تم توفيرها</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">ملاحظة مميّزة تم تنميطها بتاريخ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">‏يُرجى التأكّد من تفعيل مزامنة <ph name="TARGET_DEVICE_NAME" /> في Chrome.</translation>
 <translation id="7252076891734325316">قرِّب هاتفك من الكمبيوتر</translation>
+<translation id="727288900855680735">هل تريد إرسال <ph name="ONE_TIME_CODE" /> إلى <ph name="ORIGIN" />؟</translation>
 <translation id="7274013316676448362">الموقع المحظور</translation>
 <translation id="7286572596625053347">هل تريد تغيير اللغة <ph name="LANGUAGE" />؟</translation>
 <translation id="7290209999329137901">إعادة التسمية غير متوفرة</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
index 637dba4..13f8977 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">গণনা কৰি থকা হৈছে…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lensৰে প্ৰতিচ্ছবি অনুবাদ কৰক <ph name="BEGIN_NEW" />নতুন<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">হাইলাইটৰ শৈলীকৰণ কৰক</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" />দিনৰ পূৰ্বে সক্ৰিয় আছিল</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" />ৰ জৰিয়তে সন্ধান কৰক</translation>
 <translation id="1406000523432664303">“ট্ৰেক নকৰিব”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> বুটাম</translation>
 <translation id="2000419248597011803">আপোনাৰ ডিফ’ল্ট সন্ধান ইঞ্জিনলৈ ঠিকনা বাৰ আৰু সন্ধান বাকছৰ পৰা কিছুমান কুকি আৰু সন্ধান পঠিয়ায়</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{#টা ফাইল}one{#টা ফাইল}other{#টা ফাইল}}</translation>
-<translation id="2017836877785168846">ঠিকনাৰ বাৰত ইতিহাস আৰু স্বয়ংক্ৰিয়ভাৱে পুৰ হোৱা তথ্য মচে।</translation>
 <translation id="2021896219286479412">সম্পূর্ণ স্ক্ৰীণ ছাইটৰ নিয়ন্ত্ৰণ</translation>
 <translation id="2038563949887743358">ডেস্কটপ ছাইট অনুৰোধ কৰা সুবিধাটো অন কৰক</translation>
 <translation id="2039379262107991683">ৰিমাইণ্ডাৰ পাবলৈ আপোনাৰ পঢ়াৰ সূচীত পৃষ্ঠা যোগ দিয়ক</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lensৰে সন্ধান কৰক <ph name="BEGIN_NEW" />নতুন<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">নতুন টেবত খোলক</translation>
 <translation id="4198423547019359126">ডাউনল’ড কৰিবলৈ কোনো অৱস্থান নাই</translation>
-<translation id="4206707945726604465">সকলো প্ৰকাৰৰ ইতিহাস মচিবলৈ, <ph name="BEGIN_LINK1" />মই Googleত কৰা কাৰ্যকলাপ<ph name="END_LINK1" />লৈ যাওক</translation>
 <translation id="4209895695669353772">Googleএ চুপাৰিছ কৰা ব্যক্তিগতকৰণ কৰা সমল পাবলৈ ছিংক অন কৰক</translation>
 <translation id="4225895483398857530">টুলবাৰৰ শ্বৰ্টকাট</translation>
 <translation id="4242533952199664413">ছেটিংসমূহ খোলক</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ডাউনল’ড কৰি থকা হৈছে…</translation>
 <translation id="4404568932422911380">কোনো বুকমাৰ্ক নাই</translation>
 <translation id="4405224443901389797">ইয়ালৈ স্থানান্তৰ কৰক…</translation>
+<translation id="4409271659088619928">আপোনাৰ সন্ধানৰ ইঞ্জিনটো হৈছে <ph name="DSE" />। যদি প্ৰযোজ্য হয়, আপোনাৰ সন্ধানৰ ইতিহাস মচিবলৈ আপোনাৰ সন্ধানৰ ইঞ্জিনৰ নিৰ্দেশাৱলী চাওক।</translation>
 <translation id="4411535500181276704">লাইট ম’ড</translation>
 <translation id="4415276339145661267">আপোনাৰ Google একাউণ্ট পৰিচালনা কৰক</translation>
 <translation id="4427306783828095590">বৰ্ধিত সুৰক্ষাৰ সুবিধাটোৱে ফিশ্বিং আৰু মালৱেৰ অৱৰোধ কৰিবলৈ অধিক কাৰ্য কৰে</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">পাছৱৰ্ডবোৰ পৰীক্ষা কৰক</translation>
 <translation id="6000066717592683814">Google ৰাখক</translation>
 <translation id="6000203700195075278">পুনৰ ফ’ল’ কৰক</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />সন্ধান<ph name="END_LINK1" /> অথবা অন্য ধৰণৰ ইতিহাস মচিবলৈ <ph name="BEGIN_LINK2" />মই Googleত কৰা কাৰ্যকলাপ<ph name="END_LINK2" />লৈ যাওক</translation>
 <translation id="6005538289190791541">পৰামর্শ হিচাপে পোৱা পাছৱর্ড</translation>
 <translation id="6032091552407840792">এই ট্ৰায়েলটো কেৱল <ph name="BEGIN_LINK" />কিছুমান অঞ্চল<ph name="END_LINK" />ত সক্ৰিয়।</translation>
 <translation id="6033245666633565791">Chromeএ <ph name="BEGIN_LINK" />গোপনীয়তা বিষয়ক ছেণ্ডবক্স<ph name="END_LINK" />ৰ জৰিয়তে, আপোনাক মুক্ত ৱেবক সুৰক্ষিত কৰি ৰাখি ক্ৰছ-ছাইট ট্ৰেকিঙৰ পৰা আপোনাক সুৰক্ষা প্ৰদান কৰিবলৈ নতুন প্ৰযুক্তি বিকাশ কৰি আছে।
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">নামটো যথেষ্ট দীঘল</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# খন ছবি}one{# খন ছবি}other{# খন ছবি}}</translation>
 <translation id="6447558397796644647">সেই বুকমাৰ্কটো বিচাৰি পোৱা নাই। আপোনাৰ বানান পৰীক্ষা কৰক অথবা এটা নতুন বুকমার্ক যোগ কৰক।</translation>
+<translation id="6459045781120991510">সমীক্ষা</translation>
 <translation id="6461962085415701688">ফাইল খুলিব পৰা নাই</translation>
 <translation id="6464977750820128603">আপুনি Chromeত চোৱা ছাইটসমূহ চাব পাৰে আৰু সেইবোৰৰ বাবে টাইমাৰ ছেট কৰিব পাৰে।\n\nআপুনি টাইমাৰ ছেট কৰি থোৱা ছাইটসমূহ আৰু লগতে আপুনি কিমান সময় ধৰি সেইসমূহ চায়, Googleএ তাৰ তথ্য লাভ কৰে। এই তথ্যখিনি ডিজিটেল ৱেলবিইঙ-ক উন্নত কৰিবলৈ ব্যৱহাৰ কৰা হয়।</translation>
 <translation id="6475951671322991020">ভিডিঅ’ ডাউনল’ড কৰক</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">আপোনাৰ লগতে ৱেবত থকা প্ৰত্যেকজনৰ বাবে সুৰক্ষা উন্নত কৰে।</translation>
 <translation id="6618554661997243500">আপোনাৰ বাবে থকা শীৰ্ষ ছাইটসমূহ আৰু কাহিনীবোৰ চাবলৈ গৃহপৃষ্ঠাৰ বুটামটো টিপক</translation>
 <translation id="6627583120233659107">ফ’ল্ডাৰ সম্পাদনা কৰক</translation>
-<translation id="6635718764393004944">আপোনাৰ সন্ধানৰ ইঞ্জিনটো হৈছে <ph name="DSE" />। যদি প্ৰযোজ্য হয়, আপোনাৰ সন্ধানৰ ইতিহাস মচিবলৈ সেইবোৰৰ নিৰ্দেশাৱলী চাওক।</translation>
 <translation id="663674369910034433">গোপনীয়তা, সুৰক্ষা আৰু ডেটা সংগ্ৰহ সম্পৰ্কীয় অধিক ছেটিংসমূহৰ বাবে <ph name="BEGIN_LINK1" />ছিংক কৰক<ph name="END_LINK1" /> আৰু <ph name="BEGIN_LINK2" />Google সেৱাসমূহ<ph name="END_LINK2" /> চাওক</translation>
 <translation id="6643016212128521049">মচক</translation>
 <translation id="6643649862576733715">ছেভ কৰা ডেটাৰ পৰিমাণ অনুসৰি সজাওক</translation>
@@ -968,6 +965,7 @@
 <translation id="7242755609445462077">শৈলীকৰণ কৰা হাইলাইট <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">নিশ্চিত হৈ লওক যে Chromeত <ph name="TARGET_DEVICE_NAME" />ৰ ছিংক অন কৰা আছে</translation>
 <translation id="7252076891734325316">আপোনাৰ ফ'নটো কম্পিউটাৰটোৰ ওচৰত ৰাখক</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" />ত <ph name="ONE_TIME_CODE" /> দাখিল কৰিবনে?</translation>
 <translation id="7274013316676448362">অৱৰোধ কৰা ছাইট</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> সলনি কৰিবনে?</translation>
 <translation id="7290209999329137901">নতুন নাম দিয়াৰ সুবিধা উপলব্ধ নহয়</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
index 67664f9..db0dd1ac 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Hesablanır...</translation>
 <translation id="1383876407941801731">Axtar</translation>
 <translation id="1384704387250346179">Google Linza ilə şəkli tərcümə edin <ph name="BEGIN_NEW" />Yeni<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Vurğulama üslubunun təyini</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> gün əvvəl aktiv olub</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ilə axtarın</translation>
 <translation id="1406000523432664303">İzləməyin</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> düyməsi</translation>
 <translation id="2000419248597011803">Ünvan paneli və axtarış qutusundakı bəzi kuki və axtarışları defolt axtarış mühərrikinizə göndərin</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Fayl}other{# Fayl}}</translation>
-<translation id="2017836877785168846">Ünvan panelində tarixçə və avtomatik tamamlamaları silir.</translation>
 <translation id="2021896219286479412">Tam ekran sayt nəzarətləri</translation>
 <translation id="2038563949887743358">Əsas Versiya Sorğusunu aktiv edin</translation>
 <translation id="2039379262107991683">Xatırlatma almaq üçün Oxu Siyahınıza səhifələr əlavə edin</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Linza ilə axtarın <ph name="BEGIN_NEW" />Yeni<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Yeni tabda açın</translation>
 <translation id="4198423547019359126">Əlçatan endirmə məkanı yoxdur</translation>
-<translation id="4206707945726604465">Digər tarixçə formalarını təmizləmək üçün <ph name="BEGIN_LINK1" />Google Fəaliyyətim<ph name="END_LINK1" /> bölməsini ziyarət edin</translation>
 <translation id="4209895695669353772">Google tərəfindən təklif olunan fərdiləşdirilmiş kontenti əldə etmək üçün sinxronizasiyanı aktiv edin</translation>
 <translation id="4225895483398857530">Alətlər paneli qısayolu</translation>
 <translation id="4242533952199664413">Ayarları açın</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Endirilir…</translation>
 <translation id="4404568932422911380">Əlfəcin yoxdur</translation>
 <translation id="4405224443901389797">Bura köçürün:</translation>
+<translation id="4409271659088619928">Axtarış sisteminiz <ph name="DSE" />. Axtarış tarixçənizi silmək üçün onun təlimatlarına (təmin edilibsə) baxın.</translation>
 <translation id="4411535500181276704">Layt rejimi</translation>
 <translation id="4415276339145661267">Google Hesabını idarə edin</translation>
 <translation id="4427306783828095590">Təkmil qoruma ilə fişinq və zərərli proqramların bloklanması üçün daha çox iş görülür</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Parolları yoxlayın</translation>
 <translation id="6000066717592683814">Google'u saxlayın</translation>
 <translation id="6000203700195075278">Yenidən izləyin</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Axtarış<ph name="END_LINK1" /> və ya digər tarixçə formalarını təmizləmək üçün <ph name="BEGIN_LINK2" />Google Fəaliyyətim<ph name="END_LINK2" /> bölməsini ziyarət edin</translation>
 <translation id="6005538289190791541">Təklif edilən parol</translation>
 <translation id="6032091552407840792">Bu sınaq yalnız <ph name="BEGIN_LINK" />bəzi regionlarda<ph name="END_LINK" /> aktivdir.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Məxfilik Sendboksu<ph name="END_LINK" /> ilə Chrome açıq vebdən sərbəst şəkildə istifadənizi təmin edərkən sizi saytlararası izləmə mexanizmlərindən qoruyacaq yeni texnologiyalar hazırlayır.
@@ -884,7 +881,6 @@
 <translation id="661266467055912436">Siz və vebdəki hər kəs üçün təhlükəsizliyi artırır.</translation>
 <translation id="6618554661997243500">Sizin üçün populyar saytlar və hekayələrə baxmaq üçün Əsas səhifə düyməsinə toxunun</translation>
 <translation id="6627583120233659107">Qovluğa düzəliş edin</translation>
-<translation id="6635718764393004944">Axtarış sisteminiz <ph name="DSE" />. Mümkünsə, axtarış tarixçənizi silmək üçün təlimatlarına baxın.</translation>
 <translation id="663674369910034433">Məxfilik, təhlükəsizlik və datanın toplanması ilə bağlı daha çox ayarlar üçün <ph name="BEGIN_LINK1" />Sinxronizasiya<ph name="END_LINK1" /> və <ph name="BEGIN_LINK2" />Google xidmətləri<ph name="END_LINK2" /> səhifəsinə daxil olun.</translation>
 <translation id="6643016212128521049">Silin</translation>
 <translation id="6643649862576733715">Yadda saxlanmış data həcminə görə çeşidləyin</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
index 0ec34256..ba18a69 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Вылічэнне…</translation>
 <translation id="1383876407941801731">Пошук</translation>
 <translation id="1384704387250346179">Перакласці ў Аб'ектыве <ph name="BEGIN_NEW" />Навінка<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стылізаваць вылучанае</translation>
 <translation id="1386674309198842382">Апошнія дзеянні: <ph name="LAST_UPDATED" /> сут таму</translation>
 <translation id="1397811292916898096">Шукаць з дапамогай <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Не адсочваць"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" />, кнопка "<ph name="LINK_NAME" />"</translation>
 <translation id="2000419248597011803">Адпраўляе вашай стандартнай пошукавай сістэме некаторыя файлы cookie, а таксама пошукавыя запыты, уведзеныя ў адрасным радку і полі пошуку</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}one{# файл}few{# файлы}many{# файлаў}other{# файла}}</translation>
-<translation id="2017836877785168846">Ачышчае гісторыю і гісторыю аўтазапаўнення ў адрасным радку.</translation>
 <translation id="2021896219286479412">Кіраванне сайтам на ўвесь экран</translation>
 <translation id="2038563949887743358">Уключыць запытванне версіі для настольнага камп'ютара</translation>
 <translation id="2039379262107991683">Дадавайце старонкі ў Спіс на прагляд, каб атрымліваць пра іх напаміны</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Пошук праз Google Аб'ектыў <ph name="BEGIN_NEW" />Новае<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Адкрыць у новай укладцы</translation>
 <translation id="4198423547019359126">Няма месца для спампоўкі</translation>
-<translation id="4206707945726604465">Каб выдаліць гісторыю іншых дзеянняў, перайдзіце на старонку <ph name="BEGIN_LINK1" />Мае дзеянні ў Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Каб атрымліваць прапановы персаналізаванага змесціва ад Google, уключыце сінхранізацыю</translation>
 <translation id="4225895483398857530">Кнопка-ярлык на панэлі інструментаў</translation>
 <translation id="4242533952199664413">Адкрыць налады</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – ідзе спампоўванне…</translation>
 <translation id="4404568932422911380">Няма закладак</translation>
 <translation id="4405224443901389797">Перамясціць у…</translation>
+<translation id="4409271659088619928">Ваша пошукавая сістэма – <ph name="DSE" />. Каб выдаліць гісторыю пошуку, выканайце інструкцыі гэтай сістэмы (калі яны даступныя).</translation>
 <translation id="4411535500181276704">Спрошчаны рэжым</translation>
 <translation id="4415276339145661267">Кіраванне Уліковым запісам Google</translation>
 <translation id="4427306783828095590">Функцыя палепшанай абароны яшчэ надзейней блакіруе фішынг і шкодныя праграмы</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Праверыць паролі</translation>
 <translation id="6000066717592683814">Пакінуць Google</translation>
 <translation id="6000203700195075278">Падпісацца зноў</translation>
-<translation id="6002623704405939939">Каб выдаліць гісторыю <ph name="BEGIN_LINK1" />пошуку<ph name="END_LINK1" /> або іншых дзеянняў, перайдзіце ў <ph name="BEGIN_LINK2" />Мае дзеянні ў Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Прапанаваны пароль</translation>
 <translation id="6032091552407840792">Гэта пробная функцыя дзейнічае толькі ў <ph name="BEGIN_LINK" />некаторых рэгіёнах<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">З дапамогай <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> Chrome падтрымлівае адкрытасць інтэрнэту, распрацоўваючы новыя тэхналогіі для абароны вас ад механізмаў адсочвання паводзін на розных сайтах.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Павышае бяспеку для вас і іншых карыстальнікаў у інтэрнэце.</translation>
 <translation id="6618554661997243500">Каб прагледзець папулярныя сайты і падабраныя для вас артыкулы, націсніце кнопку "Галоўная старонка"</translation>
 <translation id="6627583120233659107">Рэдагаваць папку</translation>
-<translation id="6635718764393004944">Ваша пошукавая сістэма – <ph name="DSE" />. Каб выдаліць гісторыю пошуку, выканайце адпаведныя інструкцыі для гэтай сістэмы (калі яны даступныя).</translation>
 <translation id="663674369910034433">Дадатковыя налады прыватнасці, бяспекі і збору даных глядзіце ў раздзелах <ph name="BEGIN_LINK1" />Сінхранізацыя<ph name="END_LINK1" /> і <ph name="BEGIN_LINK2" />сэрвісы Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Ачысціць</translation>
 <translation id="6643649862576733715">Сартаваць па аб'ёме сэканомленага трафіка</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
index dfd09ada..c4a87b1 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Изчислява се…</translation>
 <translation id="1383876407941801731">Търсене</translation>
 <translation id="1384704387250346179">Превод с Google Обектив <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стилизиране на откроения текст</translation>
 <translation id="1386674309198842382">Активно преди <ph name="LAST_UPDATED" /> дни</translation>
 <translation id="1397811292916898096">Търсене чрез <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Заявка „Do Not Track“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> бутон „<ph name="LINK_NAME" />“</translation>
 <translation id="2000419248597011803">Изпраща някои „бисквитки“ и заявките за търсене от адресната лента и полето за търсене до стандартната ви търсеща машина</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}other{# файла}}</translation>
-<translation id="2017836877785168846">Изчиства историята и автоматичните довършвания в адресната лента.</translation>
 <translation id="2021896219286479412">Контроли за сайтове на цял екран</translation>
 <translation id="2038563949887743358">Включване на функцията за заявяване на настолни сайтове</translation>
 <translation id="2039379262107991683">Добавете страници към списъка си за четене, за да получите напомняне</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Търсене с Google Обектив <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Отваряне в нов раздел</translation>
 <translation id="4198423547019359126">Няма местоположения за изтегляне</translation>
-<translation id="4206707945726604465">За да изчистите другите видове история, посетете <ph name="BEGIN_LINK1" />Моята активност в Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Включете синхронизирането, за да получавате персонализирано съдържание, предлагано от Google</translation>
 <translation id="4225895483398857530">Пряк път в лентата с инструменти</translation>
 <translation id="4242533952199664413">Отваряне на настройките</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – изтегля се…</translation>
 <translation id="4404568932422911380">Няма отметки</translation>
 <translation id="4405224443901389797">Преместване във…</translation>
+<translation id="4409271659088619928">Търсещата ви машина е <ph name="DSE" />. Вижте инструкциите ѝ относно изтриването на историята на търсенията ви (ако е приложимо).</translation>
 <translation id="4411535500181276704">Олекотен режим</translation>
 <translation id="4415276339145661267">Управление на профила ви в Google</translation>
 <translation id="4427306783828095590">Режимът за подобрена защита предприема повече действия за блокиране на фишинг атаки и злонамерен софтуер</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Проверка на паролите</translation>
 <translation id="6000066717592683814">Запазване на Google</translation>
 <translation id="6000203700195075278">Повторно следене</translation>
-<translation id="6002623704405939939">За да изчистите историята на <ph name="BEGIN_LINK1" />търсенията<ph name="END_LINK1" /> или друг вид история, посетете <ph name="BEGIN_LINK2" />Моята активност в Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Предложена парола</translation>
 <translation id="6032091552407840792">Този експеримент е активен само в <ph name="BEGIN_LINK" />някои региони<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Чрез <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> Chrome разработва нови технологии, за да ви предпазва от проследяване в различни сайтове, съхранявайки отворената мрежа.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Подобрява сигурността за вас и всички потребители в мрежата.</translation>
 <translation id="6618554661997243500">За да видите водещите сайтове и материали за вас, докоснете бутона „Начало“</translation>
 <translation id="6627583120233659107">Редактиране на папката</translation>
-<translation id="6635718764393004944">Търсещата ви машина е <ph name="DSE" />. Ако е приложимо, вижте съответните инструкции, за да изтриете историята на търсенията си.</translation>
 <translation id="663674369910034433">За още настройки за поверителността, сигурността и събирането на данни вижте <ph name="BEGIN_LINK1" />Синхронизиране<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />услуги на Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Изчистване</translation>
 <translation id="6643649862576733715">Сортирайте по количество спестени данни</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
index b25fc22..cd537d7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">গণনা করছে...</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lens <ph name="BEGIN_NEW" />নতুন<ph name="END_NEW" />-এর সাহায্যে ছবি অনুবাদ করুন</translation>
-<translation id="1385855801883526502">হাইলাইট আরও স্টাইলিশ করে তুলুন</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> দিন আগে ব্যবহার করা হয়েছে</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> এর সাহায্যে খুঁজুন</translation>
 <translation id="1406000523432664303">"ট্র্যাক করবেন না"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> বোতাম</translation>
 <translation id="2000419248597011803">অ্যাড্রেস বার এবং সার্চ বক্স থেকে সার্চের তথ্য এবং কিছু কুকি আপনার ডিফল্ট সার্চ ইঞ্জিনে পাঠায়</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{#টি ফাইল}one{#টি ফাইল}other{#টি ফাইল}}</translation>
-<translation id="2017836877785168846">অ্যাড্রেস বার থেকে ইতিহাস ও অটোকমপ্লিট মুছে ফেলে।</translation>
 <translation id="2021896219286479412">পূর্ণ স্ক্রিন সাইট নিয়ন্ত্রণ</translation>
 <translation id="2038563949887743358">ডেস্কটপ সাইটের অনুরোধ চালু করুন</translation>
 <translation id="2039379262107991683">রিমাইন্ডার পাওয়ার জন্য আপনার পড়ার তালিকায় পৃষ্ঠা যোগ করুন</translation>
@@ -493,7 +491,6 @@
 <translation id="4183868528246477015">Google Lens-এর <ph name="BEGIN_NEW" />নতুন<ph name="END_NEW" /> ভার্সন দিয়ে খুুঁজুন</translation>
 <translation id="4195643157523330669">নতুন ট্যাবে খুলুন</translation>
 <translation id="4198423547019359126">ডাউনলোড করার জন্য লোকেশন উপলভ্য নেই</translation>
-<translation id="4206707945726604465">অন্যান্য ধরনের ইতিহাস মুছতে, <ph name="BEGIN_LINK1" />আমার Google অ্যাক্টিভিটি<ph name="END_LINK1" /> দেখুন</translation>
 <translation id="4209895695669353772">Google-এর প্রস্তাবিত ব্যক্তিগতকৃত কন্টেন্ট পেতে সিঙ্ক বিকল্প চালু করুন</translation>
 <translation id="4225895483398857530">টুলবারের শর্টকার্ট</translation>
 <translation id="4242533952199664413">সেটিংস খুলুন</translation>
@@ -517,6 +514,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ডাউনলোড করা হচ্ছে…</translation>
 <translation id="4404568932422911380">কোনও বুকমার্ক নেই</translation>
 <translation id="4405224443901389797">এই ফোল্ডারে সরান…</translation>
+<translation id="4409271659088619928">আপনার সার্চ ইঞ্জিনের নাম হল, <ph name="DSE" />। এক্ষেত্রে প্রযোজ্য হলে, আপনার সার্চ ইতিহাস মোছার জন্য সেটির নির্দেশাবলী দেখুন।</translation>
 <translation id="4411535500181276704">লাইট মোড</translation>
 <translation id="4415276339145661267">আপনার Google অ্যাকাউন্ট ম্যানেজ করুন</translation>
 <translation id="4427306783828095590">ফিশিং ও ম্যালওয়্যার ব্লক করার ব্যাপারে উন্নত সুরক্ষা আরও সাহায্য করে</translation>
@@ -776,7 +774,6 @@
 <translation id="5979084224081478209">পাসওয়ার্ড চেক করুন</translation>
 <translation id="6000066717592683814">Google কে রাখুন</translation>
 <translation id="6000203700195075278">আবার ফলো করুন</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />সার্চ<ph name="END_LINK1" /> বা অন্যান্য ধরনের অ্যাক্টিভিটির ইতিহাস মুছে দিতে হলে, <ph name="BEGIN_LINK2" />আমার Google অ্যাক্টিভিটি<ph name="END_LINK2" /> দেখুন</translation>
 <translation id="6005538289190791541">প্রস্তাবিত পাসওয়ার্ড</translation>
 <translation id="6032091552407840792">এই ট্রায়াল শুধুমাত্র <ph name="BEGIN_LINK" />কিছু অঞ্চলে<ph name="END_LINK" /> অ্যাক্টিভ আছে।</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />প্রাইভেসি স্যান্ডবক্স<ph name="END_LINK" />-এর সাহায্যে 'Chrome' এক নতুন প্রযুক্তি তৈরি করছে। এটি ওপেন ওয়েব সুরক্ষিত করার মাধ্যমে আপনাকে ক্রস-সাইট ট্র্যাক করা থেকে রক্ষা করে।
@@ -855,6 +852,7 @@
 <translation id="6441734959916820584">নামটি অত্যন্ত দীর্ঘ</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{#টি ছবি}one{#টি ছবি}other{#টি ছবি}}</translation>
 <translation id="6447558397796644647">এই বুকমার্কটি খুঁজে পাওয়া যাচ্ছে না। আপনার লেখা বানান চেক করুন অথবা একটি নতুন বুকমার্ক যোগ করুন।</translation>
+<translation id="6459045781120991510">সমীক্ষা</translation>
 <translation id="6461962085415701688">ফাইল খোলা যাচ্ছে না</translation>
 <translation id="6464977750820128603">Chrome-এ দেখা সাইটগুলি আপনি দেখতে পাবেন এবং সাইটগুলিতে টাইমার সেট করতে পারবেন।\n\nযে সমস্ত সাইটে টাইমার সেট করেছেন বা কত সময় ধরে সাইটটি দেখেছেন তার সমস্ত তথ্য Google-এর কাছে যায়। ডিজিটাল ওয়েলবিং-কে আরও উন্নত করতে এই তথ্য ব্যবহার করা হয়।</translation>
 <translation id="6475951671322991020">ভিডিও ডাউনলোড করুন</translation>
@@ -887,7 +885,6 @@
 <translation id="661266467055912436">ওয়েবে আপনার এবং সকলের জন্য নিরাপত্তা আরও উন্নত করুন।</translation>
 <translation id="6618554661997243500">আপনার জন্য বেছে নেওয়া সেরা সাইট ও খবর দেখতে 'হোম' বোতাম টিপুন</translation>
 <translation id="6627583120233659107">ফোল্ডার সম্পাদনা করুন</translation>
-<translation id="6635718764393004944">আপনার সার্চ ইঞ্জিন হল, <ph name="DSE" />। এক্ষেত্রে প্রযোজ্য হলে, আপনার সার্চ ইতিহাস মুছে ফেলতে তাদের নির্দেশাবলী দেখুন।</translation>
 <translation id="663674369910034433">আপনার গোপনীয়তা, নিরাপত্তা ও ডেটা সংগ্রহের সাথে সম্পর্কিত আরও সেটিংসের জন্য <ph name="BEGIN_LINK1" />সিঙ্ক<ph name="END_LINK1" /> এবং <ph name="BEGIN_LINK2" />Google পরিষেবা<ph name="END_LINK2" /> দেখুন</translation>
 <translation id="6643016212128521049">সাফ করুন</translation>
 <translation id="6643649862576733715">সেভ করা ডেটার পরিমাণ অনুযায়ী সাজান</translation>
@@ -971,6 +968,7 @@
 <translation id="7242755609445462077">স্টাইলযুক্ত হাইলাইট <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Chrome-এ <ph name="TARGET_DEVICE_NAME" /> সিঙ্ক করার ফিচার চালু করে রেখেছেন কিনা দেখে নিন।</translation>
 <translation id="7252076891734325316">ফোনকে কম্পিউটারের কাছাকাছি নিয়ে আসুন</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" />-এ <ph name="ONE_TIME_CODE" /> জমা করতে চান?</translation>
 <translation id="7274013316676448362">অবরুদ্ধ সাইট</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> পরিবর্তন করবেন?</translation>
 <translation id="7290209999329137901">আবার নামকরণের বিকল্পটি উপলভ্য নেই</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
index af3a8a0..38b47a5 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Računanje…</translation>
 <translation id="1383876407941801731">Traži</translation>
 <translation id="1384704387250346179">Prevedi sliku Google Objektivom <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stiliziraj istaknutu stavku</translation>
 <translation id="1386674309198842382">Aktivan prije <ph name="LAST_UPDATED" /> dana</translation>
 <translation id="1397811292916898096">Pretražite pomoću proizvoda <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Bez praćenja"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Dugme <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Šalje neke kolačiće i pretraživanja s trake za adresu i iz okvira za pretraživanje vašem zadanom pretraživaču</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fajl}one{# fajl}few{# fajla}other{# fajlova}}</translation>
-<translation id="2017836877785168846">Briše historiju i automatsko dovršavanje na traci za adresu.</translation>
 <translation id="2021896219286479412">Kontr. web lok. na cijelom ekr.</translation>
 <translation id="2038563949887743358">Uključivanje zahtjeva za verziju web lokacije za računar</translation>
 <translation id="2039379262107991683">Dodajte stranice na Listu za čitanje da primite podsjetnik</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Jezici</translation>
 <translation id="4183868528246477015">Pretraživanje uz Google Objektiv <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otvori u novoj kartici</translation>
+<translation id="4196597275619698563">Izradi karticu</translation>
 <translation id="4198423547019359126">Nema dostupnih lokacija za preuzimanje</translation>
-<translation id="4206707945726604465">Da obrišete druge oblike historije, posjetite <ph name="BEGIN_LINK1" />Moje aktivnosti na Googleu<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Uključite sinhronizaciju da dobijete prilagođeni sadržaj koji predlaže Google</translation>
 <translation id="4225895483398857530">Prečica za alatnu traku</translation>
 <translation id="4242533952199664413">Otvori postavke</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Preuzimanje…</translation>
 <translation id="4404568932422911380">Nema oznaka</translation>
 <translation id="4405224443901389797">Premjesti u…</translation>
+<translation id="4409271659088619928">Vaš pretraživač je <ph name="DSE" />. Ako je primjenjivo, pogledajte uputstva pretraživača da saznate kako izbrisati historiju pretraživanja.</translation>
 <translation id="4411535500181276704">Jednostavni način rada</translation>
 <translation id="4415276339145661267">Upravljajte Google računom</translation>
 <translation id="4427306783828095590">Poboljšana zaštita vas još bolje čuva od krađe identiteta i zlonamjernog softvera</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">Provjeri lozinke</translation>
 <translation id="6000066717592683814">Zadrži Google</translation>
 <translation id="6000203700195075278">Prati ponovo</translation>
-<translation id="6002623704405939939">Da obrišete <ph name="BEGIN_LINK1" />pretraživanje<ph name="END_LINK1" /> ili druge oblike historije, posjetite <ph name="BEGIN_LINK2" />Moju aktivnost na Googleu<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Prijedlog za lozinku</translation>
 <translation id="6032091552407840792">Ovaj probni period je aktivan samo u <ph name="BEGIN_LINK" />određenim regijama<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Pomoću <ph name="BEGIN_LINK" />Okruženja zaštićene privatnosti<ph name="END_LINK" />, Chrome razvija nove tehnologije da vas zaštiti od praćenja između web lokacija, a pri tome će očuvati otvoreni web.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">Poboljšava vašu i svačiju sigurnost na webu.</translation>
 <translation id="6618554661997243500">Da pogledate najpopularnije web lokacije i priče prilagođene vama, dodirnite dugme za početni ekran</translation>
 <translation id="6627583120233659107">Uredi folder</translation>
-<translation id="6635718764393004944">Vaš pretraživač je <ph name="DSE" />. Ako je primjenjivo, pogledajte upute pretraživača da izbrišete historiju pretraživanja.</translation>
 <translation id="663674369910034433">Više postavki koje se odnose na privatnost, sigurnost i prikupljanje podataka možete pronaći u odjeljcima <ph name="BEGIN_LINK1" />Sinhronizacija<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />Googleove usluge<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Obriši</translation>
 <translation id="6643649862576733715">Sortiraj po iznosu sačuvanih podataka</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">Automatsko dovršavanje pretraživanja i URL-ova</translation>
 <translation id="7707922173985738739">Koristi prijenos podataka na mobilnoj mreži</translation>
 <translation id="7725024127233776428">Stranice koje označite će se pojaviti ovdje</translation>
+<translation id="7731260005404856143"><ph name="BEGIN_LINK1" />Ostali oblici aktivnosti<ph name="END_LINK1" /> mogu se spremati na vaš Google račun kad ste prijavljeni. Možete ih izbrisati kad god želite.</translation>
 <translation id="7757787379047923882">Tekst je podijeljen s uređaja <ph name="DEVICE_NAME" /></translation>
 <translation id="7761849928583394409">Odaberite datum i vrijeme</translation>
 <translation id="7762668264895820836">SD kartica <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">Pregledajte fajlove van mreže</translation>
 <translation id="8856607253650333758">Preuzmi opise</translation>
 <translation id="8873817150012960745">Dodirnite ovdje da započnete</translation>
+<translation id="8881973373982641723">Briše povijest, uključujući u okviru za pretraživanje.</translation>
 <translation id="889338405075704026">Idi u postavke Chromea</translation>
 <translation id="8898822736010347272">Šalje Googleu URL-ove nekih stranica koje posjetite, ograničene informacije sistema i sadržaj nekih stranica radi lakšeg otkrivanja novih prijetnji te zaštite svakoga na webu.</translation>
 <translation id="8909135823018751308">Dijeljenje…</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">Upućivanje poziva nije moguće</translation>
 <translation id="9212845824145208577">Nije moguće pomjeriti niže. Pokušajte započeti na nižem mjestu na stranici.</translation>
 <translation id="9219103736887031265">Slike</translation>
+<translation id="923957533152125119"><ph name="BEGIN_LINK1" />Povijest pretraživanja<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />drugi oblici aktivnosti<ph name="END_LINK2" /> mogu se spremati na vaš Google račun kad ste prijavljeni. Možete ih izbrisati kad god želite.</translation>
 <translation id="926205370408745186">Uklonite aktivnosti Chromea iz Digitalnog blagostanja</translation>
 <translation id="927968626442779827">Koristite Jednostavni način rada na Google Chromeu</translation>
 <translation id="932327136139879170">Dom</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
index 6f5f7e6..cbd43dac 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">S'està calculant…</translation>
 <translation id="1383876407941801731">Cerca</translation>
 <translation id="1384704387250346179">Tradueix la imatge amb Lens <ph name="BEGIN_NEW" />Novetat<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Estilitza l'element destacat</translation>
 <translation id="1386674309198842382">Actiu fa <ph name="LAST_UPDATED" /> dies</translation>
 <translation id="1397811292916898096">Cerca amb <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">No segueixis</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> (botó <ph name="LINK_NAME" />)</translation>
 <translation id="2000419248597011803">Envia al motor de cerca predeterminat algunes galetes i cerques de la barra d'adreces i del quadre de cerca</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fitxer}other{# fitxers}}</translation>
-<translation id="2017836877785168846">Esborra l'historial i les complecions automàtiques a la barra d'adreces.</translation>
 <translation id="2021896219286479412">Controls de pantalla completa</translation>
 <translation id="2038563949887743358">Activa Mostra com a ordinador</translation>
 <translation id="2039379262107991683">Afegeix pàgines a la teva llista de lectura per rebre un recordatori</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Cerca amb Google Lens <ph name="BEGIN_NEW" />Novetat<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Obre en una pestanya nova</translation>
 <translation id="4198423547019359126">No hi ha cap ubicació de baixada disponible</translation>
-<translation id="4206707945726604465">Per suprimir altres formes de l'historial, visita <ph name="BEGIN_LINK1" />La meva activitat a Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Perquè Google et suggereixi contingut personalitzat, activa la sincronització</translation>
 <translation id="4225895483398857530">Drecera de la barra d'eines</translation>
 <translation id="4242533952199664413">Obre la configuració</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: s'està baixant…</translation>
 <translation id="4404568932422911380">Cap adreça d'interès</translation>
 <translation id="4405224443901389797">Mou a…</translation>
+<translation id="4409271659088619928">El teu motor de cerca és <ph name="DSE" />. Consulta'n les instruccions per suprimir l'historial de cerques, si escau.</translation>
 <translation id="4411535500181276704">Mode bàsic</translation>
 <translation id="4415276339145661267">Gestiona el teu Compte de Google</translation>
 <translation id="4427306783828095590">La protecció millorada és més efiçaç a l'hora de bloquejar la pesca de credencials i el programari maliciós</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Comprova les contrasenyes</translation>
 <translation id="6000066717592683814">Continua amb Google</translation>
 <translation id="6000203700195075278">Torna a seguir</translation>
-<translation id="6002623704405939939">Per esborrar la <ph name="BEGIN_LINK1" />cerca<ph name="END_LINK1" /> o altres formes de l'historial, visita <ph name="BEGIN_LINK2" />La meva activitat a Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Contrasenya suggerida</translation>
 <translation id="6032091552407840792">Aquesta prova només està activa en <ph name="BEGIN_LINK" />algunes regions<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Amb <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome està desenvolupant noves tecnologies per protegir-te dels mecanismes de seguiment entre llocs web, alhora que preserva el web obert.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Millora la seguretat per a tu i per a tots els usuaris del web.</translation>
 <translation id="6618554661997243500">Per consultar els llocs web i les històries que més visites, toca el botó d'inici</translation>
 <translation id="6627583120233659107">Edita la carpeta</translation>
-<translation id="6635718764393004944">El teu motor de cerca és <ph name="DSE" />. Si és necessari, consulta les seves instruccions per suprimir l'historial de cerques.</translation>
 <translation id="663674369910034433">Per trobar més opcions de configuració relacionades amb la privadesa, la seguretat i la recollida de dades, consulta <ph name="BEGIN_LINK1" />Sincronització<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />serveis de Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Esborra</translation>
 <translation id="6643649862576733715">Ordena per quantitat de dades estalviades</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
index c6b097a..752ec2f4 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Probíhá výpočet…</translation>
 <translation id="1383876407941801731">Vyhledávání</translation>
 <translation id="1384704387250346179">Přeložit obrázek pomocí Google Lens <ph name="BEGIN_NEW" />Nové<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stylizovat zvýraznění</translation>
 <translation id="1386674309198842382">Aktivní před tímto počtem dní: <ph name="LAST_UPDATED" /></translation>
 <translation id="1397811292916898096">Hledat pomocí vyhledávače <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Do Not Track (Nesledovat)</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> tlačítko <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Odesílá soubory cookie a vyhledávací dotazy z adresního řádku a vyhledávacího pole a několik souborů cookie vašemu výchozímu vyhledávači</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# soubor}few{# soubory}many{# souboru}other{# souborů}}</translation>
-<translation id="2017836877785168846">Vymaže historii a automatická dokončení v adresním řádku.</translation>
 <translation id="2021896219286479412">Ovládání webu na celé obrazovce</translation>
 <translation id="2038563949887743358">Zapnout funkci Verze webu pro PC</translation>
 <translation id="2039379262107991683">Chcete-li dostat připomenutí, přidejte si stránky na Seznam četby</translation>
@@ -236,7 +234,7 @@
 <translation id="250020030759455918">Uvidíte stav přihlášení, údaje o prohlížení a data webu <ph name="SITE_NAME" /> v Chromu</translation>
 <translation id="2512164632052122970">Jazyky obsahu</translation>
 <translation id="2513403576141822879">Další nastavení související s ochranou soukromí, zabezpečením a shromažďováním dat naleznete v části <ph name="BEGIN_LINK" />Synchronizace a služby Google<ph name="END_LINK" /></translation>
-<translation id="2517472476991765520">Vyhledat</translation>
+<translation id="2517472476991765520">Naskenovat</translation>
 <translation id="2518590038762162553">Ve zjednodušeném režimu načítá Chrome stránky rychleji a používá až o 60 procent méně dat. Kvůli optimalizaci navštěvovaných stránek přijímá Chrome váš webový provoz přes Google. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation>
 <translation id="2523184218357549926">Odesílá do Googlu adresy URL stránek, které navštěvujete</translation>
 <translation id="2527497042232966453">Přepnuto na anonymní karty</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Hledat pomocí Google Lens <ph name="BEGIN_NEW" />Nové<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otevřít na nové kartě</translation>
 <translation id="4198423547019359126">Nejsou k dispozici žádná umístění stažených souborů</translation>
-<translation id="4206707945726604465">Pokud chcete vymazat jiné formy historie, navštivte <ph name="BEGIN_LINK1" />Moji aktivitu na Googlu<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Chcete-li od Googlu získat personalizované návrhy obsahu, zapněte synchronizaci</translation>
 <translation id="4225895483398857530">Zkratka lišty</translation>
 <translation id="4242533952199664413">Otevřít Nastavení</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Stahování…</translation>
 <translation id="4404568932422911380">Žádné záložky</translation>
 <translation id="4405224443901389797">Přesunout do…</translation>
+<translation id="4409271659088619928">Váš vyhledávač je <ph name="DSE" />. Prostudujte si pokyny vyhledávače pro smazání historie vyhledávání (pokud je k dispozici).</translation>
 <translation id="4411535500181276704">Zjednodušený režim</translation>
 <translation id="4415276339145661267">Spravovat účet Google</translation>
 <translation id="4427306783828095590">Vylepšená ochrana vás lépe ochrání před phishingem a malwarem</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Zkontrolovat hesla</translation>
 <translation id="6000066717592683814">Ponechat Google</translation>
 <translation id="6000203700195075278">Znovu sledovat</translation>
-<translation id="6002623704405939939">Pokud chcete vymazat <ph name="BEGIN_LINK1" />vyhledávání<ph name="END_LINK1" /> nebo jiné formy historie, přejděte na stránku <ph name="BEGIN_LINK2" />Moje aktivita na Googlu<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Navrhované heslo</translation>
 <translation id="6032091552407840792">Tato zkušební funkce je k dispozici pouze v <ph name="BEGIN_LINK" />některých oblastech<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">V rámci sady <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> vyvíjí tým Chrome nové technologie, které uživatele chrání před sledováním mezi weby a přitom zachovávají otevřenost webu.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Zlepšuje bezpečnost pro vás i všechny ostatní uživatele internetu.</translation>
 <translation id="6618554661997243500">Chcete-li zobrazit své top weby a příběhy, klepněte na tlačítko domovské stránky</translation>
 <translation id="6627583120233659107">Upravit složku</translation>
-<translation id="6635718764393004944">Váš vyhledávač je <ph name="DSE" />. Prostudujte si pokyny k vymazání historie vyhledávání v příslušném vyhledávači.</translation>
 <translation id="663674369910034433">Další nastavení související s ochranou soukromí, zabezpečením a shromažďováním dat najdete v částech <ph name="BEGIN_LINK1" />Synchronizace<ph name="END_LINK1" /> a <ph name="BEGIN_LINK2" />Služby Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Vymazat</translation>
 <translation id="6643649862576733715">Seřadit podle množství uspořených dat</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
index 84e8a7d..1852651a7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Beregner…</translation>
 <translation id="1383876407941801731">Søg</translation>
 <translation id="1384704387250346179">Oversæt billedet med Google Lens <ph name="BEGIN_NEW" />Nyhed<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stiliser fremhævning</translation>
 <translation id="1386674309198842382">Aktiv for <ph name="LAST_UPDATED" /> dage siden</translation>
 <translation id="1397811292916898096">Søg med <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Do Not Track"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knap</translation>
 <translation id="2000419248597011803">Sender visse cookies og søgninger fra adresselinjen og søgefeltet til din standardsøgemaskine</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fil}one{# fil}other{# filer}}</translation>
-<translation id="2017836877785168846">Nulstiller historikken og autofuldførelser i adresselinjen.</translation>
 <translation id="2021896219286479412">Kontrolelementer på website i fuld skærm</translation>
 <translation id="2038563949887743358">Slå computerversionen af websitet til</translation>
 <translation id="2039379262107991683">Føj sider til din læseliste, så du kan få en påmindelse</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Søg med Google Lens <ph name="BEGIN_NEW" />Nyhed<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Åbn på ny fane</translation>
 <translation id="4198423547019359126">Der er ingen tilgængelige downloadplaceringer</translation>
-<translation id="4206707945726604465">Du kan rydde andre typer historik ved at gå til <ph name="BEGIN_LINK1" />Min Google-aktivitet<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Aktivér synkronisering for at hente brugertilpasset indhold, som er foreslået af Google</translation>
 <translation id="4225895483398857530">Genvej til værktøjslinje</translation>
 <translation id="4242533952199664413">Åbn Indstillinger</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Downloader…</translation>
 <translation id="4404568932422911380">Der er ingen bogmærker</translation>
 <translation id="4405224443901389797">Flyt til…</translation>
+<translation id="4409271659088619928">Dine standardsøgemaskine er <ph name="DSE" />. Se din søgemaskines vejledning i, hvordan du sletter din søgehistorik, hvis det er relevant.</translation>
 <translation id="4411535500181276704">Lite-tilstand</translation>
 <translation id="4415276339145661267">Administrer din Google-konto</translation>
 <translation id="4427306783828095590">Forbedret beskyttelse gør mere end at blokere phishing og malware</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Tjek adgangskoder</translation>
 <translation id="6000066717592683814">Behold Google</translation>
 <translation id="6000203700195075278">Følg igen</translation>
-<translation id="6002623704405939939">Du kan rydde dine <ph name="BEGIN_LINK1" />søgninger<ph name="END_LINK1" /> eller andre former for historik ved at gå til <ph name="BEGIN_LINK2" />Min Google-aktivitet<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Foreslået adgangskode</translation>
 <translation id="6032091552407840792">Denne prøveperiode er kun aktiv i <ph name="BEGIN_LINK" />nogle områder<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Med <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> udvikler Chrome nye teknologier, der beskytter dig mod sporing på tværs af forskellige websites og samtidig bevarer det åbne net.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Forbedrer din og alles sikkerhed på nettet.</translation>
 <translation id="6618554661997243500">Tryk på knappen Hjem for at se de mest anvendte websites og anbefalede artikler</translation>
 <translation id="6627583120233659107">Rediger mappen</translation>
-<translation id="6635718764393004944">Dine standardsøgemaskine er <ph name="DSE" />. Se evt. vejledningen til denne søgemaskine for at slette din søgehistorik.</translation>
 <translation id="663674369910034433">Du kan finde flere indstillinger vedrørende privatliv, sikkerhed og dataindsamling under <ph name="BEGIN_LINK1" />Synkronisering<ph name="END_LINK1" /> og <ph name="BEGIN_LINK2" />Google-tjenester<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Ryd</translation>
 <translation id="6643649862576733715">Sortér efter mængden af data, der blev sparet</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
index 710a7d72..386e7ed 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Berechnung läuft...</translation>
 <translation id="1383876407941801731">Durchsuchen</translation>
 <translation id="1384704387250346179">Bild mit Google Lens übersetzen <ph name="BEGIN_NEW" />Neu<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Markierung stilisieren</translation>
 <translation id="1386674309198842382">Vor <ph name="LAST_UPDATED" /> Tagen aktiv</translation>
 <translation id="1397811292916898096">Mit <ph name="PRODUCT_NAME" /> suchen</translation>
 <translation id="1406000523432664303">„Do Not Track“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> – Schaltfläche "<ph name="LINK_NAME" />"</translation>
 <translation id="2000419248597011803">Suchanfragen, die in die Adressleiste und das Suchfeld eingegeben wurden, sowie einige Cookies werden an Ihre Standardsuchmaschine gesendet</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Datei}other{# Dateien}}</translation>
-<translation id="2017836877785168846">Löscht den Verlauf sowie Autovervollständigungen in der Adressleiste.</translation>
 <translation id="2021896219286479412">Vollbild-Steuerelemente</translation>
 <translation id="2038563949887743358">"Desktopversion ansehen" aktivieren</translation>
 <translation id="2039379262107991683">Sie können Ihrer Leseliste Seiten hinzufügen, um eine Erinnerung zu erhalten</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Mit Google Lens suchen <ph name="BEGIN_NEW" />Neu<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">In neuem Tab öffnen</translation>
 <translation id="4198423547019359126">Keine verfügbaren Speicherorte für Downloads</translation>
-<translation id="4206707945726604465">Unter <ph name="BEGIN_LINK1" />Meine Google-Aktivitäten<ph name="END_LINK1" /> können Sie andere Verläufe löschen</translation>
 <translation id="4209895695669353772">Aktivieren Sie die Synchronisierung, um personalisierte, von Google vorgeschlagene Inhalte zu erhalten</translation>
 <translation id="4225895483398857530">Tastenkürzel in Symbolleiste</translation>
 <translation id="4242533952199664413">Einstellungen öffnen</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – wird heruntergeladen…</translation>
 <translation id="4404568932422911380">Keine Lesezeichen</translation>
 <translation id="4405224443901389797">Verschieben nach…</translation>
+<translation id="4409271659088619928">Sie haben <ph name="DSE" /> als Suchmaschine festgelegt. Informationen zum Löschen Ihres Suchverlaufs finden Sie in der zugehörigen Anleitung.</translation>
 <translation id="4411535500181276704">Lite-Modus</translation>
 <translation id="4415276339145661267">Google-Konto verwalten</translation>
 <translation id="4427306783828095590">Besserer Schutz vor Phishing und Malware durch erweitertes Safe Browsing</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Passwörter prüfen</translation>
 <translation id="6000066717592683814">Google beibehalten</translation>
 <translation id="6000203700195075278">Wieder folgen</translation>
-<translation id="6002623704405939939">Unter <ph name="BEGIN_LINK2" />Meine Google-Aktivitäten<ph name="END_LINK2" /> können Sie Verläufe wie den <ph name="BEGIN_LINK1" />Suchverlauf<ph name="END_LINK1" /> löschen</translation>
 <translation id="6005538289190791541">Vorgeschlagenes Passwort</translation>
 <translation id="6032091552407840792">Diese Testversion ist probeweise nur in <ph name="BEGIN_LINK" />ausgewählten Regionen verfügbar<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Im Rahmen der Initiative <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> werden neue Technologien entwickelt, die zum Schutz vor websiteübergreifenden Tracking-Mechanismen und zum Erhalt des offenen Webs beitragen.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">Name ist zu lang</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# Bild}other{# Bilder}}</translation>
 <translation id="6447558397796644647">Das Lesezeichen wurde nicht gefunden. Prüfen Sie die Schreibweise oder fügen Sie ein neues Lesezeichen hinzu.</translation>
+<translation id="6459045781120991510">Umfragen</translation>
 <translation id="6461962085415701688">Datei kann nicht geöffnet werden</translation>
 <translation id="6464977750820128603">Sie sehen in Chrome besuchte Websites und können Timer einstellen.\n\nGoogle erhält Informationen zu den Websites, für die Sie Timer einstellen, sowie zur Dauer des Besuchs. Anhand dieser Informationen wird Digital Wellbeing optimiert.</translation>
 <translation id="6475951671322991020">Video herunterladen</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Verbessert die Sicherheit für Sie und alle im Internet.</translation>
 <translation id="6618554661997243500">Auf die Schaltfläche "Startseite" tippen, um Ihre Top-Websites und Meldungen aufzurufen</translation>
 <translation id="6627583120233659107">Ordner bearbeiten</translation>
-<translation id="6635718764393004944">Sie haben <ph name="DSE" /> als Suchmaschine festgelegt. Informationen zum Löschen Ihres Suchverlaufs finden Sie ggf. in der Anleitung der Suchmaschine.</translation>
 <translation id="663674369910034433">Weitere Einstellungen in Verbindung mit Datenschutz, Sicherheit und der Erhebung von Daten finden Sie unter <ph name="BEGIN_LINK1" />Synchronisierung<ph name="END_LINK1" /> und <ph name="BEGIN_LINK2" />Google-Dienste<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Löschen</translation>
 <translation id="6643649862576733715">Nach Menge der gespeicherten Daten sortieren</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">Stilisierte Markierung <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Prüfen Sie, ob auf <ph name="TARGET_DEVICE_NAME" /> die Synchronisierung in Chrome aktiviert ist</translation>
 <translation id="7252076891734325316">Platzieren Sie Ihr Smartphone möglichst nah am Computer</translation>
+<translation id="727288900855680735"><ph name="ONE_TIME_CODE" /> an <ph name="ORIGIN" /> senden?</translation>
 <translation id="7274013316676448362">Blockierte Website</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> ändern?</translation>
 <translation id="7290209999329137901">Umbenennen nicht verfügbar</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
index b55231a..c3626a2f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Υπολογισμός…</translation>
 <translation id="1383876407941801731">Αναζήτηση</translation>
 <translation id="1384704387250346179">Μετάφραση εικόνας με Lens <ph name="BEGIN_NEW" />Νέο<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Επισήμανση στιλιζαρίσματος</translation>
 <translation id="1386674309198842382">Ενεργή <ph name="LAST_UPDATED" /> ημέρες πριν</translation>
 <translation id="1397811292916898096">Αναζήτηση με <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Να μην γίνεται εντοπισμός"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Κουμπί <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Στέλνει ορισμένα cookie και αναζητήσεις από τη γραμμή διευθύνσεων και το πλαίσιο αναζήτησης στην προεπιλεγμένη μηχανή αναζήτησης</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Αρχείο}other{# Αρχεία}}</translation>
-<translation id="2017836877785168846">Διαγράφει το ιστορικό και τις αυτόματες συμπληρώσεις στη γραμμή διευθύνσεων.</translation>
 <translation id="2021896219286479412">Στοιχ. ελέγ. σε πλήρη οθόνη</translation>
 <translation id="2038563949887743358">Ενεργοποίηση αιτήματος ιστότοπου για υπολογιστές</translation>
 <translation id="2039379262107991683">Προσθέστε σελίδες στη Λίστα ανάγνωσης για να λάβετε μια υπενθύμιση.</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Αναζήτηση με Google Lens <ph name="BEGIN_NEW" />Νέο<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Άνοιγμα σε νέα καρτέλα</translation>
 <translation id="4198423547019359126">Δεν υπάρχουν διαθέσιμες τοποθεσίες λήψης</translation>
-<translation id="4206707945726604465">Για να διαγράψετε άλλες μορφές ιστορικού, επισκεφτείτε τη διεύθυνση <ph name="BEGIN_LINK1" />Η δραστηριότητά μου Google<ph name="END_LINK1" />.</translation>
 <translation id="4209895695669353772">Για λήψη εξατομικευμένου περιεχομένου που προτείνεται από την Google, ενεργοποιήστε τον συγχρονισμό</translation>
 <translation id="4225895483398857530">Συντόμευση γραμμής εργαλείων</translation>
 <translation id="4242533952199664413">Ανοίξτε τις ρυθμίσεις</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Λήψη…</translation>
 <translation id="4404568932422911380">Δεν υπάρχουν σελιδοδείκτες</translation>
 <translation id="4405224443901389797">Μετακίνηση σε…</translation>
+<translation id="4409271659088619928">Χρησιμοποιείτε τη μηχανή αναζήτησης <ph name="DSE" />. Ανατρέξτε στις οδηγίες για διαγραφή του ιστορικού αναζήτησής σας, εφόσον υπάρχουν.</translation>
 <translation id="4411535500181276704">Λειτουργία Lite</translation>
 <translation id="4415276339145661267">Διαχείριση Λογαριασμού Google</translation>
 <translation id="4427306783828095590">Η βελτιωμένη προστασία κάνει περισσότερα για τον αποκλεισμό ηλεκτρονικού ψαρέματος (phishing) και κακόβουλων προγραμμάτων</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Έλεγχος κωδικών πρόσβασης</translation>
 <translation id="6000066717592683814">Διατήρηση του Google</translation>
 <translation id="6000203700195075278">Ακολουθήστε ξανά</translation>
-<translation id="6002623704405939939">Για διαγραφή του ιστορικού <ph name="BEGIN_LINK1" />αναζήτησης<ph name="END_LINK1" /> ή άλλων μορφών ιστορικού, επισκεφτείτε την ενότητα <ph name="BEGIN_LINK2" />Η δραστηριότητά μου Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Προτεινόμενος κωδικός πρόσβασης</translation>
 <translation id="6032091552407840792">Αυτή η δοκιμή είναι ενεργή μόνο σε <ph name="BEGIN_LINK" />ορισμένες περιοχές<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Με το <ph name="BEGIN_LINK" />Πλαίσιο ιδιωτικότητας<ph name="END_LINK" />, το Chrome αναπτύσσει νέες τεχνολογίες για να σας προστατεύσει από την παρακολούθηση μεταξύ ιστοτόπων, διατηρώντας παράλληλα τον ανοικτό ιστό.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Βελτιώνει την ασφάλεια για εσάς και όλους στον ιστό.</translation>
 <translation id="6618554661997243500">Για να δείτε κορυφαίους ιστοτόπους και ειδήσεις για εσάς, πατήστε το κουμπί αρχικής οθόνης.</translation>
 <translation id="6627583120233659107">Επεξεργασία φακέλου</translation>
-<translation id="6635718764393004944">Χρησιμοποιείτε τη μηχανή αναζήτησης <ph name="DSE" />. Εάν θέλετε, ανατρέξτε στις οδηγίες της για να διαγράψετε το ιστορικό αναζήτησής σας.</translation>
 <translation id="663674369910034433">Για περισσότερες ρυθμίσεις που σχετίζονται με το απόρρητο, την ασφάλεια και τη συλλογή δεδομένων, ανατρέξτε στην ενότητα <ph name="BEGIN_LINK1" />Συγχρονισμός<ph name="END_LINK1" /> και <ph name="BEGIN_LINK2" />υπηρεσίες Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Διαγραφή</translation>
 <translation id="6643649862576733715">Ταξινόμηση κατά όγκο δεδομένων που εξοικονομήθηκαν</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
index 78a139d..05fa255 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Computing…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Translate image with Google Lens <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stylise highlight</translation>
 <translation id="1386674309198842382">Active <ph name="LAST_UPDATED" /> days ago</translation>
 <translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">‘Do Not Track’</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation>
 <translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# File}other{# Files}}</translation>
-<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation>
 <translation id="2021896219286479412">Full screen site controls</translation>
 <translation id="2038563949887743358">Turn on Request desktop site</translation>
 <translation id="2039379262107991683">Add pages to your reading list to get a reminder</translation>
@@ -398,6 +396,7 @@
 <translation id="3518985090088779359">Accept &amp; continue</translation>
 <translation id="3522247891732774234">Update available. More options</translation>
 <translation id="3524138585025253783">Developer UI</translation>
+<translation id="3524334353996115845">Let <ph name="ORIGIN" /> verify that it's you</translation>
 <translation id="3527085408025491307">Folder</translation>
 <translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation>
 <translation id="3549657413697417275">Search your history</translation>
@@ -490,7 +489,6 @@
 <translation id="4183868528246477015">Search with Google Lens <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Open in new tab</translation>
 <translation id="4198423547019359126">No available download locations</translation>
-<translation id="4206707945726604465">To clear other forms of history, visit <ph name="BEGIN_LINK1" />My Google activity<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation>
 <translation id="4225895483398857530">Toolbar shortcut</translation>
 <translation id="4242533952199664413">Open settings</translation>
@@ -514,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Downloading…</translation>
 <translation id="4404568932422911380">No bookmarks</translation>
 <translation id="4405224443901389797">Move to…</translation>
+<translation id="4409271659088619928">Your search engine is <ph name="DSE" />. See their instructions for deleting your search history, if applicable.</translation>
 <translation id="4411535500181276704">Lite mode</translation>
 <translation id="4415276339145661267">Manage your Google Account</translation>
 <translation id="4427306783828095590">Enhanced protection does more to block phishing and malware</translation>
@@ -669,6 +668,7 @@
 <translation id="5368958499335451666">{OPEN_TABS,plural, =1{<ph name="OPEN_TABS_ONE" /> open tab, tap to switch tabs}other{<ph name="OPEN_TABS_MANY" /> open tabs, tap to switch tabs}}</translation>
 <translation id="5375577065097716013">Search image with Google Lens <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
 <translation id="5403644198645076998">Only allow certain sites</translation>
+<translation id="5409881200985013443">Submit <ph name="ONE_TIME_CODE" /> on <ph name="CLIENT_NAME" />?</translation>
 <translation id="5414836363063783498">Verifying…</translation>
 <translation id="5423934151118863508">Your most visited pages will appear here</translation>
 <translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation>
@@ -772,7 +772,6 @@
 <translation id="5979084224081478209">Check passwords</translation>
 <translation id="6000066717592683814">Keep Google</translation>
 <translation id="6000203700195075278">Refollow</translation>
-<translation id="6002623704405939939">To clear <ph name="BEGIN_LINK1" />search<ph name="END_LINK1" /> or other forms of history, visit <ph name="BEGIN_LINK2" />My Google activity<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Suggested password</translation>
 <translation id="6032091552407840792">This trial is active only in <ph name="BEGIN_LINK" />some regions<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">With <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome is developing new technologies to safeguard you from cross-site tracking while preserving the open web.
@@ -884,7 +883,6 @@
 <translation id="661266467055912436">Improves security for you and everyone on the web.</translation>
 <translation id="6618554661997243500">To see top sites and stories for you, tap the Home button</translation>
 <translation id="6627583120233659107">Edit folder</translation>
-<translation id="6635718764393004944">Your search engine is <ph name="DSE" />. If applicable, see their instructions to delete your search history.</translation>
 <translation id="663674369910034433">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK1" />Sync<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Google services<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Clear</translation>
 <translation id="6643649862576733715">Sort by amount of data saved</translation>
@@ -1027,6 +1025,7 @@
 <translation id="7583262514280211622">You’ll find your reading list here</translation>
 <translation id="7588219262685291874">Turn on dark theme when your device's Battery Saver is on</translation>
 <translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation>
+<translation id="7594687499944811403">Let <ph name="EMBEDDED_ORIGIN" /> verify that it's you for <ph name="TOP_ORIGIN" /></translation>
 <translation id="7596558890252710462">Operating system</translation>
 <translation id="7605594153474022051">Sync isn't working</translation>
 <translation id="7606077192958116810">Lite mode is on. Manage it in Settings.</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
index 9675e0e..bad799a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calculando…</translation>
 <translation id="1383876407941801731">Buscar</translation>
 <translation id="1384704387250346179">Traduce la foto con Lens <ph name="BEGIN_NEW" />Nuevo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Estilizar el contenido destacado</translation>
 <translation id="1386674309198842382">Activo hace <ph name="LAST_UPDATED" /> días</translation>
 <translation id="1397811292916898096">Buscar con <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">No realizar seguimiento</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> Botón <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envía algunas cookies y búsquedas de la barra de direcciones y del cuadro de búsqueda a tu motor de búsqueda predeterminado</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# archivo}other{# archivos}}</translation>
-<translation id="2017836877785168846">Borra el historial y las opciones de autocompletado en la barra de direcciones.</translation>
 <translation id="2021896219286479412">Controles en pantalla completa</translation>
 <translation id="2038563949887743358">Activar la opción para solicitar versión de escritorio</translation>
 <translation id="2039379262107991683">Agrega páginas a tu Lista de lectura para recibir recordatorios</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Buscar con Google Lens <ph name="BEGIN_NEW" />Nuevo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Abrir en una pestaña nueva</translation>
 <translation id="4198423547019359126">No hay ubicaciones de descarga disponibles</translation>
-<translation id="4206707945726604465">Para borrar otros tipos de historial, visita <ph name="BEGIN_LINK1" />Mi actividad de Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para obtener contenido personalizado y sugerido por Google, activa la sincronización</translation>
 <translation id="4225895483398857530">Acceso directo a la barra de herramientas</translation>
 <translation id="4242533952199664413">Abrir la configuración</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: descargando…</translation>
 <translation id="4404568932422911380">No hay favoritos</translation>
 <translation id="4405224443901389797">Mover a…</translation>
+<translation id="4409271659088619928">Tu motor de búsqueda es <ph name="DSE" />. Consulta las instrucciones para borrar el historial de búsqueda (si corresponde).</translation>
 <translation id="4411535500181276704">Modo lite</translation>
 <translation id="4415276339145661267">Administrar tu Cuenta de Google</translation>
 <translation id="4427306783828095590">La protección mejorada permite bloquear mejor la suplantación de identidad (phishing) y el software malicioso.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Revisar contraseñas</translation>
 <translation id="6000066717592683814">Seguir usando Google</translation>
 <translation id="6000203700195075278">Volver a seguir</translation>
-<translation id="6002623704405939939">Para borrar la <ph name="BEGIN_LINK1" />búsqueda<ph name="END_LINK1" /> o algún otro tipo de historial, visita <ph name="BEGIN_LINK2" />Mi actividad de Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Contraseña sugerida</translation>
 <translation id="6032091552407840792">Esta prueba está activada solo en <ph name="BEGIN_LINK" />algunas regiones<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">A través de <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome está desarrollando nuevas tecnologías para protegerte ante el seguimiento entre sitios, a la vez que se preserva la Web abierta.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">El nombre es demasiado largo</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# imagen}other{# imágenes}}</translation>
 <translation id="6447558397796644647">No se puede encontrar ese favorito. Revisa la ortografía o agrega un nuevo favorito.</translation>
+<translation id="6459045781120991510">Encuestas</translation>
 <translation id="6461962085415701688">No se puede abrir el archivo</translation>
 <translation id="6464977750820128603">Puedes ver los sitios que visites en Chrome y establecer temporizadores para ellos.\n\nGoogle obtiene información sobre los sitios para los que estableces temporizadores y la duración de las visitas a ellos. Esta información se usa para mejorar Bienestar digital.</translation>
 <translation id="6475951671322991020">Descargar video</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Mejora la seguridad para ti y todos los usuarios de la Web.</translation>
 <translation id="6618554661997243500">Para ver los sitios que más visitas y las historias que más lees, presiona el botón de la página principal</translation>
 <translation id="6627583120233659107">Editar la carpeta</translation>
-<translation id="6635718764393004944">Tu motor de búsqueda es <ph name="DSE" />. Si corresponde, consulta sus instrucciones para borrar tu historial de búsqueda.</translation>
 <translation id="663674369910034433">Para ver más opciones de configuración relacionadas con la privacidad, seguridad y recopilación de datos, visita <ph name="BEGIN_LINK1" />Sincronización<ph name="END_LINK1" /> y <ph name="BEGIN_LINK2" />Servicios de Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Borrar</translation>
 <translation id="6643649862576733715">Ordenar por cantidad de datos ahorrados</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">Nota estilizada con contenido destacado (<ph name="CURRENT_DATE" />)</translation>
 <translation id="7248069434667874558">Comprueba que <ph name="TARGET_DEVICE_NAME" /> tenga activada la sincronización en Chrome</translation>
 <translation id="7252076891734325316">Coloca el teléfono cerca de la computadora</translation>
+<translation id="727288900855680735">¿Deseas enviar <ph name="ONE_TIME_CODE" /> a <ph name="ORIGIN" />?</translation>
 <translation id="7274013316676448362">Sitio bloqueado</translation>
 <translation id="7286572596625053347">¿Quieres cambiar (<ph name="LANGUAGE" />)?</translation>
 <translation id="7290209999329137901">No se puede renombrar el elemento porque no está disponible</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
index c28348e9..b1874ed 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calculando…</translation>
 <translation id="1383876407941801731">Buscar</translation>
 <translation id="1384704387250346179">Traducir imagen con Lens <ph name="BEGIN_NEW" />Nuevo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Estilizar el contenido destacado</translation>
 <translation id="1386674309198842382">Activo hace <ph name="LAST_UPDATED" /> días</translation>
 <translation id="1397811292916898096">Buscar con <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">No hacer seguimiento</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> Botón <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envía algunas cookies y búsquedas desde la barra de direcciones y el cuadro de búsqueda a tu buscador predeterminado</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# archivo}other{# archivos}}</translation>
-<translation id="2017836877785168846">Borra el historial y los autocompletados de la barra de direcciones.</translation>
 <translation id="2021896219286479412">Controles de pantalla completa</translation>
 <translation id="2038563949887743358">Activar opción para ver como ordenador</translation>
 <translation id="2039379262107991683">Añade páginas a tu lista de lectura para recibir recordatorios</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Buscar con Google Lens <ph name="BEGIN_NEW" />Nuevo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Abrir en una pestaña nueva</translation>
 <translation id="4198423547019359126">No hay ubicaciones de descarga disponibles</translation>
-<translation id="4206707945726604465">Para borrar otros tipos de historial, visita <ph name="BEGIN_LINK1" />Mi Actividad en Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para obtener contenido personalizado sugerido por Google, activa la sincronización</translation>
 <translation id="4225895483398857530">Acceso directo en la barra de herramientas</translation>
 <translation id="4242533952199664413">Abrir Configuración</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: descargando…</translation>
 <translation id="4404568932422911380">No hay marcadores</translation>
 <translation id="4405224443901389797">Mover a…</translation>
+<translation id="4409271659088619928">Usas el buscador <ph name="DSE" />. Consulta las instrucciones de tu buscador para eliminar tu historial de búsqueda (si corresponde).</translation>
 <translation id="4411535500181276704">Modo básico</translation>
 <translation id="4415276339145661267">Gestionar tu cuenta de Google</translation>
 <translation id="4427306783828095590">La protección mejorada es más eficaz para bloquear ataques de suplantación de identidad y software malicioso.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Comprobar contraseñas</translation>
 <translation id="6000066717592683814">Mantener Google como motor de búsqueda predeterminado</translation>
 <translation id="6000203700195075278">Volver a seguir</translation>
-<translation id="6002623704405939939">Para borrar la <ph name="BEGIN_LINK1" />búsqueda<ph name="END_LINK1" /> u otros tipos de historial, visita <ph name="BEGIN_LINK2" />Mi Actividad en Google<ph name="END_LINK2" />.</translation>
 <translation id="6005538289190791541">Contraseña sugerida</translation>
 <translation id="6032091552407840792">Esta prueba solo está activa en <ph name="BEGIN_LINK" />algunas regiones<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Con <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome desarrolla nuevas tecnologías que te protegerán de mecanismos de seguimiento entre sitios y, a la vez, preservarán la Web abierta.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Mejora tu seguridad y la de todo el mundo en la Web.</translation>
 <translation id="6618554661997243500">Para ver tus sitios favoritos e historias, toca el botón de inicio</translation>
 <translation id="6627583120233659107">Editar carpeta</translation>
-<translation id="6635718764393004944">Usas el buscador <ph name="DSE" />. Si procede, consulta sus instrucciones sobre cómo eliminar tu historial de búsqueda.</translation>
 <translation id="663674369910034433">Para ver más ajustes relacionados con la privacidad, la seguridad y la recogida de datos, consulta <ph name="BEGIN_LINK1" />Sincronización<ph name="END_LINK1" /> y <ph name="BEGIN_LINK2" />Servicios de Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Borrar</translation>
 <translation id="6643649862576733715">Ordenar por cantidad de datos ahorrados</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
index 1658a0c..cb178c2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Arvutamine …</translation>
 <translation id="1383876407941801731">Otsi</translation>
 <translation id="1384704387250346179">Tõlgi pilt Google Lensiga <ph name="BEGIN_NEW" />Uus<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stiliseeri esiletõst</translation>
 <translation id="1386674309198842382">Aktiivne <ph name="LAST_UPDATED" /> päeva tagasi</translation>
 <translation id="1397811292916898096">Otsi teenusega <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Ära jälgi”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> – nupp <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Saadab teie vaikeotsingumootorile mõned küpsisefailid ja otsingud teie aadressiribalt ning otsingukastist</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fail}other{# faili}}</translation>
-<translation id="2017836877785168846">Kustutab aadressiribalt ajaloo ja automaatse täitmise teabe.</translation>
 <translation id="2021896219286479412">Saidi juhtelemendid täisekraanil</translation>
 <translation id="2038563949887743358">Valiku Taotle arvutisaiti sisselülitamine</translation>
 <translation id="2039379262107991683">Meeldetuletuse saamiseks lisage lehed oma lugemisloendisse</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Keeled</translation>
 <translation id="4183868528246477015">Otsi Google Lensi abil <ph name="BEGIN_NEW" />Uus<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Ava uuel vahelehel</translation>
+<translation id="4196597275619698563">Loo kaart</translation>
 <translation id="4198423547019359126">Ükski allalaadimise asukoht ei ole saadaval</translation>
-<translation id="4206707945726604465">Muude ajalooandmete kustutamiseks külastage lehte <ph name="BEGIN_LINK1" />Minu tegevused Google’is<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Google'i soovitatud isikupärastatud sisu hankimiseks lülitage sünkroonimine sisse</translation>
 <translation id="4225895483398857530">Tööriistariba otsetee</translation>
 <translation id="4242533952199664413">Ava seaded</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – allalaadimine …</translation>
 <translation id="4404568932422911380">Järjehoidjaid pole</translation>
 <translation id="4405224443901389797">Teisalda asukohta …</translation>
+<translation id="4409271659088619928">Teie otsingumootor on <ph name="DSE" />. Vaadake selle juhiseid otsinguajaloo kustutamise kohta, kui see on asjakohane.</translation>
 <translation id="4411535500181276704">Lihtsustatud režiim</translation>
 <translation id="4415276339145661267">Google'i konto haldamine</translation>
 <translation id="4427306783828095590">Täiustatud kaitse aitab andmepüüki ja pahavara paremini blokeerida</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">Kontrolli paroole</translation>
 <translation id="6000066717592683814">Säilita Google</translation>
 <translation id="6000203700195075278">Jälgi uuesti</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Otsinguajaloo<ph name="END_LINK1" /> ja muude ajalooandmete kustutamiseks avage jaotis <ph name="BEGIN_LINK2" />Minu tegevused Google’is<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Soovitatud parool</translation>
 <translation id="6032091552407840792">See prooviperiood on aktiivne vaid <ph name="BEGIN_LINK" />teatud piirkondades<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privaatsuse liivakasti<ph name="END_LINK" /> abil arendab Chrome uusi tehnoloogiaid, mille abil kaitsta teid saidiülese jälgimise eest, säilitades siiski juurdepääsu avatud veebile.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">Täiendab turvalisust teie ja kõigi teiste veebikasutajate jaoks.</translation>
 <translation id="6618554661997243500">Sageli külastatud saitide ja populaarsete lugude vaatamiseks puudutage avakuva nuppu</translation>
 <translation id="6627583120233659107">Muuda kausta</translation>
-<translation id="6635718764393004944">Teie otsingumootor on <ph name="DSE" />. Võimaluse korral vaadake selle juhiseid otsinguajaloo kustutamiseks.</translation>
 <translation id="663674369910034433">Privaatsuse, turvalisuse ning andmete kogumisega seotud lisaseadete nägemiseks vaadake jaotisi <ph name="BEGIN_LINK1" />Sünkroonimine<ph name="END_LINK1" /> ja <ph name="BEGIN_LINK2" />Google'i teenused<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Tühjenda</translation>
 <translation id="6643649862576733715">Sordi säästetud andmemahu alusel</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">Otsingute ja URL-ide automaatne täitmine</translation>
 <translation id="7707922173985738739">Kasuta mobiilset andmesidet</translation>
 <translation id="7725024127233776428">Järjehoidjatesse lisatud lehed kuvatakse siin</translation>
+<translation id="7731260005404856143">Kui olete sisse logitud, võidakse teie <ph name="BEGIN_LINK1" />muud tegevused<ph name="END_LINK1" /> teie Google'i kontole salvestada. Võite need igal ajal kustutada.</translation>
 <translation id="7757787379047923882">Teksti jagati seadmest <ph name="DEVICE_NAME" /></translation>
 <translation id="7761849928583394409">Kuupäeva ja kellaaja valimine</translation>
 <translation id="7762668264895820836">SD-kaart <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">Vaadake oma võrguühenduseta faile</translation>
 <translation id="8856607253650333758">Esita kirjeldusi</translation>
 <translation id="8873817150012960745">Alustamiseks puudutage siin</translation>
+<translation id="8881973373982641723">Tühjendab ajaloo, sh otsingukasti ajaloo.</translation>
 <translation id="889338405075704026">Ava Chrome'i seaded</translation>
 <translation id="8898822736010347272">Saadab mõne teie külastatud lehe URL-i, piiratud süsteemiteabe ja mõne lehe sisu Google'ile, et aidata avastada uusi ohte ja veebis kõiki kaitsta.</translation>
 <translation id="8909135823018751308">Jaga ...</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">Ei saa helistada</translation>
 <translation id="9212845824145208577">Madalamale ei saa minna. Alustage lehel altpoolt.</translation>
 <translation id="9219103736887031265">Pildid</translation>
+<translation id="923957533152125119">Kui olete sisse logitud, võidakse teie <ph name="BEGIN_LINK1" />otsinguajalugu<ph name="END_LINK1" /> ja <ph name="BEGIN_LINK2" />muud tegevused<ph name="END_LINK2" /> teie Google'i kontole salvestada. Võite need igal ajal kustutada.</translation>
 <translation id="926205370408745186">Chrome'i tegevuste eemaldamine teenusest Digitaalne heaolu</translation>
 <translation id="927968626442779827">Kasutage Google Chrome'is lihtsustatud režiimi</translation>
 <translation id="932327136139879170">Kodu</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
index d5938a9..e4db7b6c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Kalkulatzen…</translation>
 <translation id="1383876407941801731">Bilaketa</translation>
 <translation id="1384704387250346179">Itzuli irudia Google Lens-ekin <ph name="BEGIN_NEW" />Berria<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Eman estiloa nabarmendutakoari</translation>
 <translation id="1386674309198842382">Aktibo duela <ph name="LAST_UPDATED" /> egun</translation>
 <translation id="1397811292916898096">Egin bilaketak <ph name="PRODUCT_NAME" /> zerbitzuarekin</translation>
 <translation id="1406000523432664303">"Ez jarraitu"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> botoia</translation>
 <translation id="2000419248597011803">Helbide-barrako zein bilaketa-koadroko bilaketak eta cookie batzuk bidaltzen ditu bilatzaile lehenetsira</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fitxategi}other{# fitxategi}}</translation>
-<translation id="2017836877785168846">Helbide-barrako historia eta osatze automatikoak garbitzen ditu.</translation>
 <translation id="2021896219286479412">Webgunearen pantaila osoko aukerak</translation>
 <translation id="2038563949887743358">Aktibatu ordenagailuetarako webgunea eskatzeko aukera</translation>
 <translation id="2039379262107991683">Abisuak jasotzeko, gehitu orriak irakurketa-zerrendan</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Bilatu Google Lens-ekin <ph name="BEGIN_NEW" />Berria<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Ireki fitxa berri batean</translation>
 <translation id="4198423547019359126">Ez dago deskarga-kokapenik eskuragarri</translation>
-<translation id="4206707945726604465">Historiako beste datu batzuk ezabatzeko, joan <ph name="BEGIN_LINK1" />Google-ko nire jarduerak<ph name="END_LINK1" /> atalera</translation>
 <translation id="4209895695669353772">Google-k iradokitzen duen eduki pertsonalizatua jasotzeko, aktibatu sinkronizazioa</translation>
 <translation id="4225895483398857530">Tresna-barrako lasterbidea</translation>
 <translation id="4242533952199664413">Ireki ezarpenak</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: deskargatzen…</translation>
 <translation id="4404568932422911380">Ez dago laster-markarik</translation>
 <translation id="4405224443901389797">Eraman hona…</translation>
+<translation id="4409271659088619928"><ph name="DSE" /> da bilatzailea. Behar izanez gero, joan haren argibideetara bilaketa-historia ezabatzeari buruzko informazio gehiago lortzeko.</translation>
 <translation id="4411535500181276704">Oinarrizko modua</translation>
 <translation id="4415276339145661267">Kudeatu Google-ko kontua</translation>
 <translation id="4427306783828095590">Babes handiagoa eskaintzen du phishingaren eta malwarearen aurka</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Egiaztatu pasahitzak</translation>
 <translation id="6000066717592683814">Jarraitu Google erabiltzen</translation>
 <translation id="6000203700195075278">Jarraitu berriro</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Bilaketa-historia<ph name="END_LINK1" /> edo beste historia mota batzuk ezabatzeko, joan <ph name="BEGIN_LINK2" />Google-ko nire jarduerak<ph name="END_LINK2" /> atalera</translation>
 <translation id="6005538289190791541">Iradokitako pasahitza</translation>
 <translation id="6032091552407840792"><ph name="BEGIN_LINK" />Lurralde batzuetan<ph name="END_LINK" /> soilik dago aktibo probaldia.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox-arekin<ph name="END_LINK" />, Chrome teknologia berriak garatzen ari da sare irekia mantendu bitartean zu webguneen arteko jarraipenetik babesteko.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">Izena luzeegia da</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# irudi}other{# irudi}}</translation>
 <translation id="6447558397796644647">Ezin da aurkitu laster-marka hori. Egiaztatu zuzen idatzi duzula edo gehitu laster-marka bat.</translation>
+<translation id="6459045781120991510">Inkestak</translation>
 <translation id="6461962085415701688">Ezin da ireki fitxategia</translation>
 <translation id="6464977750820128603">Chrome-n irekitako webguneak ikus ditzakezu, eta haiek erabiltzeko tenporizadoreak ezarri.\n\nGoogle-k informazioa jasotzen du tenporizadoreak ezarri dizkiezun webguneei buruz eta haietan zenbat denbora eman duzun kalkulatzen du. Ongizate digitala programa hobetzeko erabiltzen da informazio hori.</translation>
 <translation id="6475951671322991020">Deskargatu bideoa</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Segurtasuna hobetzen du, bai zuretzat, bai sareko gainontzeko erabiltzaileentzat.</translation>
 <translation id="6618554661997243500">Zuretzat hautatutako webgune eta istorio nagusiak ikusteko, sakatu Hasiera botoia</translation>
 <translation id="6627583120233659107">Editatu karpeta</translation>
-<translation id="6635718764393004944">Bilatzailea <ph name="DSE" /> da. Ikusi bilaketa-historia ezabatzeko argibideak, halakorik badago.</translation>
 <translation id="663674369910034433">Pribatutasunarekin, segurtasunarekin eta datu-bilketarekin lotutako ezarpen gehiago ikusteko, joan <ph name="BEGIN_LINK1" />Sinkronizazioa<ph name="END_LINK1" /> eta <ph name="BEGIN_LINK2" />Google-ren zerbitzuak<ph name="END_LINK2" /> ataletara.</translation>
 <translation id="6643016212128521049">Garbitu</translation>
 <translation id="6643649862576733715">Ordenatu aurreztutako datu kopuruaren arabera</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">Nabarmentze estilizatua <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Ziurtatu <ph name="TARGET_DEVICE_NAME" /> gailuak Chrome-ren sinkronizazioa aktibatuta daukala</translation>
 <translation id="7252076891734325316">Jarri telefonoa ordenagailutik gertu</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" /> domeinura bidali nahi duzu <ph name="ONE_TIME_CODE" />?</translation>
 <translation id="7274013316676448362">Blokeatutako webgunea</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> aldatu nahi duzu?</translation>
 <translation id="7290209999329137901">Ezin da aldatu izena</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
index c51df95..b222bb44 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">درحال محاسبه…</translation>
 <translation id="1383876407941801731">جستجو</translation>
 <translation id="1384704387250346179">‏ترجمه تصویر با «لنز Google» <ph name="BEGIN_NEW" />جدید<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">برجسته‌سازی سبک‌دار</translation>
 <translation id="1386674309198842382">آخرین فعالیت: <ph name="LAST_UPDATED" /> روز قبل</translation>
 <translation id="1397811292916898096">جستجو با <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">«ردیابی نشود»</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> دکمه <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">برخی کوکی‌ها و جستجوها را از نوار نشانی و جعبه جستجو به موتور جستجوی پیش‌فرض ارسال می‌کند</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# فایل}one{# فایل}other{# فایل}}</translation>
-<translation id="2017836877785168846">سابقه و تکمیل خودکار را در نوار نشانی پاک می‌کند.</translation>
 <translation id="2021896219286479412">کنترل‌های سایت تمام‌صفحه</translation>
 <translation id="2038563949887743358">روشن کردن درخواست سایت رایانه‌ای</translation>
 <translation id="2039379262107991683">برای دریافت یادآوری، صفحه‌هایتان را به «فهرست خواندن» اضافه کنید</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">‏جستجو با «لنز Google» <ph name="BEGIN_NEW" />جدید<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">باز کردن در برگهٔ جدید</translation>
 <translation id="4198423547019359126">مکانی برای بارگیری دردسترس نیست</translation>
-<translation id="4206707945726604465">‏برای پاک کردن انواع دیگر سابقه، به <ph name="BEGIN_LINK1" />فعالیت Google من<ph name="END_LINK1" /> بروید</translation>
 <translation id="4209895695669353772">‏برای اینکه Google محتوای شخصی‌شده به شما پیشنهاد دهد، همگام‌سازی را روشن کنید</translation>
 <translation id="4225895483398857530">میان‌بر نوار ابزار</translation>
 <translation id="4242533952199664413">باز کردن تنظیمات</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - درحال بارگیری…</translation>
 <translation id="4404568932422911380">هیچ نشانکی موجود نیست</translation>
 <translation id="4405224443901389797">انتقال به…</translation>
+<translation id="4409271659088619928">موتور جستجوی شما <ph name="DSE" /> است. برای اینکه سابقه جستجویتان را درصورت امکان حذف کنید، دستورالعمل‌های آن موتور جستجو را ببینید.</translation>
 <translation id="4411535500181276704">حالت ساده</translation>
 <translation id="4415276339145661267">‏مدیریت «حساب Google»</translation>
 <translation id="4427306783828095590">«محافظت بهبودیافته» کارهای بیشتری برای مسدود کردن رمزگیری و بدافزار انجام می‌دهد</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">بررسی گذرواژه‌ها</translation>
 <translation id="6000066717592683814">‏حفظ Google</translation>
 <translation id="6000203700195075278">دنبال کردن مجدد</translation>
-<translation id="6002623704405939939">‏برای پاک کردن سابقه <ph name="BEGIN_LINK1" />جستجو<ph name="END_LINK1" /> یا دیگر انواع سابقه، به <ph name="BEGIN_LINK2" />فعالیت من در Google<ph name="END_LINK2" /> بروید</translation>
 <translation id="6005538289190791541">گذرواژه پیشنهادی</translation>
 <translation id="6032091552407840792">این دوره آزمایشی فقط در <ph name="BEGIN_LINK" />برخی مناطق<ph name="END_LINK" /> فعال است.</translation>
 <translation id="6033245666633565791">‏Chrome بااستفاده از <ph name="BEGIN_LINK" />جعبه ایمنی حریم‌خصوصی<ph name="END_LINK" /> درحال توسعه فناوری‌های جدیدی است که ضمن حفظ وبِ باز، از شما در برابر ردیابی بین‌سایتی محافظت می‌کند.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">امنیت را برای شما و همه کاربران دیگر وب بهبود می‌بخشد.</translation>
 <translation id="6618554661997243500">برای دیدن سایت‌ها و داستان‌های برتر ویژه شما، روی دکمه «صفحه اصلی» ضربه بزنید</translation>
 <translation id="6627583120233659107">ویرایش پوشه</translation>
-<translation id="6635718764393004944">موتور جستجوی شما <ph name="DSE" /> است. درصورت وجود، دستورالعمل‌های حذف سابقه جستجو را ببینید.</translation>
 <translation id="663674369910034433">‏برای تنظیمات بیشتر مرتبط با حریم‌خصوصی، امنیت، و جمع‌آوری داده، <ph name="BEGIN_LINK1" />همگام‌سازی<ph name="END_LINK1" /> و <ph name="BEGIN_LINK2" />سرویس‌های Google<ph name="END_LINK2" /> را ببینید.</translation>
 <translation id="6643016212128521049">پاک کردن</translation>
 <translation id="6643649862576733715">به‌ترتیب مقدار داده صرفه‌جویی‌شده</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
index 5a20ec5..ddf6b88a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Lasketaan…</translation>
 <translation id="1383876407941801731">Haku</translation>
 <translation id="1384704387250346179">Käännä kuva Google Lensillä <ph name="BEGIN_NEW" />Uusi<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Tyylitelty korostus</translation>
 <translation id="1386674309198842382">Aktiivinen <ph name="LAST_UPDATED" /> päivää sitten</translation>
 <translation id="1397811292916898096">Hae nimellä <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Do Not Track</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-painike</translation>
 <translation id="2000419248597011803">Lähettää joitakin osoitekentän ja hakukentän kautta tehtyjä hakuja sekä joitakin evästeitä oletushakukoneellesi</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# tiedosto}other{# tiedostoa}}</translation>
-<translation id="2017836877785168846">Tyhjentää historian ja osoitepalkin automaattiset täydennykset.</translation>
 <translation id="2021896219286479412">Ohjaimet koko näytön tilassa</translation>
 <translation id="2038563949887743358">Ota käyttöön Käytä tietokoneversiota</translation>
 <translation id="2039379262107991683">Lisää lukulistalle sivuja, joista saat muistutuksen</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Hae Google Lensillä <ph name="BEGIN_NEW" />Uusi<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Avaa uudelle välilehdelle</translation>
 <translation id="4198423547019359126">Tallennussijainteja ei ole saatavilla</translation>
-<translation id="4206707945726604465">Voit tyhjentää muita historiatietoja <ph name="BEGIN_LINK1" />Google-toimintani<ph name="END_LINK1" /> ‑kohdassa.</translation>
 <translation id="4209895695669353772">Ota synkronointi käyttöön, niin näet Googlen suosittelemaa yksilöllistä sisältöä</translation>
 <translation id="4225895483398857530">Työkalupalkin pikakuvake</translation>
 <translation id="4242533952199664413">Avaa asetukset</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Ladataan…</translation>
 <translation id="4404568932422911380">Ei kirjanmerkkejä</translation>
 <translation id="4405224443901389797">Siirrä…</translation>
+<translation id="4409271659088619928">Hakukoneesi on <ph name="DSE" />. Katso tarvittaessa hakukoneen ohjeet hakuhistorian poistamiselle.</translation>
 <translation id="4411535500181276704">Yksinkertaistettu tila</translation>
 <translation id="4415276339145661267">Ylläpidä Google-tiliäsi</translation>
 <translation id="4427306783828095590">Parannettu suojaus torjuu tietojenkalastelua ja haittaohjelmia entistä tehokkaammin</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Tarkista salasanat</translation>
 <translation id="6000066717592683814">Käytä Googlea</translation>
 <translation id="6000203700195075278">Seuraa uudelleen</translation>
-<translation id="6002623704405939939">Voit tyhjentää <ph name="BEGIN_LINK1" />haun<ph name="END_LINK1" /> tai muita historiatietoja <ph name="BEGIN_LINK2" />Google-toimintani<ph name="END_LINK2" />-kohdassa.</translation>
 <translation id="6005538289190791541">Salasanaehdotus</translation>
 <translation id="6032091552407840792">Tämä kokeilu on aktiivinen vain <ph name="BEGIN_LINK" />tietyillä alueilla<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Chrome kehittää <ph name="BEGIN_LINK" />Privacy Sandboxin<ph name="END_LINK" /> avulla uusia tekniikoita, joiden avulla sinua voidaan suojata sivustojen väliseltä seurannalta verkon pysyessä avoimena.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Parantaa sinun ja kaikkien verkon käyttäjien suojausta</translation>
 <translation id="6618554661997243500">Katso suositut sivustosi ja sinulle valitut jutut napauttamalla Etusivu-painiketta</translation>
 <translation id="6627583120233659107">Muokkaa kansiota</translation>
-<translation id="6635718764393004944">Hakukoneesi on <ph name="DSE" />. Katso sen mahdolliset ohjeet hakuhistorian tyhjentämiseen.</translation>
 <translation id="663674369910034433">Näet lisää yksityisyyteen, tietoturvaan ja datankeruuseen liittyviä asetuksia kohdista <ph name="BEGIN_LINK1" />Synkronointi<ph name="END_LINK1" /> ja <ph name="BEGIN_LINK2" />Googlen palvelut<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Tyhjennä</translation>
 <translation id="6643649862576733715">Lajittele säästetyn datan määrän mukaan</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
index ff387cf6..7fd548eb 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Kino-compute…</translation>
 <translation id="1383876407941801731">Hanapin</translation>
 <translation id="1384704387250346179">Isalin sa Google Lens <ph name="BEGIN_NEW" />Bago<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">I-style ang highlight</translation>
 <translation id="1386674309198842382">Aktibo <ph name="LAST_UPDATED" /> (na) araw ang nakalipas</translation>
 <translation id="1397811292916898096">Maghanap gamit ang <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Huwag Subaybayan”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Button ng <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Nagpapadala ng ilang cookies at paghahanap mula sa address bar at box para sa paghahanap sa iyong default na search engine</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# File}one{# File}other{# na File}}</translation>
-<translation id="2017836877785168846">Kini-clear ang history at mga awtomatikong pagkumpleto sa address bar.</translation>
 <translation id="2021896219286479412">Control ng full screen sa site</translation>
 <translation id="2038563949887743358">I-on ang Hilingin ang site sa desktop</translation>
 <translation id="2039379262107991683">Magdagdag ng mga page sa iyong Listahan ng Babasahin para makatanggap ng paalala</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Hanapin gamit ang Google Lens <ph name="BEGIN_NEW" />Bago<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Buksan sa bagong tab</translation>
 <translation id="4198423547019359126">Walang available na lokasyon ng pag-download</translation>
-<translation id="4206707945726604465">Para i-clear ang iba pang uri ng history, bisitahin ang <ph name="BEGIN_LINK1" />Aking Aktibidad sa Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para makakuha ng naka-personalize na content na iminumungkahi ng Google, i-on ang pag-sync</translation>
 <translation id="4225895483398857530">Shortcut ng toolbar</translation>
 <translation id="4242533952199664413">Buksan ang mga setting</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Dina-download…</translation>
 <translation id="4404568932422911380">Walang bookmark</translation>
 <translation id="4405224443901389797">Ilipat sa…</translation>
+<translation id="4409271659088619928"><ph name="DSE" /> ang iyong search engine. Tingnan ang mga tagubilin nito para sa pag-delete sa iyong history ng paghahanap, kung naaangkop.</translation>
 <translation id="4411535500181276704">Lite mode</translation>
 <translation id="4415276339145661267">Pamahalaan ang iyong Google Account</translation>
 <translation id="4427306783828095590">Mas maraming magagawa ang pinahusay na proteksyon para mag-block ng phishing and malware</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Suriin ang mga password</translation>
 <translation id="6000066717592683814">Panatilihin ang Google</translation>
 <translation id="6000203700195075278">Subaybayan ulit</translation>
-<translation id="6002623704405939939">Para i-clear ang <ph name="BEGIN_LINK1" />paghahanap<ph name="END_LINK1" /> o iba pang uri ng history, bisitahin ang <ph name="BEGIN_LINK2" />Aking Aktibidad sa Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Iminumungkahing password</translation>
 <translation id="6032091552407840792">Aktibo lang ang trial na ito sa <ph name="BEGIN_LINK" />ilang rehiyon<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Sa pamamagitan ng <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, nagde-develop ang Chrome ng mga bagong teknolohiya para protektahan ka laban sa cross-site na pagsubaybay habang pinapanatili ang bukas na web.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Pinapahusay ang seguridad para sa iyo at sa lahat ng tao sa web.</translation>
 <translation id="6618554661997243500">Para makita ang mga nangungunang site at kuwento para sa iyo, i-tap ang button ng Home</translation>
 <translation id="6627583120233659107">I-edit ang folder</translation>
-<translation id="6635718764393004944"><ph name="DSE" /> ang iyong search engine. Kung naaangkop, tingnan ang kanilang mga tagubilin para i-delete ang iyong history ng paghahanap.</translation>
 <translation id="663674369910034433">Para sa higit pang setting na nauugnay sa privacy, seguridad, at pagkolekta ng data, tingnan ang <ph name="BEGIN_LINK1" />Pag-sync<ph name="END_LINK1" /> at <ph name="BEGIN_LINK2" />Mga serbisyo ng Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">I-clear</translation>
 <translation id="6643649862576733715">Pagbukud-bukurin ayon sa dami ng data na natipid</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
index 6db56e8..d4ac117 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calcul en cours…</translation>
 <translation id="1383876407941801731">Rechercher</translation>
 <translation id="1384704387250346179">Traduire l'image avec Lentille Google <ph name="BEGIN_NEW" />Nouv.<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Formater la surbrillance</translation>
 <translation id="1386674309198842382">Actif il y a <ph name="LAST_UPDATED" /> jours</translation>
 <translation id="1397811292916898096">Rechercher avec <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">« Ne pas faire le suivi »</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Bouton <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envoie des témoins et des recherches à partir de la barre d'adresse et du champ de recherche à votre moteur de recherche par défaut</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fichier}one{# fichier}other{# fichiers}}</translation>
-<translation id="2017836877785168846">Efface l'historique et la saisie semi-automatique de la barre d'adresse.</translation>
 <translation id="2021896219286479412">Contrôles du site en plein écran</translation>
 <translation id="2038563949887743358">Activer l’option Demander site pour ordinateurs de bureau</translation>
 <translation id="2039379262107991683">Ajoutez des pages à votre liste de lecture pour recevoir un rappel</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015"><ph name="BEGIN_NEW" />Nouv.<ph name="END_NEW" /> Rech. avec Lentille Google</translation>
 <translation id="4195643157523330669">Ouvrir dans un nouvel onglet</translation>
 <translation id="4198423547019359126">Aucun dossier de téléchargement n'est disponible</translation>
-<translation id="4206707945726604465">Pour effacer d'autres historiques, visitez la page <ph name="BEGIN_LINK1" />Mon activité Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Pour obtenir du contenu personnalisé suggéré par Google, activez la synchronisation</translation>
 <translation id="4225895483398857530">Raccourci de la barre d'outils</translation>
 <translation id="4242533952199664413">Ouvrir les paramètres</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546">Téléchargement de la langue <ph name="LANG" /> en cours…</translation>
 <translation id="4404568932422911380">Aucun favori</translation>
 <translation id="4405224443901389797">Déplacer dans…</translation>
+<translation id="4409271659088619928">Vous utilisez <ph name="DSE" /> comme moteur de recherche. Consultez les instructions de celui-ci pour supprimer votre historique de recherche, le cas échéant.</translation>
 <translation id="4411535500181276704">Mode simplifié</translation>
 <translation id="4415276339145661267">Gérer votre compte Google</translation>
 <translation id="4427306783828095590">La protection renforcée en fait plus pour bloquer l'hameçonnage et les logiciels nuisibles</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Vérifier les mots de passe</translation>
 <translation id="6000066717592683814">Conserver Google</translation>
 <translation id="6000203700195075278">Se réabonner</translation>
-<translation id="6002623704405939939">Pour effacer vos <ph name="BEGIN_LINK1" />recherches<ph name="END_LINK1" /> ou d'autres types d'historiques, visitez la page<ph name="BEGIN_LINK2" />Mon activité Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Mot de passe suggéré</translation>
 <translation id="6032091552407840792">Cette version d'essai est uniquement active dans <ph name="BEGIN_LINK" />certaines régions<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Grâce au <ph name="BEGIN_LINK" />bac à sable de confidentialité<ph name="END_LINK" />, Chrome développe de nouvelles technologies pour vous protéger du suivi intersites, tout en préservant le caractère ouvert du Web.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Il renforce votre sécurité et celle de tous les utilisateurs sur le Web.</translation>
 <translation id="6618554661997243500">Pour consulter les sites les plus fréquentés et des articles sélectionnés pour vous, touchez le bouton Accueil</translation>
 <translation id="6627583120233659107">Modifier le dossier</translation>
-<translation id="6635718764393004944">Vous utilisez <ph name="DSE" /> comme moteur de recherche. Le cas échéant, consultez ses instructions pour apprendre comment supprimer votre historique de recherche.</translation>
 <translation id="663674369910034433">Pour voir plus de paramètres relatifs à la confidentialité, à la sécurité et à la collecte de données, reportez-vous aux rubriques <ph name="BEGIN_LINK1" />Synchronisation<ph name="END_LINK1" /> et <ph name="BEGIN_LINK2" />Services Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Effacer</translation>
 <translation id="6643649862576733715">Trier par quantité de données enregistrées</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
index 70659b3..27b4849 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calcul…</translation>
 <translation id="1383876407941801731">Rechercher</translation>
 <translation id="1384704387250346179">Traduire avec Google Lens <ph name="BEGIN_NEW" />Nouveau<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Modifier la surbrillance</translation>
 <translation id="1386674309198842382">Actif il y a <ph name="LAST_UPDATED" /> jours</translation>
 <translation id="1397811292916898096">Rechercher avec <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Interdire le suivi</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Bouton <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envoie des cookies et des recherches effectuées à partir de la barre d'adresse et du champ de recherche à votre moteur de recherche par défaut</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fichier}one{# fichier}other{# fichiers}}</translation>
-<translation id="2017836877785168846">Efface l'historique et les saisies semi-automatiques dans la barre d'adresse.</translation>
 <translation id="2021896219286479412">Commandes du site en plein écran</translation>
 <translation id="2038563949887743358">Activer "Voir version ordinateur"</translation>
 <translation id="2039379262107991683">Ajoutez des pages à votre liste de lecture pour recevoir un rappel</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Utiliser Google Lens <ph name="BEGIN_NEW" />Nouveau<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Ouvrir dans un nouvel onglet</translation>
 <translation id="4198423547019359126">Aucun emplacement de téléchargements disponible</translation>
-<translation id="4206707945726604465">Pour effacer d'autres historiques, consultez <ph name="BEGIN_LINK1" />Mon activité Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Activez la synchronisation pour obtenir des suggestions de contenu personnalisées de la part de Google</translation>
 <translation id="4225895483398857530">Raccourci de la barre d'outils</translation>
 <translation id="4242533952199664413">Ouvrir les paramètres</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Téléchargement…</translation>
 <translation id="4404568932422911380">Aucun favori</translation>
 <translation id="4405224443901389797">Déplacer vers…</translation>
+<translation id="4409271659088619928">Votre moteur de recherche est <ph name="DSE" />. Lisez les instructions pour supprimer l'historique de vos recherches, le cas échéant.</translation>
 <translation id="4411535500181276704">Mode simplifié</translation>
 <translation id="4415276339145661267">Gérer votre compte Google</translation>
 <translation id="4427306783828095590">La protection renforcée assure une meilleure protection contre l'hameçonnage et les logiciels malveillants</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Vérifier les mots de passe</translation>
 <translation id="6000066717592683814">Conserver Google</translation>
 <translation id="6000203700195075278">Se réabonner</translation>
-<translation id="6002623704405939939">Pour effacer l'<ph name="BEGIN_LINK1" />historique des recherches<ph name="END_LINK1" /> ou d'autres historiques, consultez <ph name="BEGIN_LINK2" />Mon activité Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Mot de passe suggéré</translation>
 <translation id="6032091552407840792">Cet essai n'est actif que dans <ph name="BEGIN_LINK" />certaines régions<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Avec <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome développe de nouvelles technologies pour vous protéger contre le suivi intersite tout en préservant le Web ouvert.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">Nom trop long</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# image}one{# image}other{# images}}</translation>
 <translation id="6447558397796644647">Impossible de localiser ce favori. Vérifiez l'orthographe ou ajoutez-en un autre.</translation>
+<translation id="6459045781120991510">Enquêtes</translation>
 <translation id="6461962085415701688">Impossible d'ouvrir le fichier</translation>
 <translation id="6464977750820128603">Vous pouvez voir les sites que vous avez consultés dans Chrome et définir des minuteurs pour ceux-ci.\n\nGoogle obtient des informations sur les sites pour lesquels vous définissez des minuteurs et peut déterminer le temps que vous passez sur ces derniers. Ces informations sont utilisées pour améliorer Bien-être numérique.</translation>
 <translation id="6475951671322991020">Télécharger la vidéo</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Il renforce votre sécurité et celle de tous les utilisateurs sur le Web.</translation>
 <translation id="6618554661997243500">Appuyez sur le bouton d'accueil pour retrouver les meilleurs sites et articles pour vous.</translation>
 <translation id="6627583120233659107">Modifier le dossier</translation>
-<translation id="6635718764393004944">Votre moteur de recherche est <ph name="DSE" />. Le cas échéant, consultez ses instructions pour supprimer votre historique des recherches.</translation>
 <translation id="663674369910034433">Pour accéder à d'autres paramètres liés à la confidentialité, à la sécurité et à la collecte de données, consultez les pages <ph name="BEGIN_LINK1" />Synchronisation<ph name="END_LINK1" /> et <ph name="BEGIN_LINK2" />Services Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Effacer</translation>
 <translation id="6643649862576733715">Trier en fonction de la quantité de données économisées</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">En surbrillance et stylisé, <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Assurez-vous que la synchronisation est activée sur votre <ph name="TARGET_DEVICE_NAME" /> dans Chrome</translation>
 <translation id="7252076891734325316">Posez le téléphone près de l'ordinateur</translation>
+<translation id="727288900855680735">Envoyer <ph name="ONE_TIME_CODE" /> à <ph name="ORIGIN" /> ?</translation>
 <translation id="7274013316676448362">Site bloqué</translation>
 <translation id="7286572596625053347">Modifier <ph name="LANGUAGE" /> ?</translation>
 <translation id="7290209999329137901">Option de changement de nom indisponible</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
index 3e10f87..982ce2a9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calculando...</translation>
 <translation id="1383876407941801731">Buscar</translation>
 <translation id="1384704387250346179">Traducir imaxe con Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Estilizar texto destacado</translation>
 <translation id="1386674309198842382">Dispositivo activo hai <ph name="LAST_UPDATED" />días</translation>
 <translation id="1397811292916898096">Buscar con <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Non facer seguimento</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> (botón <ph name="LINK_NAME" />)</translation>
 <translation id="2000419248597011803">Envía buscas e cookies da barra de enderezos e da caixa de busca ao motor de busca predeterminado</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ficheiro}other{# ficheiros}}</translation>
-<translation id="2017836877785168846">Borra o historial e os completados automáticos na barra de enderezos.</translation>
 <translation id="2021896219286479412">Controis de pantalla completa</translation>
 <translation id="2038563949887743358">Activa a opción Ver como ordenador</translation>
 <translation id="2039379262107991683">Engade páxinas á túa lista de lectura para recibir un recordatorio</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Buscar con Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Abrir en pestana nova</translation>
 <translation id="4198423547019359126">Non hai localizacións de descarga dispoñibles</translation>
-<translation id="4206707945726604465">Para borrar outros historiais, visita <ph name="BEGIN_LINK1" />A miña actividade de Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para recibir contido personalizado suxerido por Google, activa a sincronización</translation>
 <translation id="4225895483398857530">Atallo da barra de ferramentas</translation>
 <translation id="4242533952199664413">Abrir configuración</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: descargando…</translation>
 <translation id="4404568932422911380">Non hai marcadores</translation>
 <translation id="4405224443901389797">Mover a…</translation>
+<translation id="4409271659088619928">O teu motor de busca é <ph name="DSE" />. En caso aplicable, consulta as súas instrucións para eliminar o historial de busca.</translation>
 <translation id="4411535500181276704">Modo básico</translation>
 <translation id="4415276339145661267">Xestionar a túa Conta de Google</translation>
 <translation id="4427306783828095590">A protección mellorada é máis eficaz á hora de bloquear o phishing e o software malicioso</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Comprobar contrasinais</translation>
 <translation id="6000066717592683814">Manter Google</translation>
 <translation id="6000203700195075278">Volver seguir</translation>
-<translation id="6002623704405939939">Para borrar o historial de <ph name="BEGIN_LINK1" />busca<ph name="END_LINK1" /> ou doutros tipos, visita <ph name="BEGIN_LINK2" />A miña actividade de Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Contrasinal suxerido</translation>
 <translation id="6032091552407840792">A proba está dispoñible só <ph name="BEGIN_LINK" />nalgunhas rexións<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Con <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome está desenvolvendo novas tecnoloxías para protexerte dos mecanismos de seguimento en múltiples sitios e para garantir asemade que a Web siga sendo un espazo aberto.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">O nome é demasiado longo</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# imaxe}other{# imaxes}}</translation>
 <translation id="6447558397796644647">Non se puido atopar o marcador. Comproba a ortografía ou engade un marcador novo.</translation>
+<translation id="6459045781120991510">Enquisas</translation>
 <translation id="6461962085415701688">Non se puido abrir o ficheiro</translation>
 <translation id="6464977750820128603">Podes ver os sitios que visitas en Chrome e definirlles temporizadores.\n\nGoogle obtén información sobre os sitios para os que estableces temporizadores e sobre a duración da túa visita. Estes datos utilízanse para mellorar Benestar dixital.</translation>
 <translation id="6475951671322991020">Descargar vídeo</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Mellora a túa seguranza e a do resto dos usuarios da Web.</translation>
 <translation id="6618554661997243500">Tocar botón Inicio para ver os principais sitios e historias recomendados para ti</translation>
 <translation id="6627583120233659107">Editar cartafol</translation>
-<translation id="6635718764393004944">O teu motor de busca é <ph name="DSE" />. En caso aplicable, consulta as súas instrucións para eliminar o historial de busca.</translation>
 <translation id="663674369910034433">Para ver máis opcións de configuración relacionadas coa privacidade, a seguranza e a recompilación de datos, consulta <ph name="BEGIN_LINK1" />Sincronización<ph name="END_LINK1" /> e <ph name="BEGIN_LINK2" />Servizos de Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Borrar</translation>
 <translation id="6643649862576733715">Ordenar por cantidade de datos aforrados</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">Nota estilizada (<ph name="CURRENT_DATE" />)</translation>
 <translation id="7248069434667874558">Asegúrate de que a sincronización de Chrome do dispositivo <ph name="TARGET_DEVICE_NAME" /> estea activada</translation>
 <translation id="7252076891734325316">Coloca o teléfono preto do ordenador</translation>
+<translation id="727288900855680735">Queres enviar <ph name="ONE_TIME_CODE" /> a <ph name="ORIGIN" />?</translation>
 <translation id="7274013316676448362">Bloqueouse o sitio</translation>
 <translation id="7286572596625053347">Queres cambiar o idioma (<ph name="LANGUAGE" />)?</translation>
 <translation id="7290209999329137901">Non está dispoñible a opción de cambiar o nome</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
index 8bc6054a..d7dddc6 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ગણતરી કરી રહ્યાં છે…</translation>
 <translation id="1383876407941801731">શોધો</translation>
 <translation id="1384704387250346179">Google Lensથી છબીનો અનુવાદ કરો <ph name="BEGIN_NEW" />નવું<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">હાઇલાઇટને શૈલીકૃત કરો</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> દિવસ પહેલાં સક્રિય હતું</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> વડે શોધો</translation>
 <translation id="1406000523432664303">“ટ્રેક કરશો નહીં”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> બટન</translation>
 <translation id="2000419248597011803">ઍડ્રેસ બાર અને શોધ બૉક્સમાંથી કેટલીક કુકી અને શોધને તમારા ડિફૉલ્ટ શોધ એંજિન પર મોકલે છે</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ફાઇલ}one{# ફાઇલો}other{# ફાઇલો}}</translation>
-<translation id="2017836877785168846">ઍડ્રેસ બારમાં ઇતિહાસ અને સ્વતઃપૂર્ણ કરવું સાફ કરો.</translation>
 <translation id="2021896219286479412">પૂર્ણ સ્ક્રીન સાઇટ નિયંત્રણો</translation>
 <translation id="2038563949887743358">વિનંતી ડેસ્કટૉપ સાઇટ ચાલુ કરો</translation>
 <translation id="2039379262107991683">રિમાઇન્ડર મેળવવા માટે, તમારી વાંચન સૂચિમાં પેજ ઉમેરો</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google લેન્સ વડે શોધો <ph name="BEGIN_NEW" />નવું<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">નવા ટૅબમાં ખોલો</translation>
 <translation id="4198423547019359126">કોઈ ડાઉનલોડ સ્થાનો ઉપલબ્ધ નથી</translation>
-<translation id="4206707945726604465">ઇતિહાસની અન્ય પ્રકારની માહિતી સાફ કરવા માટે, <ph name="BEGIN_LINK1" />મારી Google પ્રવૃત્તિ<ph name="END_LINK1" />ની મુલાકાત લો</translation>
 <translation id="4209895695669353772">Google દ્વારા સૂચવેલ વ્યક્તિગત કરેલ કન્ટેન્ટ મેળવવા માટે, સિંક કરવાનું ચાલુ કરો</translation>
 <translation id="4225895483398857530">ટૂલબારનો શૉર્ટકટ</translation>
 <translation id="4242533952199664413">સેટિંગ્સ ખોલો</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> ડાઉનલોડ કરી રહ્યાં છીએ…</translation>
 <translation id="4404568932422911380">કોઈ બુકમાર્ક નથી</translation>
 <translation id="4405224443901389797">આમાં ખસેડો…</translation>
+<translation id="4409271659088619928">તમારું શોધ એન્જિન <ph name="DSE" /> છે. જો લાગુ થતી હોય, તો તમારા શોધ ઇતિહાસને ડિલીટ કરવા માટે, તેમની સૂચનાઓ જુઓ.</translation>
 <translation id="4411535500181276704">લાઇટ મોડ</translation>
 <translation id="4415276339145661267">તમારું Google એકાઉન્ટ મેનેજ કરો</translation>
 <translation id="4427306783828095590">વધારેલી સુરક્ષા ફિશિંગ અને માલવેરને બ્લૉક કરવામાં વધુ સહાયરૂપ થાય છે</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">પાસવર્ડ ચેક કરો</translation>
 <translation id="6000066717592683814">Google રાખો</translation>
 <translation id="6000203700195075278">ફરીથી ફૉલો કરો</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />શોધ<ph name="END_LINK1" /> ઇતિહાસ અથવા ઇતિહાસના અન્ય પ્રકારની માહિતી સાફ કરવા માટે <ph name="BEGIN_LINK2" />મારી Google પ્રવૃત્તિ<ph name="END_LINK2" />ની મુલાકાત લો</translation>
 <translation id="6005538289190791541">સૂચવેલ પાસવર્ડ</translation>
 <translation id="6032091552407840792">આ અજમાયશ માત્ર <ph name="BEGIN_LINK" />કેટલાક પ્રદેશો<ph name="END_LINK" />માં સક્રિય છે.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />પ્રાઇવસી સૅન્ડબૉક્સ<ph name="END_LINK" /> વડે, Chrome નવી ટેક્નોલોજીનો વિકાસ કરી રહ્યું છે, જે ખુલ્લી વેબ પર સુરક્ષિત રાખીને, ક્રોસ-સાઇટ ટ્રૅકિંગ સામે તમારું સંરક્ષણ કરે છે.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">નામ ખૂબ લાંબું છે</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# છબી}one{# છબીઓ}other{# છબીઓ}}</translation>
 <translation id="6447558397796644647">તે બુકમાર્ક શોધી શકતા નથી. તમારી જોડણી ચેક કરો અથવા નવું બુકમાર્ક ઉમેરો.</translation>
+<translation id="6459045781120991510">સર્વેક્ષણો</translation>
 <translation id="6461962085415701688">ફાઇલ ખોલી શકતાં નથી</translation>
 <translation id="6464977750820128603">તમે Chromeમાં મુલાકાત લીધેલી સાઇટ જોઈ શકશો અને તેના માટે ટાઇમર પણ સેટ કરી શકશો.\n\nતમે જે સાઇટ માટે ટાઇમર સેટ કરો છો અને કેટલા સમય માટે તેની મુલાકાત લો છો, તે માહિતી Google મેળવે છે. આ માહિતી ડિજિટલ લાઇફસ્ટાઇલને બહેતર બનાવવા માટે ઉપયોગમાં લેવામાં આવે છે.</translation>
 <translation id="6475951671322991020">વીડિયો ડાઉનલોડ કરો</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">વેબ પર તમારા માટે તેમજ પ્રત્યેક માટે સુરક્ષાને બહેતર બનાવે છે.</translation>
 <translation id="6618554661997243500">તમારા માટે શ્રેષ્ઠ હોય તેવી સાઇટ અને સ્ટોરી જોવા માટે હોમ બટન પર ટૅપ કરો</translation>
 <translation id="6627583120233659107">ફોલ્ડરમાં ફેરફાર કરો</translation>
-<translation id="6635718764393004944">તમારું શોધ એન્જિન <ph name="DSE" /> છે. જો લાગુ પડતું હોય, તો તમારો શોધનો ઇતિહાસ ડિલીટ કરવા માટે શોધ એન્જિનની સૂચનાઓ જુઓ.</translation>
 <translation id="663674369910034433">પ્રાઇવસી, સુરક્ષા અને ડેટા સંગ્રહથી સંબંધિત વધુ સેટિંગ માટે, <ph name="BEGIN_LINK1" />સિંક<ph name="END_LINK1" /> અને <ph name="BEGIN_LINK2" />Googleની સેવાઓ<ph name="END_LINK2" /> જુઓ</translation>
 <translation id="6643016212128521049">સાફ કરો</translation>
 <translation id="6643649862576733715">બચાવાયેલ ડેટાના પ્રમાણ અનુસાર સૉર્ટ કરો</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">સ્ટાઇલિશ હાઇલાઇટ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">ખાતરી કરો કે <ph name="TARGET_DEVICE_NAME" />માં Chromeમાં સિંક ચાલુ કરેલું છે</translation>
 <translation id="7252076891734325316">તમારા ફોનને કમ્પ્યુટરની નજીક રાખો</translation>
+<translation id="727288900855680735"><ph name="ONE_TIME_CODE" />ને <ph name="ORIGIN" /> પર સબમિટ કરીએ?</translation>
 <translation id="7274013316676448362">અવરોધિત સાઇટ</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> બદલીએ?</translation>
 <translation id="7290209999329137901">નામ બદલવું ઉપલબ્ધ નથી</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
index b8e57a4..5e12874 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">गणना की जा रही है…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179"><ph name="BEGIN_NEW" />नए<ph name="END_NEW" /> Google Lens से इमेज का अनुवाद करें</translation>
-<translation id="1385855801883526502">हाइलाइट को बेहतर बनाएं</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" />दिन पहले सिंक किया गया</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> के ज़रिए खोजें</translation>
 <translation id="1406000523432664303">“नज़र न रखें”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> बटन</translation>
 <translation id="2000419248597011803">'पता बार' और 'खोज बॉक्स' की कुछ कुकी और खोजों को आपके डिफ़ॉल्ट खोज इंजन पर भेजा जाता है</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# फ़ाइल}one{# फ़ाइलें}other{# फ़ाइलें}}</translation>
-<translation id="2017836877785168846">इतिहास साफ़ करता है और पता बार मेंअपने-आपपूर्णता को साफ़ करता है.</translation>
 <translation id="2021896219286479412">पूरी स्क्रीन के साइट नियंत्रण</translation>
 <translation id="2038563949887743358">अनुरोध डेस्कटॉप साइट चालू करें</translation>
 <translation id="2039379262107991683">अपनी रीडिंग लिस्ट में पेज जोड़ें, ताकि आप उनके बारे में रिमाइंडर पा सकें</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens से खोजें <ph name="BEGIN_NEW" />नया<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">नए टैब में खोलें</translation>
 <translation id="4198423547019359126">डाउनलोड करने की कोई जगह उपलब्ध नहीं है</translation>
-<translation id="4206707945726604465">अन्य तरह के इतिहास को मिटाने के लिए, <ph name="BEGIN_LINK1" />मेरी Google गतिविधि<ph name="END_LINK1" /> पर जाएं</translation>
 <translation id="4209895695669353772">Google की ओर से सुझाई गई मनमुताबिक सामग्री पाने के लिए, 'सिंक करें' को चालू करें</translation>
 <translation id="4225895483398857530">Toolbar का शॉर्टकट</translation>
 <translation id="4242533952199664413">सेटिंग खोलें</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - डाउनलोड हो रही है…</translation>
 <translation id="4404568932422911380">कोई बुकमार्क नहीं</translation>
 <translation id="4405224443901389797">इसमें ले जाएं…</translation>
+<translation id="4409271659088619928">आपका सर्च इंजन <ph name="DSE" /> है. अगर लागू होता है, तो अपना खोज इतिहास मिटाने के लिए निर्देश देखें.</translation>
 <translation id="4411535500181276704">लाइट मोड</translation>
 <translation id="4415276339145661267">अपना Google खाता प्रबंधित करें</translation>
 <translation id="4427306783828095590">बेहतर सुरक्षा की मदद से फ़िशिंग और मैलवेयर को बेहतर तरीके से ब्लॉक किया जाता है</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">पासवर्ड जांचें</translation>
 <translation id="6000066717592683814">Google को डिफ़ॉल्ट बनाए रखें</translation>
 <translation id="6000203700195075278">फिर से फ़ॉलो करें</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />खोज इतिहास<ph name="END_LINK1" /> या किसी और तरह की गतिविधि का इतिहास मिटाने के लिए, <ph name="BEGIN_LINK2" />मेरी Google गतिविधि<ph name="END_LINK2" /> पर जाएं</translation>
 <translation id="6005538289190791541">सुझाया गया पासवर्ड</translation>
 <translation id="6032091552407840792">मुफ़्त में आज़माने की यह सुविधा सिर्फ़ <ph name="BEGIN_LINK" />कुछ क्षेत्रों<ph name="END_LINK" /> में चालू है.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />निजता सैंडबॉक्स<ph name="END_LINK" /> की मदद से Chrome एक नई टेक्नोलॉजी डेवलप कर रहा है. यह टेक्नोलॉजी ओपन वेब को सुरक्षित रखते हुए, आपको क्रॉस-साइट ट्रैकिंग से बचाने में मदद करेगी.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">यह सुविधा, वेब पर आपकी और सभी उपयोगकर्ताओं की सुरक्षा को बेहतर बनाती है.</translation>
 <translation id="6618554661997243500">अपने हिसाब से खास साइटें और खबरें देखने के लिए, होम बटन पर टैप करें</translation>
 <translation id="6627583120233659107">फ़ोल्‍डर में बदलाव करें</translation>
-<translation id="6635718764393004944">आपका सर्च इंजन <ph name="DSE" /> है. अगर लागू हो, तो अपना खोज इतिहास मिटाने के लिए, उनके निर्देश देखें.</translation>
 <translation id="663674369910034433">निजता, सुरक्षा और डेटा इकट्ठा करने से जुड़ी ज़्यादा सेटिंग के लिए, <ph name="BEGIN_LINK1" />सिंक करें<ph name="END_LINK1" /> और <ph name="BEGIN_LINK2" />Google की सेवाएं<ph name="END_LINK2" /> देखें</translation>
 <translation id="6643016212128521049">साफ़ करें</translation>
 <translation id="6643649862576733715">सेव किए गए डेटा की मात्रा के हिसाब से क्रम में लगाएं</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
index ea281ec..7f7f07c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Izračunavanje…</translation>
 <translation id="1383876407941801731">Traži</translation>
 <translation id="1384704387250346179">Prevedite sliku pomoću Objektiva <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stiliziraj isticanje</translation>
 <translation id="1386674309198842382">Aktivan prije <ph name="LAST_UPDATED" /> dana</translation>
 <translation id="1397811292916898096">Pretraživanje pomoću usluge <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Nemoj pratiti"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Gumb <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Zadanoj tražilici šalje neke kolačiće i pretraživanja iz adresne trake i okvira za pretraživanje</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# datoteka}one{# datoteka}few{# datoteke}other{# datoteka}}</translation>
-<translation id="2017836877785168846">Briše povijest i automatsko dovršavanje u adresnoj traci.</translation>
 <translation id="2021896219286479412">Kontrole web-lokacije na cijelom zaslonu</translation>
 <translation id="2038563949887743358">Uključivanje zahtjeva za prikaz klasične web-lokacije</translation>
 <translation id="2039379262107991683">Dodajte stranice na popis za čitanje da biste dobili podsjetnik</translation>
@@ -489,8 +487,8 @@
 <translation id="4181841719683918333">Jezici</translation>
 <translation id="4183868528246477015">Pretraži pomoću Google objektiva <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otvori na novoj kartici</translation>
+<translation id="4196597275619698563">Izradi karticu</translation>
 <translation id="4198423547019359126">Lokacije preuzimanja nisu dostupne</translation>
-<translation id="4206707945726604465">Da biste izbrisali druge oblike povijesti, posjetite stranicu <ph name="BEGIN_LINK1" />Moje aktivnosti na Googleu<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Uključite sinkronizaciju ako želite da vam Google predlaže prilagođene sadržaje</translation>
 <translation id="4225895483398857530">Prečac alatne trake</translation>
 <translation id="4242533952199664413">Otvori postavke</translation>
@@ -514,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – preuzimanje…</translation>
 <translation id="4404568932422911380">Bez oznaka</translation>
 <translation id="4405224443901389797">Premjesti u…</translation>
+<translation id="4409271659088619928">Vaša je tražilica <ph name="DSE" />. Potražite njezine upute da biste saznali kako izbrisati svoju povijest pretraživanja, ako je primjenjivo.</translation>
 <translation id="4411535500181276704">Jednostavni način</translation>
 <translation id="4415276339145661267">Upravljajte svojim Google računom</translation>
 <translation id="4427306783828095590">Poboljšana zaštita blokira krađu identiteta i zlonamjerni softver na više načina</translation>
@@ -773,7 +772,6 @@
 <translation id="5979084224081478209">Provjeri zaporke</translation>
 <translation id="6000066717592683814">Zadrži Google</translation>
 <translation id="6000203700195075278">Pratite ponovo</translation>
-<translation id="6002623704405939939">Da biste izbrisali <ph name="BEGIN_LINK1" />pretraživanja<ph name="END_LINK1" /> ili neku drugu povijest, posjetite stranicu <ph name="BEGIN_LINK2" />Moje aktivnosti na Googleu<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Predložena zaporka</translation>
 <translation id="6032091552407840792">Proba je aktivna samo u <ph name="BEGIN_LINK" />nekim regijama<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Uz <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> Chrome razvija nove tehnologije koje će vas štititi od praćenja na različitim web-lokacijama, a istovremeno očuvati otvorenost weba.
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Poboljšava sigurnost za vas i sve ostale na webu.</translation>
 <translation id="6618554661997243500">Za prikaz web-lokacija koje najčešće posjećujete i vijesti prilagođenih vama dodirnite gumb početnog zaslona</translation>
 <translation id="6627583120233659107">Uredi mapu</translation>
-<translation id="6635718764393004944">Vaša tražilica je <ph name="DSE" />. Ako je primjenjivo, pročitajte upute da biste izbrisali svoju povijest pretraživanja.</translation>
 <translation id="663674369910034433">Više postavki koje se odnose na privatnost, sigurnost i prikupljanje podataka dostupno je u odjeljcima <ph name="BEGIN_LINK1" />Sinkronizacija<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />Googleove usluge<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Izbriši</translation>
 <translation id="6643649862576733715">Poredaj po količini spremljenih podataka</translation>
@@ -1049,6 +1046,7 @@
 <translation id="7704317875155739195">Samodovršavanje pretraživanja i URL-ova</translation>
 <translation id="7707922173985738739">Upotreba mobilnih podataka</translation>
 <translation id="7725024127233776428">Ovdje se prikazuju stranice koje označite</translation>
+<translation id="7731260005404856143"><ph name="BEGIN_LINK1" />Ostali oblici aktivnosti<ph name="END_LINK1" /> mogu se spremati na vaš Google račun kad ste prijavljeni. Možete ih izbrisati kad god želite.</translation>
 <translation id="7757787379047923882">Tekst dijeljen s uređaja <ph name="DEVICE_NAME" /></translation>
 <translation id="7761849928583394409">Odaberite datum i vrijeme</translation>
 <translation id="7762668264895820836">SD kartica <ph name="SD_CARD_NUMBER" /></translation>
@@ -1239,6 +1237,7 @@
 <translation id="8854223127042600341">Prikaz offline datoteka</translation>
 <translation id="8856607253650333758">Primite opise</translation>
 <translation id="8873817150012960745">Dodirnite ovdje da biste započeli</translation>
+<translation id="8881973373982641723">Briše povijest, uključujući u okviru za pretraživanje.</translation>
 <translation id="889338405075704026">Otvorite Chromeove postavke</translation>
 <translation id="8898822736010347272">Šalje URL-ove određenih stranica koje posjećujete, ograničene podatke o sustavu i sadržaj određenih stranica Googleu kako bi se pomoglo pri otkrivanju novih prijetnji i kako bi se zaštitili svi korisnici na webu.</translation>
 <translation id="8909135823018751308">Dijeljenje…</translation>
@@ -1292,6 +1291,7 @@
 <translation id="9209888181064652401">Upućivanje poziva nije moguće</translation>
 <translation id="9212845824145208577">Ne možete ići niže. Pokušajte započeti na nižem mjestu na stranici.</translation>
 <translation id="9219103736887031265">Slike</translation>
+<translation id="923957533152125119"><ph name="BEGIN_LINK1" />Povijest pretraživanja<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />drugi oblici aktivnosti<ph name="END_LINK2" /> mogu se spremati na vaš Google račun kad ste prijavljeni. Možete ih izbrisati kad god želite.</translation>
 <translation id="926205370408745186">Uklanjanje vaše aktivnosti u Chromeu iz Digitalne ravnoteže</translation>
 <translation id="927968626442779827">Koristite Jednostavni način na Google Chromeu</translation>
 <translation id="932327136139879170">Početna stranica</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
index 6a0c40d..acac7310 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Számítás…</translation>
 <translation id="1383876407941801731">Keresés</translation>
 <translation id="1384704387250346179">Google Lens-képfordítás <ph name="BEGIN_NEW" />Új<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Kiemelés stilizálása</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> napja volt aktív</translation>
 <translation id="1397811292916898096">Keresés a(z) <ph name="PRODUCT_NAME" /> keresőmotorral</translation>
 <translation id="1406000523432664303">„Nincs nyomon követés”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> gomb</translation>
 <translation id="2000419248597011803">Bizonyos cookie-kat és kereséseket küld a címsávból és a keresőmezőből az alapértelmezett keresőmotornak</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fájl}other{# fájl}}</translation>
-<translation id="2017836877785168846">Törli a címsávban található előzményeket és automatikus kiegészítéseket.</translation>
 <translation id="2021896219286479412">Teljes képernyős oldal vezérlői</translation>
 <translation id="2038563949887743358">Kapcsolja be az Asztali webhely kérése funkciót</translation>
 <translation id="2039379262107991683">Ha értesítést szeretne kapni, adja hozzá az oldalakat az Olvasólistához</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Keresés a Google Lensszel <ph name="BEGIN_NEW" />Új<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Megnyitás új lapon</translation>
 <translation id="4198423547019359126">Nem áll rendelkezésre letöltési hely</translation>
-<translation id="4206707945726604465">További előzményfajták törléséhez keresse fel a <ph name="BEGIN_LINK1" />Saját Google-tevékenységek<ph name="END_LINK1" /> oldalát.</translation>
 <translation id="4209895695669353772">A Google által javasolt, személyre szabott tartalmak fogadásához kapcsolja be a szinkronizálást</translation>
 <translation id="4225895483398857530">Eszköztár gyorsparancs</translation>
 <translation id="4242533952199664413">Beállítások megnyitása</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Letöltés…</translation>
 <translation id="4404568932422911380">Nincsenek könyvjelzők</translation>
 <translation id="4405224443901389797">Áthelyezés…</translation>
+<translation id="4409271659088619928">Az Ön keresőmotorja a következő: <ph name="DSE" />. A keresési előzmények törléséről a keresőmotorja útmutatójából tájékozódhat, ha van ilyen.</translation>
 <translation id="4411535500181276704">Egyszerűsített mód</translation>
 <translation id="4415276339145661267">Google-fiók kezelése</translation>
 <translation id="4427306783828095590">A Speciális védelem még többet tesz annak érdekében, hogy letiltsa az adathalászatot és a rosszindulatú programokat</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Jelszavak ellenőrzése</translation>
 <translation id="6000066717592683814">A Google megtartása</translation>
 <translation id="6000203700195075278">Újrakövetés</translation>
-<translation id="6002623704405939939">A <ph name="BEGIN_LINK1" />keresések<ph name="END_LINK1" /> vagy más előzmények törléséhez keresse fel a <ph name="BEGIN_LINK2" />Saját Google-tevékenységek<ph name="END_LINK2" /> oldalt</translation>
 <translation id="6005538289190791541">Javasolt jelszó</translation>
 <translation id="6032091552407840792">Ez a próbaverzió csak <ph name="BEGIN_LINK" />egyes régiókban áll rendelkezésre<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">A <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> révén a Chrome olyan új technológiákat fejlesztünk, melyek megvédik Önt a nyomon követési mechanizmusoktól, miközben megőrzik a web nyitottságát.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Javítja az Ön és mindenki más biztonságát az interneten.</translation>
 <translation id="6618554661997243500">Ha szeretné megtekinteni a legkedveltebb webhelyeit és a legfrissebb híreket, koppintson a Kezdőképernyő gombra</translation>
 <translation id="6627583120233659107">Mappa szerkesztése</translation>
-<translation id="6635718764393004944">Az Ön keresőmotorja a következő: <ph name="DSE" />. Adott esetben tekintse meg az utasításokat a keresési előzmények törléséhez.</translation>
 <translation id="663674369910034433">A <ph name="BEGIN_LINK1" />Szinkronizálás<ph name="END_LINK1" /> és a <ph name="BEGIN_LINK2" />Google-szolgáltatások<ph name="END_LINK2" /> részben további beállításokat talál az adatvédelemre, biztonságra és adatgyűjtésre vonatkozóan.</translation>
 <translation id="6643016212128521049">Törlés</translation>
 <translation id="6643649862576733715">Rendezés a megtakarított adatmennyiség szerint</translation>
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 8378192..b243866 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Հաշվարկ...</translation>
 <translation id="1383876407941801731">Որոնում</translation>
 <translation id="1384704387250346179">Թարգմանել Տեսապակու միջոցով <ph name="BEGIN_NEW" />Նոր<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Ոճավորել ընդգծված տեքստը</translation>
 <translation id="1386674309198842382">Ակտիվ է եղել <ph name="LAST_UPDATED" /> օր առաջ</translation>
 <translation id="1397811292916898096">Որոնում <ph name="PRODUCT_NAME" />-ում</translation>
 <translation id="1406000523432664303">«Չհետևել»</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Ձեր կանխադրված որոնիչին է ուղարկում հասցեագոտու և որոնման դաշտի հարցումները, ինչպես նաև որոշ քուքիներ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ֆայլ}one{# ֆայլ}other{# ֆայլ}}</translation>
-<translation id="2017836877785168846">Մաքրում է պատմությունն ու հասցեագոտու ինքնալրացումները:</translation>
 <translation id="2021896219286479412">Լիաէկրան ռեժիմի կարգավորումներ</translation>
 <translation id="2038563949887743358">Միացնել կայքի ամբողջական տարբերակը</translation>
 <translation id="2039379262107991683">Դուք կարող եք ձեր Ընթերցանության ցանկում ավելացնել էջեր՝ հիշեցումներ ստանալու համար</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Որոնել Տեսապակու միջոցով <ph name="BEGIN_NEW" />Նոր<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Բացել նոր ներդիրով</translation>
 <translation id="4198423547019359126">Ներբեռնումների պանակներ չկան</translation>
-<translation id="4206707945726604465">Պատմությունից այլ տվյալներ ջնջելու համար այցելեք <ph name="BEGIN_LINK1" />Իմ գործողությունները Google-ում<ph name="END_LINK1" /> էջ</translation>
 <translation id="4209895695669353772">Google-ից անհատականացված բովանդակություն ստանալու համար միացրեք համաժամացումը</translation>
 <translation id="4225895483398857530">Գործիքագոտու դյուրանցում</translation>
 <translation id="4242533952199664413">Բացել կարգավորումները</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546">Ներբեռնվում է <ph name="LANG" /> լեզվի փաթեթը…</translation>
 <translation id="4404568932422911380">Էջանիշներ չկան</translation>
 <translation id="4405224443901389797">Տեղափոխել…</translation>
+<translation id="4409271659088619928">Դուք օգտագործում եք <ph name="DSE" /> որոնողական համակարգը։ Որոնումների պատմությունը ջնջելու համար կարդացեք համապատասխան ցուցումները։</translation>
 <translation id="4411535500181276704">Lite ռեժիմ</translation>
 <translation id="4415276339145661267">Կառավարել Google հաշիվը</translation>
 <translation id="4427306783828095590">Լրացուցիչ պաշտպանությունն օգնում է խուսափել ֆիշինգից և արգելափակել վնասաբեր ծրագրերը</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Ստուգել գաղտնաբառերը</translation>
 <translation id="6000066717592683814">Օգտագործել Google-ը</translation>
 <translation id="6000203700195075278">Նորից բաժանորդագրվել</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Որոնման հարցումները<ph name="END_LINK1" /> կամ ձեր գործողությունների հետ կապված այլ տվյալներ ջնջելու համար անցեք <ph name="BEGIN_LINK2" />«Իմ գործողությունները Google-ում»<ph name="END_LINK2" /> էջ։</translation>
 <translation id="6005538289190791541">Առաջարկվող գաղտնաբառ</translation>
 <translation id="6032091552407840792">Այս փորձնական գործառույթը հասանելի է միայն <ph name="BEGIN_LINK" />որոշ տարածաշրջաններում<ph name="END_LINK" />։</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />-ի օգնությամբ Chrome-ը մշակում է նոր տեխնոլոգիաներ, որոնք պաշտպանում են ձեզ գործողությունների միջկայքային հետագծման մեխանիզմներից։
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Համացանցը դարձնում է ավելի անվտանգ ձեր և մյուս օգտատերերի համար։</translation>
 <translation id="6618554661997243500">Ձեր թոփ կայքերն ու հոդվածները տեսնելու համար սեղմեք գլխավոր էկրանի կոճակը</translation>
 <translation id="6627583120233659107">Փոփոխել պանակը</translation>
-<translation id="6635718764393004944">Դուք օգտագործում եք <ph name="DSE" /> որոնման համակարգը։ Անհրաժեշտության դեպքում դիտեք, թե ինչպես համակարգի ցուցումներում ջնջել որոնումների պատմությունը։</translation>
 <translation id="663674369910034433">Գաղտնիության, անվտանգության և տվյալների հավաքման հետ կապված լրացուցիչ կարգավորումներին կարող եք ծանոթանալ <ph name="BEGIN_LINK1" />Համաժամացում<ph name="END_LINK1" /> և <ph name="BEGIN_LINK2" />Google-ի ծառայություններ<ph name="END_LINK2" /> բաժիններում։</translation>
 <translation id="6643016212128521049">Մաքրել</translation>
 <translation id="6643649862576733715">Դասավորել ըստ պահված տվյալների ծավալի</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
index 532f43d..52bd0a6 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Menghitung…</translation>
 <translation id="1383876407941801731">Telusuri</translation>
 <translation id="1384704387250346179">Terjemahkan gambar dengan Google Lens <ph name="BEGIN_NEW" />Baru<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Sesuaikan gaya sorotan</translation>
 <translation id="1386674309198842382">Aktif <ph name="LAST_UPDATED" /> hari lalu</translation>
 <translation id="1397811292916898096">Telusuri dengan <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Jangan Lacak”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Tombol <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Mengirimkan beberapa cookie dan penelusuran dari kolom URL dan kotak penelusuran ke mesin telusur default</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# File}other{# File}}</translation>
-<translation id="2017836877785168846">Hapus histori dan pelengkapan otomatis di kolom URL.</translation>
 <translation id="2021896219286479412">Kontrol situs layar penuh</translation>
 <translation id="2038563949887743358">Aktifkan Ubah situs desktop</translation>
 <translation id="2039379262107991683">Tambahkan halaman ke Daftar Bacaan untuk mendapatkan pengingat</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Telusuri dgn Google Lens <ph name="BEGIN_NEW" />Baru<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Buka di tab baru</translation>
 <translation id="4198423547019359126">Tidak tersedia lokasi download</translation>
-<translation id="4206707945726604465">Untuk menghapus bentuk histori lainnya, buka <ph name="BEGIN_LINK1" />Aktivitas Google Saya<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Untuk mendapatkan konten hasil personalisasi yang disarankan oleh Google, aktifkan sinkronisasi</translation>
 <translation id="4225895483398857530">Pintasan toolbar</translation>
 <translation id="4242533952199664413">Buka setelan</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Sedang Mendownload…</translation>
 <translation id="4404568932422911380">Tidak ada bookmark</translation>
 <translation id="4405224443901389797">Pindahkan ke…</translation>
+<translation id="4409271659088619928">Mesin telusur Anda adalah <ph name="DSE" />. Lihat petunjuknya untuk menghapus histori penelusuran Anda, jika memungkinkan.</translation>
 <translation id="4411535500181276704">Mode Ringan</translation>
 <translation id="4415276339145661267">Kelola Akun Google Anda</translation>
 <translation id="4427306783828095590">Perlindungan yang disempurnakan akan memblokir phishing dan malware dengan lebih optimal</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Periksa sandi</translation>
 <translation id="6000066717592683814">Tetap menggunakan Google</translation>
 <translation id="6000203700195075278">Ikuti kembali</translation>
-<translation id="6002623704405939939">Untuk menghapus <ph name="BEGIN_LINK1" />penelusuran<ph name="END_LINK1" /> atau bentuk histori lainnya, buka <ph name="BEGIN_LINK2" />Aktivitas Google Saya<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Sandi yang disarankan</translation>
 <translation id="6032091552407840792">Uji coba ini hanya aktif di <ph name="BEGIN_LINK" />beberapa wilayah<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Dengan <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome mengembangkan teknologi baru untuk mengamankan Anda dari pelacakan lintas situs sekaligus mempertahankan web terbuka.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Meningkatkan keamanan untuk Anda dan semua orang di web.</translation>
 <translation id="6618554661997243500">Untuk melihat situs dan artikel teratas untuk Anda, ketuk tombol Beranda</translation>
 <translation id="6627583120233659107">Edit folder</translation>
-<translation id="6635718764393004944">Mesin telusur Anda adalah <ph name="DSE" />. Jika berlaku, lihat petunjuknya untuk menghapus histori penelusuran Anda.</translation>
 <translation id="663674369910034433">Untuk setelan lainnya yang berkaitan dengan privasi, keamanan, dan pengumpulan data, lihat <ph name="BEGIN_LINK1" />Sinkronisasi<ph name="END_LINK1" /> dan <ph name="BEGIN_LINK2" />Layanan Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Hapus</translation>
 <translation id="6643649862576733715">Urutkan menurut jumlah kuota yang dihemat</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
index 659c51a95..6307885 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Reiknar…</translation>
 <translation id="1383876407941801731">Leita</translation>
 <translation id="1384704387250346179">Þýða mynd með Google linsu <ph name="BEGIN_NEW" />Nýtt<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stílfæra áhersluatriði</translation>
 <translation id="1386674309198842382">Virkt fyrir <ph name="LAST_UPDATED" /> dögum</translation>
 <translation id="1397811292916898096">Leita með <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Ekki rekja“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> hnappur</translation>
 <translation id="2000419248597011803">Sendir sum fótspor og sumar leitir úr veffangastikunni og leitarreitnum í sjálfgefnu leitarvélina þína</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# skrá}one{# skrá}other{# skrár}}</translation>
-<translation id="2017836877785168846">Hreinsar ferilinn og sjálfvirka útfyllingu í veffangastiku.</translation>
 <translation id="2021896219286479412">Stýringar vefsvæðis á öllum skjá</translation>
 <translation id="2038563949887743358">Kveikja á beiðni um vefsvæði fyrir tölvur</translation>
 <translation id="2039379262107991683">Bættu síðum við leslistann þinn til að fá áminningu</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Leita með Google linsu <ph name="BEGIN_NEW" />Nýtt<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Opna í nýjum flipa</translation>
 <translation id="4198423547019359126">Engar tiltækar niðurhalsstaðsetningar</translation>
-<translation id="4206707945726604465">Farðu í <ph name="BEGIN_LINK1" />Google virkni mín<ph name="END_LINK1" /> til að hreinsa aðra ferla</translation>
 <translation id="4209895695669353772">Kveiktu á samstillingu til að fá sérsniðið efni sem Google stingur upp á</translation>
 <translation id="4225895483398857530">Flýtileið á tækjastiku</translation>
 <translation id="4242533952199664413">Opna stillingar</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Sækir…</translation>
 <translation id="4404568932422911380">Engin bókamerki</translation>
 <translation id="4405224443901389797">Færa í…</translation>
+<translation id="4409271659088619928">Leitarvélin þín er <ph name="DSE" />. Skoðaðu leiðbeiningar hennar um að eyða leitarferlinum ef það á við.</translation>
 <translation id="4411535500181276704">Léttútgáfa</translation>
 <translation id="4415276339145661267">Stjórna Google reikningnum</translation>
 <translation id="4427306783828095590">Aukin vernd gengur lengra í að loka á vefveiðar og spilliforrit</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Yfirfara aðgangsorð</translation>
 <translation id="6000066717592683814">Nota Google áfram</translation>
 <translation id="6000203700195075278">Fylgja aftur</translation>
-<translation id="6002623704405939939">Til að hreinsa <ph name="BEGIN_LINK1" />leit<ph name="END_LINK1" /> eða aðra ferla skaltu fara í <ph name="BEGIN_LINK2" />Google virkni mín<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Útbúið aðgangsorð</translation>
 <translation id="6032091552407840792">Þessi prufuútgáfa er aðeins virk á <ph name="BEGIN_LINK" />sumum svæðum<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Chrome notar <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> til að þróa nýja tækni sem verndar þig fyrir rakningartækni en varðveitir á sama tíma opna vefinn.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Eykur öryggi þitt og allra á vefnum.</translation>
 <translation id="6618554661997243500">Ýttu á heimahnappinn til að sjá mest sóttu vefsvæðin og sögur fyrir þig</translation>
 <translation id="6627583120233659107">Breyta möppu</translation>
-<translation id="6635718764393004944">Leitarvélin þín er <ph name="DSE" />. Skoðaðu leiðbeiningar hennar til að eyða leitarferlinum þínum, ef slíkt á við.</translation>
 <translation id="663674369910034433">Frekari upplýsingar sem tengjast persónuvernd, öryggi og gagnasöfnun má finna í <ph name="BEGIN_LINK1" />Samstilling<ph name="END_LINK1" /> og <ph name="BEGIN_LINK2" />Google þjónustur<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Hreinsa</translation>
 <translation id="6643649862576733715">Raða eftir gagnasparnaði</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
index 4d0a6238..5951dfc8 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Elaborazione...</translation>
 <translation id="1383876407941801731">Cerca</translation>
 <translation id="1384704387250346179">Traduci l'immagine con Google Lens <ph name="BEGIN_NEW" />Novità<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizza evidenziazione</translation>
 <translation id="1386674309198842382">Attivo <ph name="LAST_UPDATED" /> giorni fa</translation>
 <translation id="1397811292916898096">Cerca con <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Non tenere traccia</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> pulsante <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Invia al tuo motore di ricerca predefinito alcune ricerche dalla barra degli indirizzi e dalla casella di ricerca, nonché alcuni cookie</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# file}other{# file}}</translation>
-<translation id="2017836877785168846">Consente di cancellare la cronologia e i completamenti automatici nella barra degli indirizzi.</translation>
 <translation id="2021896219286479412">Controlli sito a schermo intero</translation>
 <translation id="2038563949887743358">Attiva Richiedi sito desktop</translation>
 <translation id="2039379262107991683">Aggiungi pagine al tuo Elenco di lettura per ricevere un promemoria</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Cerca con Google Lens <ph name="BEGIN_NEW" />Novità<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Apri in un'altra scheda</translation>
 <translation id="4198423547019359126">Nessun percorso di download disponibile</translation>
-<translation id="4206707945726604465">Per cancellare altri tipi di cronologia, visita <ph name="BEGIN_LINK1" />Le mie attività Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Per ricevere contenuti suggeriti appositamente per te da Google, attiva la sincronizzazione</translation>
 <translation id="4225895483398857530">Scorciatoia per la barra degli strumenti</translation>
 <translation id="4242533952199664413">Apri le impostazioni</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: download in corso…</translation>
 <translation id="4404568932422911380">Nessun preferito</translation>
 <translation id="4405224443901389797">Sposta in…</translation>
+<translation id="4409271659088619928">Il tuo motore di ricerca è <ph name="DSE" />. Consulta le relative istruzioni per eliminare la tua cronologia delle ricerche, se applicabile.</translation>
 <translation id="4411535500181276704">Modalità Lite</translation>
 <translation id="4415276339145661267">Gestisci il tuo Account Google</translation>
 <translation id="4427306783828095590">La protezione avanzata blocca malware e tentativi di phishing con maggiore efficacia</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Controlla password</translation>
 <translation id="6000066717592683814">Mantieni Google</translation>
 <translation id="6000203700195075278">Segui di nuovo</translation>
-<translation id="6002623704405939939">Per cancellare la cronologia delle <ph name="BEGIN_LINK1" />ricerche<ph name="END_LINK1" /> o altri tipi di cronologia, visita la pagina <ph name="BEGIN_LINK2" />Le mie attività Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Password consigliata</translation>
 <translation id="6032091552407840792">Questa prova è attiva soltanto in <ph name="BEGIN_LINK" />alcune aree geografiche<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Con <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome sviluppa nuove tecnologie che ti tutelano dai meccanismi di tracciamento tra siti salvaguardando al contempo il Web aperto.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Migliora il livello di sicurezza per te e per chiunque sul Web.</translation>
 <translation id="6618554661997243500">Per vedere notizie e siti principali personalizzati, tocca il pulsante Home</translation>
 <translation id="6627583120233659107">Modifica cartella</translation>
-<translation id="6635718764393004944">Il tuo motore di ricerca è <ph name="DSE" />. Se pertinente, leggi le relative istruzioni per eliminare la cronologia delle ricerche.</translation>
 <translation id="663674369910034433">Per altre impostazioni relative a privacy, sicurezza e raccolta dei dati, consulta le sezioni <ph name="BEGIN_LINK1" />Sincronizzazione<ph name="END_LINK1" /> e <ph name="BEGIN_LINK2" />Servizi Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Cancella</translation>
 <translation id="6643649862576733715">Ordina per quantità di dati risparmiati</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 27ccb79..a3fb84d 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">מחשב...</translation>
 <translation id="1383876407941801731">חיפוש</translation>
 <translation id="1384704387250346179">‏תרגום תמונה באמצעות Google Lens‏ <ph name="BEGIN_NEW" />חדש<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">עיצוב ההדגשה</translation>
 <translation id="1386674309198842382">פעילות אחרונה: לפני <ph name="LAST_UPDATED" /> ימים</translation>
 <translation id="1397811292916898096">חיפוש באמצעות <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">‏'לא לעקוב (DNT)'</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> לחצן <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">‏שליחה של חלק מקובצי ה-Cookie והחיפושים משורת כתובת האתר ומתיבת החיפוש אל מנוע החיפוש שהוגדר כברירת מחדל</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{קובץ אחד (#)}two{# קבצים}many{# קבצים}other{# קבצים}}</translation>
-<translation id="2017836877785168846">ניקוי של ההיסטוריה וההשלמות האוטומטיות בסרגל הכתובות</translation>
 <translation id="2021896219286479412">פקדי אתר במסך מלא</translation>
 <translation id="2038563949887743358">הפעלה של 'בקשת אתר עבור מחשב שולחני'</translation>
 <translation id="2039379262107991683">יש להוסיף דפים לרשימת הקריאה כדי לקבל תזכורת</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">‏חיפוש בעזרת Google Lens <ph name="BEGIN_NEW" />חדש<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">פתיחה בכרטיסייה חדשה</translation>
 <translation id="4198423547019359126">אין מיקומים זמינים להורדה</translation>
-<translation id="4206707945726604465">‏יש לך אפשרות למחוק היסטוריה מסוגים אחרים בדף <ph name="BEGIN_LINK1" />הפעילות שלי ב-Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">‏כדי לקבל מ-Google הצעות לתוכן מותאם אישית, יש להפעיל את הסנכרון</translation>
 <translation id="4225895483398857530">קיצור דרך בסרגל הכלים</translation>
 <translation id="4242533952199664413">פתיחת ההגדרות</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ההורדה מתבצעת…</translation>
 <translation id="4404568932422911380">ללא סימניות</translation>
 <translation id="4405224443901389797">העברה אל…</translation>
+<translation id="4409271659088619928">מנוע החיפוש שלך הוא <ph name="DSE" />. ניתן לעיין בהוראות שלו לגבי מחיקת היסטוריית החיפושים, אם רלוונטי.</translation>
 <translation id="4411535500181276704">מצב טעינה מהירה</translation>
 <translation id="4415276339145661267">‏ניהול חשבון Google שלך</translation>
 <translation id="4427306783828095590">עם ההגנה המשופרת, החסימה של פישינג ותוכנות זדוניות מקיפה יותר</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">בדיקת הסיסמאות</translation>
 <translation id="6000066717592683814">‏להמשיך להשתמש ב-Google</translation>
 <translation id="6000203700195075278">מעקב מחודש</translation>
-<translation id="6002623704405939939">‏כדי לנקות את <ph name="BEGIN_LINK1" />החיפוש<ph name="END_LINK1" /> או היסטוריה מסוגים אחרים, יש לעבור אל <ph name="BEGIN_LINK2" />הפעילות שלי ב-Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">הצעה לסיסמה</translation>
 <translation id="6032091552407840792">תקופת הניסיון הזו פעילה רק ב<ph name="BEGIN_LINK" />אזורים מסוימים<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">‏באמצעות <ph name="BEGIN_LINK" />ארגז חול לפרטיות<ph name="END_LINK" />, מפתחים ב-Chrome טכנולוגיות חדשות שמגינות עליך מפני מעקב באתרים שונים תוך שמירה על האופי הפתוח של רשת האינטרנט.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">רמת אבטחה משופרת עבורך ועבור כל מי שמתחבר לאינטרנט.</translation>
 <translation id="6618554661997243500">להצגת הכתבות והאתרים המובילים שלך, יש להקיש על הלחצן הראשי</translation>
 <translation id="6627583120233659107">עריכת התיקייה</translation>
-<translation id="6635718764393004944">מנוע החיפוש שלך הוא <ph name="DSE" />. אם יש הוראות לגביו, יש לעיין בהן כדי למחוק את היסטוריית החיפושים.</translation>
 <translation id="663674369910034433">‏אפשר למצוא הגדרות נוספות בנושא פרטיות, אבטחה ואיסוף נתונים בדפים <ph name="BEGIN_LINK1" />סנכרון<ph name="END_LINK1" /> ו<ph name="BEGIN_LINK2" />שירותי Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">ניקוי</translation>
 <translation id="6643649862576733715">מיון לפי כמות הנתונים שנחסכו</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
index 98539b0c..f8e3b5c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">計算中...</translation>
 <translation id="1383876407941801731">検索</translation>
 <translation id="1384704387250346179">Google レンズで画像を翻訳 <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">選択箇所のスタイルを設定</translation>
 <translation id="1386674309198842382">最終同期: <ph name="LAST_UPDATED" /> 日前</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> で検索</translation>
 <translation id="1406000523432664303">「トラッキング拒否」</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ボタン</translation>
 <translation id="2000419248597011803">Cookie と、アドレスバーや検索ボックスに入力した検索語句を既定の検索エンジンに送信します</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# 件のファイル}other{# 件のファイル}}</translation>
-<translation id="2017836877785168846">アドレスバーの履歴とオートコンプリート データを削除します。</translation>
 <translation id="2021896219286479412">全画面表示時のサイトの操作項目</translation>
 <translation id="2038563949887743358">[PC 版サイトを見る] をオンにします</translation>
 <translation id="2039379262107991683">ページをリーディング リストに追加すると、リマインダーを受け取ることができます</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google レンズで検索<ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">新しいタブで開く</translation>
 <translation id="4198423547019359126">ダウンロードの保存先はありません</translation>
-<translation id="4206707945726604465">他の履歴を削除するには、<ph name="BEGIN_LINK1" />Google マイ アクティビティ<ph name="END_LINK1" />にアクセスしてください</translation>
 <translation id="4209895695669353772">ユーザーに合わせた Google からのおすすめコンテンツを表示するには、同期を有効にします</translation>
 <translation id="4225895483398857530">ツールバー ショートカット</translation>
 <translation id="4242533952199664413">設定を開く</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ダウンロードしています…</translation>
 <translation id="4404568932422911380">ブックマークがありません</translation>
 <translation id="4405224443901389797">移動…</translation>
+<translation id="4409271659088619928">検索エンジンは <ph name="DSE" /> に設定されています。検索履歴を削除する場合は、検索エンジンの手順をご確認ください(該当する場合)。</translation>
 <translation id="4411535500181276704">ライトモード</translation>
 <translation id="4415276339145661267">Google アカウントの管理</translation>
 <translation id="4427306783828095590">保護強化機能により、フィッシングを防ぎ、不正なソフトウェアをより強力にブロックします</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">パスワードを確認</translation>
 <translation id="6000066717592683814">Google のままにする</translation>
 <translation id="6000203700195075278">再フォロー</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />検索<ph name="END_LINK1" />や他の履歴を削除するには、<ph name="BEGIN_LINK2" />Google マイ アクティビティ<ph name="END_LINK2" />にアクセスしてください</translation>
 <translation id="6005538289190791541">推奨パスワード</translation>
 <translation id="6032091552407840792">この試用版は、<ph name="BEGIN_LINK" />一部の地域<ph name="END_LINK" />でのみ使用できます。</translation>
 <translation id="6033245666633565791">Chrome では、<ph name="BEGIN_LINK" />プライバシー サンドボックス<ph name="END_LINK" />という取り組みを通じて、クロスサイト トラッキングからユーザーを保護しつつ、オープンウェブの理念を支える新しい技術を開発しています。
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">すべてのウェブユーザーの安全性を高めます。</translation>
 <translation id="6618554661997243500">よく使用するサイトや記事を表示するには、ホームボタンをタップします</translation>
 <translation id="6627583120233659107">フォルダを編集</translation>
-<translation id="6635718764393004944">検索エンジンは <ph name="DSE" /> に設定されています。この検索エンジンの検索履歴を削除するには、以下の手順をご覧ください。</translation>
 <translation id="663674369910034433">プライバシー、セキュリティ、データ収集に関連するその他の設定については、<ph name="BEGIN_LINK1" />同期<ph name="END_LINK1" />と <ph name="BEGIN_LINK2" />Google サービス<ph name="END_LINK2" />をご覧ください</translation>
 <translation id="6643016212128521049">削除</translation>
 <translation id="6643649862576733715">データ節約量で並べ替え</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
index d5038e2..a4ffcfe 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">მიმდინარეობს გამოთვლა…</translation>
 <translation id="1383876407941801731">ძიება</translation>
 <translation id="1384704387250346179">თარგმნეთ სურათი Google Lens-ით <ph name="BEGIN_NEW" />სიახლე<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">გამოყოფილის სტილის მართვა</translation>
 <translation id="1386674309198842382">აქტიური იყო <ph name="LAST_UPDATED" /> დღის წინ</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" />-ით ძიება</translation>
 <translation id="1406000523432664303">„არ ადევნო თვალი“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> ღილაკი <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">თქვენს ნაგულისხმევ საძიებო სისტემას უგზავნის ზოგიერთ ქუქი-ჩანაწერს და საძიებო მოთხოვნებს მისამართთა ზოლიდან ან საძიებო ველიდან</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ფაილი}other{# ფაილი}}</translation>
-<translation id="2017836877785168846">გაასუფთავებს ისტორიას და მისამართთა ზოლის ავტომატური დასრულების მონაცემებს.</translation>
 <translation id="2021896219286479412">სრულეკრანიანი რეჟიმის მართვა</translation>
 <translation id="2038563949887743358">საიტის დესკტოპის ვერსიის მოთხოვნის ჩართვა</translation>
 <translation id="2039379262107991683">დაამატეთ გვერდები თქვენს საკითხავ სიას, შეხსენება რომ მიიღოთ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">ძიება Google Lens-ით <ph name="BEGIN_NEW" />სიახლე<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">ახალ ჩანართში გახსნა</translation>
 <translation id="4198423547019359126">ჩამოსატვირთი მდებარეობები მიუწვდომელია</translation>
-<translation id="4206707945726604465">ისტორიის სხვა ფორმების გასასუფთავებლად მოინახულეთ <ph name="BEGIN_LINK1" />ჩემი Google აქტივობა<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Google-ის მიერ შემოთავაზებულ, პერსონალიზებულ კონტენტზე წვდომისთვის ჩართეთ სინქრონიზაცია</translation>
 <translation id="4225895483398857530">ხელსაწყოთა ზოლის მალსახმობი</translation>
 <translation id="4242533952199664413">პარამეტრების გახსნა</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> — იტვირთება…</translation>
 <translation id="4404568932422911380">სანიშნეები არ არის</translation>
 <translation id="4405224443901389797">გადატანა…</translation>
+<translation id="4409271659088619928">თქვენი საძიებო სისტემაა <ph name="DSE" />. გაეცანით მის ინსტრუქციას იმის თაობაზე, როგორ წაშალოთ თქვენი ძიების ისტორია, თუ ეს შესაძლებელია.</translation>
 <translation id="4411535500181276704">Lite რეჟიმი</translation>
 <translation id="4415276339145661267">თქვენი Google ანგარიშის მართვა</translation>
 <translation id="4427306783828095590">გაძლიერებული დაცვა გთავაზობთ ფიშინგისა და მავნე პროგრამებისგან დაცვის მეტ საშუალებას</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">პაროლების შემოწმება</translation>
 <translation id="6000066717592683814">Google-ის შენარჩუნება</translation>
 <translation id="6000203700195075278">თვალის ხელახლა მიდევნება</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ძიებისა<ph name="END_LINK1" /> და სხვა ტიპის ისტორიის გასასუფთავებლად გადადით სექციაზე „<ph name="BEGIN_LINK2" />ჩემი Google აქტივობა<ph name="END_LINK2" />“</translation>
 <translation id="6005538289190791541">შემოთავაზებული პაროლი</translation>
 <translation id="6032091552407840792">ეს საცდელი ვერსია აქტიურია მხოლოდ <ph name="BEGIN_LINK" />ზოგიერთ რეგიონში<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />-ის სახით Chrome ავითარებს ახალ ტექნოლოგიებს, რომლებიც დაგიცავთ საიტებს შორის თვალის მიდევნების მექანიზმებისგან, იმავდროულად კი შეინარჩუნებს ინტერნეტზე ღია წვდომას.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">უსაფრთხოების გაუმჯობესება თქვენთვის და ვების ყველა მომხმარებლისთვის.</translation>
 <translation id="6618554661997243500">თქვენთვის შერჩეული საუკეთესო საიტებისა და ამბების სანახავად შეეხეთ საწყისი გვერდის ღილაკს</translation>
 <translation id="6627583120233659107">საქაღალდის რედაქტირება</translation>
-<translation id="6635718764393004944">თქვენი საძიებო სისტემაა <ph name="DSE" />. ძიების ისტორიის წასაშლელად გაეცანით მის ინსტრუქციას (ასეთის არსებობის შემთხვევაში).</translation>
 <translation id="663674369910034433">კონფიდენციალურობასთან, უსაფრთხოებასთან და მონაცემთა შეგროვებასთან დაკავშირებული სხვა პარამეტრებისთვის იხილეთ <ph name="BEGIN_LINK1" />სინქრონიზაცია<ph name="END_LINK1" /> და <ph name="BEGIN_LINK2" />Google სერვისები<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">გასუფთავება</translation>
 <translation id="6643649862576733715">დალაგება დაზოგილი მონაცემების მიხედვით</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
index 28c78853..46581df5 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Есептелуде…</translation>
 <translation id="1383876407941801731">Іздеу</translation>
 <translation id="1384704387250346179">Google Lens арқылы аудару <ph name="BEGIN_NEW" />Жаңа<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Бөлектеу құралдарын форматтау</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> күн бұрын қосылған.</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> арқылы іздеу</translation>
 <translation id="1406000523432664303">"Бақыламау"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> түймесі</translation>
 <translation id="2000419248597011803">Мекенжай жолағына және іздеу өрісіне енгізілген сұрауларды, сонымен қатар кейбір cookie файлдарын әдепкі іздеу жүйесіне жібереді</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}other{# файл}}</translation>
-<translation id="2017836877785168846">Мекенжай жолағындағы тарихты және автотолтыруларды өшіреді.</translation>
 <translation id="2021896219286479412">Толық экран режимін басқару</translation>
 <translation id="2038563949887743358">Жұмыс үстелі сайтын сұрау: қосу</translation>
 <translation id="2039379262107991683">Беттерді оқу тізіміңізге қосып, еске салғыштар алыңыз</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens арқылы іздеу <ph name="BEGIN_NEW" />Жаңа<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Жаңа қойындыда ашу</translation>
 <translation id="4198423547019359126">Жүктеп алуға пайдалануға болатын орындар жоқ</translation>
-<translation id="4206707945726604465">Тарихтың басқа түрлерін тазалау үшін <ph name="BEGIN_LINK1" />Google әрекеттерім<ph name="END_LINK1" /> бетіне өтіңіз.</translation>
 <translation id="4209895695669353772">Google ұсынатын жекелендірілген мазмұнды алу үшін синхрондау функциясын қосыңыз</translation>
 <translation id="4225895483398857530">Құралдар тақтасы таңбашасы</translation>
 <translation id="4242533952199664413">Параметрлерді ашу</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – жүктеп алынуда…</translation>
 <translation id="4404568932422911380">Бетбелгілер жоқ</translation>
 <translation id="4405224443901389797">Мына қалтаға жылжыту…</translation>
+<translation id="4409271659088619928">Іздеу жүйесі — <ph name="DSE" />. Қажет болса, ондағы іздеу тарихын жою туралы нұсқауларды қараңыз.</translation>
 <translation id="4411535500181276704">Lite режимі</translation>
 <translation id="4415276339145661267">Google есептік жазбасын басқару</translation>
 <translation id="4427306783828095590">Жақсартылған қорғаныс фишинг пен зиянды бағдарламаларды бөгеуде көбірек істейді.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Құпия сөздерді тексеру</translation>
 <translation id="6000066717592683814">Google қызметін әдепкісінше пайдалану</translation>
 <translation id="6000203700195075278">Қайта жазылу</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Іздеу тарихын<ph name="END_LINK1" /> немесе басқа тарихтарды өшіру үшін <ph name="BEGIN_LINK2" />Google пайдалану тарихына<ph name="END_LINK2" /> кіріңіз.</translation>
 <translation id="6005538289190791541">Ұсынылған құпия сөз</translation>
 <translation id="6032091552407840792">Бұл сынақ нұсқасы <ph name="BEGIN_LINK" />кейбір аймақта<ph name="END_LINK" /> ғана қолжетімді.</translation>
 <translation id="6033245666633565791">Chrome ашық желіні қолдай отырып, <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> көмегімен сізді сайтаралық бақылаудан қорғайтын жаңа технологияларды әзірлеуде.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Интернеттегі сіздің және басқалардың қауіпсіздігін күшейтеді.</translation>
 <translation id="6618554661997243500">Көп қолданылатын сайттар мен қызықты жаңалықтарды көру үшін "Hегізгі экран" түймесін басыңыз.</translation>
 <translation id="6627583120233659107">Қалтаны өзгерту</translation>
-<translation id="6635718764393004944">Іздеу жүйеңіз — <ph name="DSE" />. Қажет болса іздеу тарихын жою үшін нұсқауларды қараңыз.</translation>
 <translation id="663674369910034433">Құпиялылыққа, қауіпсіздікке және дерек жинауға қатысты басқа да параметрлерді <ph name="BEGIN_LINK1" />Синхрондау<ph name="END_LINK1" /> және <ph name="BEGIN_LINK2" />Google қызметтері<ph name="END_LINK2" /> бөлімінен қараңыз.</translation>
 <translation id="6643016212128521049">Тазалау</translation>
 <translation id="6643649862576733715">Үнемделген деректер көлемі бойынша сұрыптау</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
index 44b705a..fa387424 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">កំពុងគណនា...</translation>
 <translation id="1383876407941801731">ស្វែងរក</translation>
 <translation id="1384704387250346179">បកប្រែរូបភាពដោយប្រើ Google Lens <ph name="BEGIN_NEW" />ថ្មី<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">កំណត់រចនាប័ទ្ម​ការរំលេច</translation>
 <translation id="1386674309198842382">ដំណើរការ <ph name="LAST_UPDATED" /> ថ្ងៃ​មុន</translation>
 <translation id="1397811292916898096">ស្វែងរក​ដោយ​ប្រើ <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“កុំតាមដាន”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">ប៊ូតុង <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">បញ្ជូនការស្វែងរក និងខូគី​មួយចំនួនពី​របារអាសយដ្ឋាន និង​ប្រអប់​ស្វែងរកទៅ​ម៉ាស៊ីន​ស្វែងរក​លំនាំដើម​របស់​អ្នក</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{ឯកសារ #}other{ឯកសារ #}}</translation>
-<translation id="2017836877785168846">សម្អាត​ប្រវត្តិ និងការ​បំពេញស្វ័យប្រវត្តិ​នៅក្នុង​របារ​អាសយដ្ឋាន។</translation>
 <translation id="2021896219286479412">ការគ្រប់គ្រងទំព័រពេញអេក្រង់</translation>
 <translation id="2038563949887743358">បើកសំណើគេហទំព័រសម្រាប់កុំព្យូទ័រ</translation>
 <translation id="2039379262107991683">បញ្ចូលទំព័រ​ទៅក្នុង​បញ្ជីអាន​របស់អ្នក ដើម្បីទទួលបាន​ការរំលឹក</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">ស្វែងរកដោយប្រើ Google Lens <ph name="BEGIN_NEW" />ថ្មី<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">បើកនៅក្នុងផ្ទាំងថ្មី</translation>
 <translation id="4198423547019359126">មិនមាន​ទីតាំង​សម្រាប់​ការទាញយក​ទេ</translation>
-<translation id="4206707945726604465">ដើម្បីសម្អាត​ទម្រង់​ប្រវត្តិ​ផ្សេងទៀត សូមចូលទៅកាន់<ph name="BEGIN_LINK1" />សកម្មភាព Google របស់ខ្ញុំ<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">ដើម្បីទទួលបានខ្លឹមសារ​ស្រប​តាមបុគ្គលដែលណែនាំដោយ Google សូមបើកសមកាលកម្ម</translation>
 <translation id="4225895483398857530">ផ្លូវកាត់របារឧបករណ៍</translation>
 <translation id="4242533952199664413">បើកការកំណត់</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - កំពុង​ទាញ​យក…</translation>
 <translation id="4404568932422911380">មិនមាន​ចំណាំ​ទេ</translation>
 <translation id="4405224443901389797">ផ្លាស់ទីទៅ…</translation>
+<translation id="4409271659088619928">ម៉ាស៊ីន​ស្វែងរករបស់អ្នកគឺ <ph name="DSE" />។ មើល​ការណែនាំ​របស់​ម៉ាស៊ីន​ស្វែងរក ដើម្បីដឹង​អំពីរបៀប​លុបប្រវត្តិ​ស្វែងរក​របស់អ្នក ប្រសិនបើអាច។</translation>
 <translation id="4411535500181276704">មុខងារស្រាល</translation>
 <translation id="4415276339145661267">គ្រប់គ្រង​គណនី Google របស់​អ្នក</translation>
 <translation id="4427306783828095590">ការការពារ​ដែលប្រសើរជាងមុនធ្វើសកម្មភាពសកម្មជាងមុន ដើម្បីទប់ស្កាត់ការដាក់នុយ និងកម្មវិធីគ្រោះថ្នាក់</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">ពិនិត្យពាក្យសម្ងាត់</translation>
 <translation id="6000066717592683814">រក្សា Google ដដែល</translation>
 <translation id="6000203700195075278">តាមដាន​ឡើងវិញ</translation>
-<translation id="6002623704405939939">ដើម្បីសម្អាត<ph name="BEGIN_LINK1" />ការស្វែងរក<ph name="END_LINK1" /> ឬទម្រង់ប្រវត្តិផ្សេងទៀត សូមចូលទៅកាន់<ph name="BEGIN_LINK2" />សកម្មភាព Google របស់ខ្ញុំ<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">ពាក្យ​សម្ងាត់​ដែលបានណែនាំ</translation>
 <translation id="6032091552407840792">ការសាកល្បងនេះ​ដំណើរការ​តែនៅក្នុង<ph name="BEGIN_LINK" />តំបន់មួយចំនួន<ph name="END_LINK" />ប៉ុណ្ណោះ។</translation>
 <translation id="6033245666633565791">Chrome កំពុងអភិវឌ្ឍបច្ចេកវិទ្យាថ្មី ដើម្បីការពារ​អ្នកពី​ការប្រមូល​ទិន្នន័យរុករក​នៅលើគេហទំព័រ​នានា ដោយរក្សាបណ្ដាញចំហ តាមរយៈ <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />។
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">ពង្រឹងសុវត្ថិភាព​សម្រាប់អ្នក និងអ្នកគ្រប់គ្នានៅលើអ៊ីនធឺណិត។</translation>
 <translation id="6618554661997243500">ដើម្បី​មើល​ឃើញអត្ថបទ និង​គេហទំព័រ​ពេញនិយម​សម្រាប់អ្នក សូមចុច​ប៊ូតុងដើម</translation>
 <translation id="6627583120233659107">កែសម្រួលថតឯកសារ</translation>
-<translation id="6635718764393004944">ម៉ាស៊ីន​ស្វែងរករបស់អ្នកគឺ <ph name="DSE" />។ ប្រសិនបើអាច សូមមើលការណែនាំរបស់ម៉ាស៊ីន​ស្វែងរកនេះ ដើម្បីលុបប្រវត្តិ​ស្វែងរករបស់អ្នក។</translation>
 <translation id="663674369910034433">សម្រាប់​ការកំណត់​ជាច្រើនទៀត ដែលពាក់ព័ន្ធនឹង​ឯកជន​ភាព សុវត្ថិភាព និង​ការ​ប្រមូល​ទិន្នន័យ សូមមើល<ph name="BEGIN_LINK1" />សមកាលកម្ម​<ph name="END_LINK1" /> និង<ph name="BEGIN_LINK2" />សេវាកម្ម Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">ជម្រះ</translation>
 <translation id="6643649862576733715">តម្រៀបតាម​បរិមាណ​ទិន្នន័យ​ដែលបានសន្សំ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
index 0fbaff4..43e6879 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ಲೆಕ್ಕ ಮಾಡುತ್ತಿದೆ...</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lens ಬಳಸಿ ಚಿತ್ರವನ್ನು ಅನುವಾದಿಸಿ <ph name="BEGIN_NEW" />ಹೊಸತು<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ಸ್ಟೈಲೈಸ್ ಮಾಡಿದ ಹೈಲೈಟ್</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> ದಿನಗಳ ಹಿಂದೆ ಸಕ್ರಿಯ</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ಮೂಲಕ ಹುಡುಕಿ</translation>
 <translation id="1406000523432664303">“ಟ್ರ್ಯಾಕ್ ಮಾಡಬೇಡಿ”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ಬಟನ್</translation>
 <translation id="2000419248597011803">ಕೆಲವು ಕುಕೀಗಳನ್ನು ಹಾಗೂ ವಿಳಾಸ ಪಟ್ಟಿ ಮತ್ತು ಹುಡುಕಾಟ ಬಾಕ್ಸ್‌ನಿಂದ ಹುಡುಕಾಟಗಳನ್ನು, ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಹುಡುಕಾಟದ ಎಂಜಿನ್‌ಗೆ ಕಳುಹಿಸುತ್ತದೆ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ಫೈಲ್}one{# ಫೈಲ್‌ಗಳು}other{# ಫೈಲ್‌ಗಳು}}</translation>
-<translation id="2017836877785168846">ಇತಿಹಾಸವನ್ನು ತೆರವುಗೊಳಿಸಿ ಮತ್ತು ವಿಳಾಸಪಟ್ಟಿಯಲ್ಲಿರುವುದನ್ನು ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಸಿ.</translation>
 <translation id="2021896219286479412">ಪೂರ್ಣ ಪರದೆ ಸೈಟ್ ನಿಯಂತ್ರಣಗಳು</translation>
 <translation id="2038563949887743358">ಡೆಸ್ಕ್‌ಟಾಪ್ ಸೈಟ್ ವಿನಂತಿಯನ್ನು ಆನ್ ಮಾಡಿ</translation>
 <translation id="2039379262107991683">ಜ್ಞಾಪನೆಯನ್ನು ಪಡೆಯುವುದಕ್ಕಾಗಿ, ನಿಮ್ಮ ಓದುವ ಪಟ್ಟಿಗೆ ಪುಟಗಳನ್ನು ಸೇರಿಸಿ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google ಲೆನ್ಸ್ ಮೂಲಕ ಹುಡುಕಿ<ph name="BEGIN_NEW" />ಹೊಸತು<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">ಹೊಸ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ತೆರೆಯಿರಿ</translation>
 <translation id="4198423547019359126">ಡೌನ್‌ಲೋಡ್ ಸ್ಥಳಗಳು ಲಭ್ಯವಿಲ್ಲ</translation>
-<translation id="4206707945726604465">ಇತರೆ ರೀತಿಯ ಇತಿಹಾಸವನ್ನು ತೆರವುಗೊಳಿಸಲು, <ph name="BEGIN_LINK1" />ನನ್ನ Google ಚಟುವಟಿಕೆ<ph name="END_LINK1" /> ಗೆ ಭೇಟಿ ನೀಡಿ</translation>
 <translation id="4209895695669353772">Google ಸಲಹೆ ನೀಡಿದ ವೈಯಕ್ತೀಕರಿಸಲಾದ ವಿಷಯವನ್ನು ಪಡೆದುಕೊಳ್ಳಲು, ಸಿಂಕ್ ಆನ್ ಮಾಡಿ</translation>
 <translation id="4225895483398857530">Toolbar ಶಾರ್ಟ್‌ಕಟ್</translation>
 <translation id="4242533952199664413">ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆ</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ಡೌನ್‌ಲೋಡ್ ಆಗುತ್ತಿದೆ…</translation>
 <translation id="4404568932422911380">ಯಾವುದೇ ಬುಕ್‌ಮಾರ್ಕ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ</translation>
 <translation id="4405224443901389797">ಇದಕ್ಕೆ ಸರಿಸಿ…</translation>
+<translation id="4409271659088619928">ನಿಮ್ಮ ಹುಡುಕಾಟದ ಎಂಜಿನ್ <ph name="DSE" /> ಆಗಿದೆ. ಅನ್ವಯವಾದರೆ, ನಿಮ್ಮ ಹುಡುಕಾಟದ ಇತಿಹಾಸವನ್ನು ಅಳಿಸುವುದಕ್ಕಾಗಿ ಅವರ ಸೂಚನೆಗಳನ್ನು ನೋಡಿ.</translation>
 <translation id="4411535500181276704">ಲೈಟ್ ಮೋಡ್</translation>
 <translation id="4415276339145661267">ನಿಮ್ಮ Google ಖಾತೆಯನ್ನು ನಿರ್ವಹಿಸಿ</translation>
 <translation id="4427306783828095590">ಫಿಶಿಂಗ್ ಮತ್ತು ಮಾಲ್‌ವೇರ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲು ವರ್ಧಿತ ಸುರಕ್ಷತೆ ಹೆಚ್ಚಿನ ಸಹಾಯ ಮಾಡುತ್ತದೆ</translation>
@@ -773,7 +771,6 @@
 <translation id="5979084224081478209">ಪಾಸ್‌ವರ್ಡ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ</translation>
 <translation id="6000066717592683814">Google ಇರಿಸಿಕೊಳ್ಳಿ</translation>
 <translation id="6000203700195075278">ಮರು ಅನುಸರಿಸಿ</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ಹುಡುಕಾಟ<ph name="END_LINK1" /> ಅಥವಾ ಇತರೆ ಫಾರ್ಮ್‌ಗಳ ಇತಿಹಾಸವನ್ನು ತೆರವುಗೊಳಿಸಲು, <ph name="BEGIN_LINK2" />ನನ್ನ Google ಚಟುವಟಿಕೆ<ph name="END_LINK2" /> ಗೆ ಭೇಟಿ ನೀಡಿ</translation>
 <translation id="6005538289190791541">ಸೂಚಿಸಿದ ಪಾಸ್‌ವರ್ಡ್</translation>
 <translation id="6032091552407840792"><ph name="BEGIN_LINK" />ಕೆಲವು ಪ್ರದೇಶಗಳಲ್ಲಿ<ph name="END_LINK" /> ಮಾತ್ರ ಈ ಪ್ರಯೋಗವು ಸಕ್ರಿಯವಾಗಿರುತ್ತದೆ.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />ಪ್ರೈವೆಸಿ ಸ್ಯಾಂಡ್‌ಬಾಕ್ಸ್<ph name="END_LINK" /> ನೊಂದಿಗೆ, ತೆರೆದ ವೆಬ್ ಅನ್ನು ಸಂರಕ್ಷಿಸುವುದರ ಜೊತೆಗೆ, ಕ್ರಾಸ್-ಸೈಟ್ ಟ್ರ್ಯಾಕಿಂಗ್‌ನಿಂದ ನಿಮ್ಮನ್ನು ರಕ್ಷಿಸಲು Chrome ಹೊಸ ತಂತ್ರಜ್ಞಾನಗಳನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸುತ್ತಿದೆ.
@@ -885,7 +882,6 @@
 <translation id="661266467055912436">ನಿಮಗಾಗಿ ಹಾಗೂ ವೆಬ್‌ನಲ್ಲಿರುವ ಎಲ್ಲರಿಗಾಗಿ ಸುರಕ್ಷತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.</translation>
 <translation id="6618554661997243500">ನಿಮಗಾಗಿ ಪ್ರಮುಖ ಸೈಟ್‌ಗಳು ಮತ್ತು ಸ್ಟೋರಿಗಳನ್ನು ವೀಕ್ಷಿಸಲು, ಹೋಮ್ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿ</translation>
 <translation id="6627583120233659107">ಫೋಲ್ಡರ್ ಎಡಿಟ್ ಮಾಡಿ</translation>
-<translation id="6635718764393004944">ನಿಮ್ಮ ಹುಡುಕಾಟ ಎಂಜಿನ್ <ph name="DSE" /> ಆಗಿದೆ. ಅನ್ವಯಿಸಿದರೆ, ನಿಮ್ಮ ಹುಡುಕಾಟ ಇತಿಹಾಸವನ್ನು ಅಳಿಸಲು ಅವರ ಸೂಚನೆಗಳನ್ನು ನೋಡಿ.</translation>
 <translation id="663674369910034433">ಗೌಪ್ಯತೆ, ಸುರಕ್ಷತೆ ಮತ್ತು ಡೇಟಾ ಸಂಗ್ರಹಣೆಗೆ ಸಂಬಂಧಿಸಿದ ಹೆಚ್ಚಿನ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗಾಗಿ <ph name="BEGIN_LINK1" />ಸಿಂಕ್<ph name="END_LINK1" /> ಮತ್ತು <ph name="BEGIN_LINK2" />Google ಸೇವೆಗಳನ್ನು<ph name="END_LINK2" /> ನೋಡಿ.</translation>
 <translation id="6643016212128521049">ತೆರವುಗೊಳಿಸಿ</translation>
 <translation id="6643649862576733715">ಉಳಿಸಿದ ಡೇಟಾ ಪ್ರಮಾಣದ ಪ್ರಕಾರ ವಿಂಗಡಿಸಿ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
index 66d9502..566ede0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">계산 중...</translation>
 <translation id="1383876407941801731">검색</translation>
 <translation id="1384704387250346179">Google 렌즈로 이미지 번역 <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">스타일 하이라이트</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" />일 전 동기화됨</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" />에서 검색</translation>
 <translation id="1406000523432664303">'추적 안함'</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> 버튼</translation>
 <translation id="2000419248597011803">검색주소창 및 검색창의 검색어 및 일부 쿠키를 기본 검색엔진에 전송</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{파일 #개}other{파일 #개}}</translation>
-<translation id="2017836877785168846">검색주소창의 검색 기록 및 자동 완성 항목을 삭제합니다.</translation>
 <translation id="2021896219286479412">전체화면 사이트 컨트롤</translation>
 <translation id="2038563949887743358">데스크톱 버전으로 보기 사용 설정</translation>
 <translation id="2039379262107991683">알림을 받으려면 읽기 목록에 페이지를 추가하세요.</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google 렌즈로 검색 <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">새 탭에서 열기</translation>
 <translation id="4198423547019359126">사용할 수 있는 다운로드 위치가 없음</translation>
-<translation id="4206707945726604465">다른 형식의 기록을 삭제하려면 <ph name="BEGIN_LINK1" />내 Google 활동<ph name="END_LINK1" />으로 이동하세요.</translation>
 <translation id="4209895695669353772">Google에서 추천하는 맞춤 콘텐츠를 보려면 동기화를 사용 설정하세요.</translation>
 <translation id="4225895483398857530">툴바 바로가기</translation>
 <translation id="4242533952199664413">설정 열기</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: 다운로드 중입니다…</translation>
 <translation id="4404568932422911380">북마크 없음</translation>
 <translation id="4405224443901389797">다음 폴더로 이동…</translation>
+<translation id="4409271659088619928">기본 검색엔진은 <ph name="DSE" />입니다. 해당 검색엔진에서 검색 기록을 삭제할 수 있는 경우 검색 기록 삭제 안내를 확인하세요.</translation>
 <translation id="4411535500181276704">라이트 모드</translation>
 <translation id="4415276339145661267">Google 계정 관리</translation>
 <translation id="4427306783828095590">향상된 보호 기능이 피싱 및 멀웨어를 더욱 효과적으로 차단합니다.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">비밀번호 확인</translation>
 <translation id="6000066717592683814">계속 Google 사용</translation>
 <translation id="6000203700195075278">다시 팔로우</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />검색<ph name="END_LINK1" /> 또는 다른 형태의 기록을 삭제하려면 <ph name="BEGIN_LINK2" />내 Google 활동<ph name="END_LINK2" />으로 이동하세요.</translation>
 <translation id="6005538289190791541">추천 비밀번호</translation>
 <translation id="6032091552407840792">이 무료 체험은 <ph name="BEGIN_LINK" />일부 지역<ph name="END_LINK" />에서만 진행됩니다.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />개인 정보 보호 샌드박스<ph name="END_LINK" />를 통해 Chrome은 오픈 웹의 장점을 유지하면서 크로스 사이트 추적으로부터 사용자를 보호하는 새로운 기술을 개발하고 있습니다.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">모든 웹 사용자를 위해 보안을 향상합니다.</translation>
 <translation id="6618554661997243500">맞춤 인기 사이트 및 뉴스를 보려면 홈 버튼 탭하기</translation>
 <translation id="6627583120233659107">폴더 수정</translation>
-<translation id="6635718764393004944">기본 검색엔진은 <ph name="DSE" />입니다. 해당하는 경우, 검색엔진에서 방문 기록을 삭제하는 방법을 확인하세요.</translation>
 <translation id="663674369910034433">개인정보 보호, 보안, 데이터 수집에 관한 추가 설정을 보려면 <ph name="BEGIN_LINK1" />동기화<ph name="END_LINK1" /> 및 <ph name="BEGIN_LINK2" />Google 서비스<ph name="END_LINK2" />를 참고하세요.</translation>
 <translation id="6643016212128521049">삭제</translation>
 <translation id="6643649862576733715">저장된 데이터 양에 따라 정렬</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
index 5db4a22d..941878a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Эсептелүүдө…</translation>
 <translation id="1383876407941801731">Издөө</translation>
 <translation id="1384704387250346179">Сүрөттү Google Lens аркылуу которуу <ph name="BEGIN_NEW" />Жаңы<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Бөлүп көрсөтүлгөн нерселерди стилдештирүү</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> күн мурун жигердүү болгон</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> аркылуу издөө</translation>
 <translation id="1406000523432664303">Байкоо салынбасын</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> баскычы</translation>
 <translation id="2000419248597011803">Дарек тилкесиндеги жана издөө кутучасындагы издөөлөрдү жана айрым cookie файлдарын демейки издөө тутумуна жөнөтөт</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}other{# файл}}</translation>
-<translation id="2017836877785168846">Дарек тилкесиндеги таржымалды жана сөздү автоматтык түрдө бүтүрүүнү тазалайт.</translation>
 <translation id="2021896219286479412">Сайтты толук экран режиминде көзөмөлдөө</translation>
 <translation id="2038563949887743358">Иш тактасынын сайтындагы суроо-талапты күйгүзүү</translation>
 <translation id="2039379262107991683">Эстеткич алуу үчүн барактарды Окуу тизмесине кошуңуз</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens менен издөө <ph name="BEGIN_NEW" />Жаңы<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Жаңы өтмөктө ачуу</translation>
 <translation id="4198423547019359126">Жүктөп алуу үчүн жеткиликтүү орун жок</translation>
-<translation id="4206707945726604465">Таржымалдын башка түрлөрүн өчүрүү үчүн <ph name="BEGIN_LINK1" />Менин Google аракеттериме<ph name="END_LINK1" /> өтүңүз</translation>
 <translation id="4209895695669353772">Google тарабынан сунушталган мазмунду алуу үчүн шайкештирүүнү күйгүзүңүз</translation>
 <translation id="4225895483398857530">Куралдар тилкесинин ыкчам баскычы</translation>
 <translation id="4242533952199664413">Жөндөөлөрдү ачуу</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Жүктөлүп алынууда…</translation>
 <translation id="4404568932422911380">Кыстармалар жок</translation>
 <translation id="4405224443901389797">Төмөнкүгө жылдыруу…</translation>
+<translation id="4409271659088619928">Издөө каражатыңыз: <ph name="DSE" />. Издөө таржымалын өчүрүү үчүн бар болсо, издөө каражатындагы нускамаларды караңыз.</translation>
 <translation id="4411535500181276704">Жөнөкөй режим</translation>
 <translation id="4415276339145661267">Google аккаунтунун жөндөөлөрүнө өтүү</translation>
 <translation id="4427306783828095590">Өркүндөтүлгөн коргоо параметри фишинг жана кесепеттүү программалардан жакшыраак коргойт</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Сырсөздөрдү текшерүү</translation>
 <translation id="6000066717592683814">Google калсын</translation>
 <translation id="6000203700195075278">Кайра жазылуу</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Изделген нерселерди<ph name="END_LINK1" /> же таржымалдын башка түрлөрүн өчүрүү үчүн <ph name="BEGIN_LINK2" />Менин Google аракеттерим<ph name="END_LINK2" /> бөлүмүнө өтүңүз</translation>
 <translation id="6005538289190791541">Сунушталган сырсөз</translation>
 <translation id="6032091552407840792">Бул сынамык версия <ph name="BEGIN_LINK" />айрым аймактарда<ph name="END_LINK" /> гана иштейт.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> менен бирге Chrome ачык тармакты коргоодо сайттарга кайчылаш көз салуудан сактай турган жаңы технологияларды иштеп чыгарууда.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Сиз жана башкалар үчүн Интернеттеги коопсуздукту арттырат.</translation>
 <translation id="6618554661997243500">Башкы бет баскычын таптаган сайын эң көп колдонгон сайттарыңыз жана акыркы окуяларыңыз көрүнөт</translation>
 <translation id="6627583120233659107">Куржунду түзөтүү</translation>
-<translation id="6635718764393004944">Издөө каражатыңыз: <ph name="DSE" />. Эгер мүмкүн болсо, издөө таржымалыңызды өчүрүү боюнча нускамаларды караңыз.</translation>
 <translation id="663674369910034433">Купуялыкка, коопсуздукка жана дайындарды чогултууга байланыштуу дагы башка жөндөөлөрдү көрүү үчүн <ph name="BEGIN_LINK1" />Шайкештирү<ph name="END_LINK1" /> жана <ph name="BEGIN_LINK2" />Google кызматтары<ph name="END_LINK2" /> бөлүмүнө өтүңүз.</translation>
 <translation id="6643016212128521049">Тазалоо</translation>
 <translation id="6643649862576733715">Үнөмдөлгөн трафик боюнча иргөө</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
index ae22ddc..a480db8 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ກຳລັງຄຳນວນ...</translation>
 <translation id="1383876407941801731">ຊອກຫາ</translation>
 <translation id="1384704387250346179">ແປພາສາໃນຮູບກັບ Google Lens <ph name="BEGIN_NEW" />ໃໝ່<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ສ້າງສີສັນໄຮໄລ້</translation>
 <translation id="1386674309198842382">ເປີດໃຊ້ເມື່ອ <ph name="LAST_UPDATED" /> ມື້ກ່ອນ</translation>
 <translation id="1397811292916898096">ຊອກຫາດ້ວຍ <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“ຢ່າ​ຕິດຕາມ”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">ປຸ່ມ <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">ສົ່ງບາງຄຸກກີ້ ແລະ ການຊອກຫາຈາກແຖບທີ່ຢູ່ ແລະ ກ່ອງຊອກຫາໄປໃຫ້ໂປຣແກຣມຊອກຫາເລີ່ມຕົ້ນຂອງທ່ານ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ໄຟລ໌}other{# ໄຟລ໌}}</translation>
-<translation id="2017836877785168846">ລຶບລ້າງປະຫວັດ ແລະ ການເຮັດສຳເລັດອັດຕະໂນມັດໃນແຖບທີ່ຢູ່.</translation>
 <translation id="2021896219286479412">ການຄວບຄຸມເວັບໄຊແບບເຕັມຈໍ</translation>
 <translation id="2038563949887743358">ເປີດ​ຂໍ​ເວັບ​ໄຊ​ທ໌​ເດັ​ສ​ທັອບ</translation>
 <translation id="2039379262107991683">ເພີ່ມໜ້າໃສ່ລາຍຊື່ການອ່ານຂອງທ່ານເພື່ອຮັບການແຈ້ງເຕືອນ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">ຊອກຫາດ້ວຍ Google Lens <ph name="BEGIN_NEW" />ໃໝ່<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">ເປີດຢູ່ໃນແຖບໃໝ່</translation>
 <translation id="4198423547019359126">ບໍ່ມີບ່ອນບັນທຶກການດາວໂຫຼດທີ່ສາມາດໃຊ້ໄດ້</translation>
-<translation id="4206707945726604465">ເພື່ອລຶບລ້າງປະຫວັດຮູບແບບອື່ນໆ, ກະລຸນາເຂົ້າໄປ <ph name="BEGIN_LINK1" />ການ​ເຄື່ອນ​ໄຫວ Google ຂອງຂ້ອຍ<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">ເພື່ອຮັບເນື້ອຫາແບບເປັນສ່ວນຕົວທີ່ແນະນຳໂດຍ Google, ກະລຸນາເປີດການຊິ້ງຂໍ້ມູນກ່ອນ</translation>
 <translation id="4225895483398857530">ທາງລັດແຖບ​ເຄື່ອງ​ມື</translation>
 <translation id="4242533952199664413">ເປີດ​ການ​ຕັ້ງ​ຄ່າ</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ກຳລັງດາວໂຫຼດ…</translation>
 <translation id="4404568932422911380">ບໍ່ມີບຸກມາກ</translation>
 <translation id="4405224443901389797">ຍ້າຍໄປໃສ່…</translation>
+<translation id="4409271659088619928">ໂປຣແກຣມຊອກຫາຂອງທ່ານແມ່ນ <ph name="DSE" />. ກະລຸນາອ່ານຄຳແນະນຳສຳລັບການລຶບປະຫວັດການຊອກຫາ, ຖ້າມີ.</translation>
 <translation id="4411535500181276704">ໂໝດ Lite</translation>
 <translation id="4415276339145661267">ຈັດການບັນຊີ Google ຂອງທ່ານ</translation>
 <translation id="4427306783828095590">ການປົກປ້ອງທີ່ປັບປຸງດີຂຶ້ນເຮັດໄດ້ຫຼາຍກວ່າໃນການບລັອກການຫຼອກເອົາຂໍ້ມູນ ແລະ ເມົາແວ</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">ກວດເບິ່ງລະຫັດຜ່ານ</translation>
 <translation id="6000066717592683814">ດຳເນີນການໃຊ້ Google</translation>
 <translation id="6000203700195075278">ຕິດຕາມຄືນໃໝ່</translation>
-<translation id="6002623704405939939">ເພື່ອລຶບລ້າງ <ph name="BEGIN_LINK1" />ການຊອກຫາ<ph name="END_LINK1" /> ຫຼື ປະຫວັດໃນຮູບແບບອື່ນ, ກະລຸນາເຂົ້າໄປ <ph name="BEGIN_LINK2" />ການເຄື່ອນໄຫວ Google ຂອງຂ້ອຍ<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">ລະຫັດຜ່ານທີ່ແນະນຳ</translation>
 <translation id="6032091552407840792">ການທົດລອງໃຊ້ນີ້ແມ່ນໃຊ້ໄດ້ສະເພາະໃນ <ph name="BEGIN_LINK" />ບາງພາກພື້ນ<ph name="END_LINK" /> ເທົ່ານັ້ນ.</translation>
 <translation id="6033245666633565791">ດ້ວຍ <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome ກຳລັງພັດທະນາເທັກໂນໂລຢີໃໝ່ເພື່ອປ້ອງກັນທ່ານຈາກການຕິດຕາມຂ້າມເວັບໄຊໃນຂະນະທີ່ຍັງຄົງຮັກສາຄວາມເປີດກວ້າງຂອງເວັບໄວ້.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">ປັບປຸງຄວາມປອດໄພສຳລັບທ່ານ ແລະ ທຸກຄົນໃນເວັບ.</translation>
 <translation id="6618554661997243500">ເພື່ອເຫັນເວັບໄຊ ແລະ ຂ່າວຍອດນິຍົມສຳລັບທ່ານ, ກະລຸນາແຕະປຸ່ມໜ້າທຳອິດ</translation>
 <translation id="6627583120233659107">ແກ້ໄຂໂຟລເດີ</translation>
-<translation id="6635718764393004944">ໂປຣແກຣມຊອກຫາຂອງທ່ານແມ່ນ <ph name="DSE" />. ເບິ່ງຄຳແນະນຳເພື່ອລຶບປະ​ຫວັດ​ການ​ຊອກຫາຂອງທ່ານ, ຖ້າມີ.</translation>
 <translation id="663674369910034433">ສຳລັບການຕັ້ງຄ່າເພີ່ມເຕີມທີ່ກ່ຽວຂ້ອງກັບຄວາມເປັນສ່ວນຕົວ, ຄວາມປອດໄພ ແລະ ການເກັບກຳຂໍ້ມູນ, ກະລຸນາເບິ່ງ <ph name="BEGIN_LINK1" />ການຊິ້ງຂໍ້ມູນ<ph name="END_LINK1" /> ແລະ <ph name="BEGIN_LINK2" />ການບໍລິການຂອງ Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">ລຶບ</translation>
 <translation id="6643649862576733715">ຮຽງຕາມປະລິມານອິນເຕີເນັດທີ່ປະຢັດໄດ້</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
index 7bab1311..8d1b4cf 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Apskaičiuojama...</translation>
 <translation id="1383876407941801731">Ieškoti</translation>
 <translation id="1384704387250346179">Versti vaizdą su „Google Lens“ <ph name="BEGIN_NEW" />Nauja<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizuoti paryškinimą</translation>
 <translation id="1386674309198842382">Aktyvus prieš <ph name="LAST_UPDATED" /> d.</translation>
 <translation id="1397811292916898096">Paieška su „<ph name="PRODUCT_NAME" />“</translation>
 <translation id="1406000523432664303">Funkcija „Nestebėti“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> mygtukas</translation>
 <translation id="2000419248597011803">Numatytajam paieškos varikliui siunčiami kai kurie slapukai ir į adreso juostą bei paieškos laukelį įvestos paieškos</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# failas}one{# failas}few{# failai}many{# failo}other{# failų}}</translation>
-<translation id="2017836877785168846">Išvaloma istorija ir automatiniai užbaigimai adreso juostoje.</translation>
 <translation id="2021896219286479412">Viso ekrano svetainės valdikliai</translation>
 <translation id="2038563949887743358">Įjungti stalinio kompiuterio svetainės užklausą</translation>
 <translation id="2039379262107991683">Pridėkite puslapių prie skaitymo sąrašo, kad gautumėte priminimą</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Ieškoti su „Google Lens“ <ph name="BEGIN_NEW" />Nauja<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Atidaryti naujame skirtuke</translation>
 <translation id="4198423547019359126">Nėra pasiekiamų atsisiuntimo vietų</translation>
-<translation id="4206707945726604465">Jei norite išvalyti kitų formų istoriją, apsilankykite skiltyje <ph name="BEGIN_LINK1" />„Mano „Google“ veikla“<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Jei norite gauti „Google“ siūlomo suasmeninto turinio, įjunkite sinchronizavimą</translation>
 <translation id="4225895483398857530">Įrankių juostos spartusis klavišas</translation>
 <translation id="4242533952199664413">Atidaryti nustatymus</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – atsisiunčiama…</translation>
 <translation id="4404568932422911380">Nėra jokių žymių</translation>
 <translation id="4405224443901389797">Perkelti į…</translation>
+<translation id="4409271659088619928">Jūsų paieškos variklis yra „<ph name="DSE" />“. Peržiūrėkite jo instrukcijas, kaip ištrinti paieškos istoriją (jei taikoma).</translation>
 <translation id="4411535500181276704">Supaprastintasis režimas</translation>
 <translation id="4415276339145661267">„Google“ paskyros tvarkymas</translation>
 <translation id="4427306783828095590">Naudojant sustiprintą apsaugą pasitelkiama papildomų priemonių sukčiavimui ir kenkėjiškoms programoms užblokuoti</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Patikrinti slaptažodžius</translation>
 <translation id="6000066717592683814">Palikti „Google“</translation>
 <translation id="6000203700195075278">Stebėti iš naujo</translation>
-<translation id="6002623704405939939">Norėdami išvalyti <ph name="BEGIN_LINK1" />paieškos<ph name="END_LINK1" /> ar kitos veiklos istoriją, apsilankykite puslapyje <ph name="BEGIN_LINK2" />„Mano „Google“ veikla“<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Siūlomas slaptažodis</translation>
 <translation id="6032091552407840792">Ši bandomoji versija aktyvi tik <ph name="BEGIN_LINK" />kai kuriuose regionuose<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Naudodama <ph name="BEGIN_LINK" />privatumo „sandbox“ (smėlio dėžę)<ph name="END_LINK" /> „Chrome“ kuria naujas technologijas, kad apsaugotų jus nuo veiklos skirtingose svetainėse stebėjimo, išlaikydama atvirą žiniatinklį.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Sustiprina jūsų ir visų žiniatinklio naudotojų saugą.</translation>
 <translation id="6618554661997243500">Norėdami peržiūrėti populiariausias svetaines ir jums skirtus pasakojimus palieskite pagrindinio ekrano mygtuką</translation>
 <translation id="6627583120233659107">Redaguoti aplanką</translation>
-<translation id="6635718764393004944">Jūsų paieškos variklis yra „<ph name="DSE" />“. Jei yra, peržiūrėkite jo instrukcijas, kaip ištrinti paieškos istoriją.</translation>
 <translation id="663674369910034433">Daugiau nustatymų, susijusių su privatumu, sauga ir duomenų rinkimu, žr. skiltyse <ph name="BEGIN_LINK1" />„Sinchronizavimas“<ph name="END_LINK1" /> ir <ph name="BEGIN_LINK2" />„Google“ paslaugos“<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Išvalyti</translation>
 <translation id="6643649862576733715">Rūšiuoti pagal išsaugotų duomenų kiekį</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
index 6b67a7fd..8768878 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Notiek aprēķināšana...</translation>
 <translation id="1383876407941801731">Meklēt</translation>
 <translation id="1384704387250346179">Tulkot attēlu ar Google Lens <ph name="BEGIN_NEW" />Jaunums<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizēt atzīmētos objektus</translation>
 <translation id="1386674309198842382">Aktīvs pirms <ph name="LAST_UPDATED" /> dienām</translation>
 <translation id="1397811292916898096">Meklēt, izmantojot meklētājprogramu <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Nesekot”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> poga</translation>
 <translation id="2000419248597011803">Nosūta dažus sīkfailus un meklēšanas vaicājumus no adreses joslas un meklēšanas lodziņa uz jūsu noklusējuma meklētājprogrammu.</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fails}zero{# faili}one{# fails}other{# faili}}</translation>
-<translation id="2017836877785168846">Notīra vēsturi un automātiskās pabeigšanas ierakstus adreses joslā.</translation>
 <translation id="2021896219286479412">Pilnekrāna vietnes vadīklas</translation>
 <translation id="2038563949887743358">Ieslēgt iestatījumu “Pieprasīt datora vietni”</translation>
 <translation id="2039379262107991683">Pievienojiet lapas savam lasīšanas sarakstam, lai saņemtu atgādinājumu.</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Meklēšana ar Google Lens <ph name="BEGIN_NEW" />Jauns<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Atvērt jaunā cilnē</translation>
 <translation id="4198423547019359126">Nav pieejamu lejupielādes atrašanās vietu.</translation>
-<translation id="4206707945726604465">Lai notīrītu citu vēstures informāciju, apmeklējiet lapu <ph name="BEGIN_LINK1" />Manas Google darbības<ph name="END_LINK1" />.</translation>
 <translation id="4209895695669353772">Lai saņemtu Google ieteikto personalizēto saturu, ieslēdziet sinhronizāciju.</translation>
 <translation id="4225895483398857530">Rīkjoslas īsinājumtaustiņš</translation>
 <translation id="4242533952199664413">Atvērt iestatījumus</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> — notiek lejupielāde…</translation>
 <translation id="4404568932422911380">Nav grāmatzīmju</translation>
 <translation id="4405224443901389797">Pārvietot uz…</translation>
+<translation id="4409271659088619928">Jūsu meklētājprogramma ir <ph name="DSE" />. Skatiet tās norādījumus par meklēšanas vēstures dzēšanu, ja šāda iespēja ir pieejama.</translation>
 <translation id="4411535500181276704">Vienkāršais režīms</translation>
 <translation id="4415276339145661267">Google konta pārvaldība</translation>
 <translation id="4427306783828095590">Uzlabotā aizsardzība labāk bloķē pikšķerēšanas mēģinājumus un ļaunprātīgu programmatūru</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Pārbaudīt paroles</translation>
 <translation id="6000066717592683814">Arī turpmāk izmantot Google</translation>
 <translation id="6000203700195075278">Atsākt sekošanu</translation>
-<translation id="6002623704405939939">Lai notīrītu <ph name="BEGIN_LINK1" />meklēšanas vaicājumus<ph name="END_LINK1" /> vai citu vēstures informāciju, atveriet lapu <ph name="BEGIN_LINK2" />Manas Google darbības<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Ieteiktā parole</translation>
 <translation id="6032091552407840792">Šī izmēģinājuma versija ir aktīva tikai <ph name="BEGIN_LINK" />dažos reģionos<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Izmantojot <ph name="BEGIN_LINK" />konfidencialitātes smilškasti<ph name="END_LINK" />, pārlūkā Chrome ir iespējams izstrādāt jaunas tehnoloģijas, kas aizsargā jūs no starpvietņu izsekošanas, vienlaikus saglabājot atvērtā tīmekļa darbību.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Šis režīms efektīvāk aizsargā gan jūs, gan visus citus tīmekļa lietotājus.</translation>
 <translation id="6618554661997243500">Lai skatītu vietnes, ko apmeklējat visbiežāk, un ieteicamos rakstus, pieskarieties pogai Sākumlapa</translation>
 <translation id="6627583120233659107">Rediģēt mapi</translation>
-<translation id="6635718764393004944">Jūsu meklētājprogramma ir <ph name="DSE" />. Skatiet tās norādījumus par meklēšanas vēstures dzēšanu, ja tādi ir pieejami.</translation>
 <translation id="663674369910034433">Papildu iestatījumus, kas attiecas uz konfidencialitāti, drošību un datu vākšanu, skatiet sadaļās <ph name="BEGIN_LINK1" />Sinhronizēšana<ph name="END_LINK1" /> un <ph name="BEGIN_LINK2" />Google pakalpojumi<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Notīrīt</translation>
 <translation id="6643649862576733715">Kārtot pēc saglabāto datu apjoma</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
index 5743e0cf..a16181a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Се пресметува…</translation>
 <translation id="1383876407941801731">Барај</translation>
 <translation id="1384704387250346179">Преведете слика со Google Lens <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стилизирано нагласување</translation>
 <translation id="1386674309198842382">Активен пред <ph name="LAST_UPDATED" /> дена</translation>
 <translation id="1397811292916898096">Пребарувајте со <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Не ме следи“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> копче</translation>
 <translation id="2000419248597011803">Испраќа колачиња и пребарувања од лентата за адреси и полето за пребарување во вашиот стандарден пребарувач</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# датотека}one{# датотека}other{# датотеки}}</translation>
-<translation id="2017836877785168846">Ги брише историјата и автоматските довршувања во лентата за адреси.</translation>
 <translation id="2021896219286479412">Контроли на сајтот на цел екран</translation>
 <translation id="2038563949887743358">Вклучи „Барај локација на работна површина“</translation>
 <translation id="2039379262107991683">Додавајте страници во „Списокот за читање“ за да добивате потсетници</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Пребарувајте со Google Lens <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Отвори во нова картичка</translation>
 <translation id="4198423547019359126">Нема достапни локации за преземање</translation>
-<translation id="4206707945726604465">За да избришете друг тип историја, одете на <ph name="BEGIN_LINK1" />Моја активност на Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">За да добивате персонализирани содржини предложени од Google, вклучете ја синхронизацијата</translation>
 <translation id="4225895483398857530">Кратенка за алатникот</translation>
 <translation id="4242533952199664413">Отвори ги поставките</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Се презема…</translation>
 <translation id="4404568932422911380">Нема обележувачи</translation>
 <translation id="4405224443901389797">Премести во…</translation>
+<translation id="4409271659088619928">Вашиот пребарувач е <ph name="DSE" />. Погледнете го неговото упатство за бришење на историјата на пребарување ако е применливо.</translation>
 <translation id="4411535500181276704">Лесен режим</translation>
 <translation id="4415276339145661267">Управувајте со сметката на Google</translation>
 <translation id="4427306783828095590">„Подобрената заштита“ помага при блокирање кражби на идентитетот и злонамерен софтвер</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Провери ги лозинките</translation>
 <translation id="6000066717592683814">Задржи го Google</translation>
 <translation id="6000203700195075278">Следете пак</translation>
-<translation id="6002623704405939939">За да избришете <ph name="BEGIN_LINK1" />пребарување<ph name="END_LINK1" /> или друг тип историја, одете на <ph name="BEGIN_LINK2" />Моја активност на Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Предложена лозинка</translation>
 <translation id="6032091552407840792">Оваа пробна верзија е активна само во <ph name="BEGIN_LINK" />некои региони<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Со <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome развива нови технологии за заштита од следење на повеќе сајтови, додека истовремено го зачувува отворениот интернет.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Ја подобрува безбедноста за вас и сите останати на интернет.</translation>
 <translation id="6618554661997243500">За да ги гледате најдобрите сајтови и стории за вас, допрете го копчето за почетен екран</translation>
 <translation id="6627583120233659107">Уредувај папка</translation>
-<translation id="6635718764393004944">Вашиот пребарувач е <ph name="DSE" />. Ако е применливо, погледнете ги упатствата за да ја избришете историјата на пребарување.</translation>
 <translation id="663674369910034433">За повеќе поставки што се однесуваат на приватноста, безбедноста и прибирањето податоци, одете на <ph name="BEGIN_LINK1" />Синхронизација<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />Услуги на Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Исчисти</translation>
 <translation id="6643649862576733715">Подреди по количина на заштеден сообраќај</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
index 15780a2..c624f8a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">കണക്കാക്കുന്നു…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lens-ൽ ചിത്രം വിവർത്തനം ചെയ്യൂ <ph name="BEGIN_NEW" />പുതിയത്<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ഹൈലൈറ്റ് മോടിയാക്കുക</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> ദിവസം മുമ്പ് സജീവമായിരുന്നു</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ഉപയോഗിച്ച് തിരയുക</translation>
 <translation id="1406000523432664303">“ട്രാക്ക് ചെയ്യരുത്”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ബട്ടൺ</translation>
 <translation id="2000419248597011803">നിങ്ങളുടെ ഡിഫോൾട്ട് തിരയൽ എഞ്ചിനിലേക്ക് വിലാസ ബാറിൽ നിന്നും തിരയൽ ബോക്‌സിൽ നിന്നുമുള്ള തിരയലുകളും കുറച്ച് കുക്കികളും അയയ്ക്കുന്നു</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ഫയല്‍}other{# ഫയലുകൾ}}</translation>
-<translation id="2017836877785168846">വിലാസ ബാറിലെ ചരിത്രവും സ്വയം പൂർത്തീകരണങ്ങളും മായ്ക്കുന്നു.</translation>
 <translation id="2021896219286479412">പൂർണ്ണ സ്ക്രീൻ സൈറ്റ് നിയന്ത്രണങ്ങൾ</translation>
 <translation id="2038563949887743358">'ഡെസ്‌ക്‌ടോപ്പ് സൈറ്റ് അഭ്യർത്ഥിക്കുക' ഓണാക്കുക</translation>
 <translation id="2039379262107991683">റിമെെൻഡർ ലഭിക്കുന്നതിന്, വായിക്കാനുള്ളവയുടെ ലിസ്‌റ്റിൽ പേജുകൾ ചേർക്കുക</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google ലെൻസ് ഉപയോഗിച്ച് തിരയൂ <ph name="BEGIN_NEW" />പുതിയത്<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">പുതിയ ടാബില്‍ തുറക്കുക</translation>
 <translation id="4198423547019359126">ലഭ്യമായ ഡൗൺലോഡ് ലൊക്കേഷനുകളൊന്നും ഇല്ല</translation>
-<translation id="4206707945726604465">ചരിത്രത്തിന്റെ മറ്റ് രൂപങ്ങൾ മായ്‌ക്കാൻ <ph name="BEGIN_LINK1" />എന്റെ Google ആക്‌റ്റിവിറ്റി<ph name="END_LINK1" /> സന്ദർശിക്കുക</translation>
 <translation id="4209895695669353772">Google നിർദ്ദേശിക്കുന്ന വ്യക്തിപരമാക്കിയ ഉള്ളടക്കം ലഭിക്കാൻ, സമന്വയിപ്പിക്കൽ ഓണാക്കുക</translation>
 <translation id="4225895483398857530">ടൂള്‍ബാര്‍ കുറുക്കുവഴി</translation>
 <translation id="4242533952199664413">ക്രമീകരണം തുറക്കുക</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ഡൗൺലോഡ് ചെയ്യുന്നു…</translation>
 <translation id="4404568932422911380">ബുക്ക്‌മാർക്കുകളൊന്നുമില്ല</translation>
 <translation id="4405224443901389797">ഇതിലേക്ക് നീക്കുക…</translation>
+<translation id="4409271659088619928"><ph name="DSE" /> ആണ് നിങ്ങളുടെ തിരയൽ യന്ത്രം. ബാധകമെങ്കിൽ, നിങ്ങളുടെ തിരയൽ ചരിത്രം ഇല്ലാതാക്കാനുള്ള അതിലെ നിർദ്ദേശങ്ങൾ കാണുക.</translation>
 <translation id="4411535500181276704">ലൈറ്റ് മോഡ്</translation>
 <translation id="4415276339145661267">നിങ്ങളുടെ Google അക്കൗണ്ട് മാനേജ് ചെയ്യുക</translation>
 <translation id="4427306783828095590">ഫിഷിംഗും മാല്‍വെയറും ബ്ലോക്ക് ചെയ്യുന്നതിന് മെച്ചപ്പെടുത്തിയ പരിരക്ഷ കൂടുതൽ കാര്യങ്ങൾ ചെയ്യുന്നു</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">പാസ്‌വേഡ് പരിശോധിക്കൂ</translation>
 <translation id="6000066717592683814">Google ഉപയോഗിക്കുക</translation>
 <translation id="6000203700195075278">വീണ്ടും പിന്തുടരുക</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />തിരയൽ<ph name="END_LINK1" /> അല്ലെങ്കിൽ മറ്റ് തരത്തിലുള്ള ചരിത്രം മായ്ക്കാൻ <ph name="BEGIN_LINK2" />എന്റെ Google ആക്റ്റിവിറ്റി<ph name="END_LINK2" /> സന്ദർശിക്കുക</translation>
 <translation id="6005538289190791541">നിർദ്ദേശിച്ച പാസ്‌വേഡ്</translation>
 <translation id="6032091552407840792">ഈ ട്രയൽ <ph name="BEGIN_LINK" />ചില പ്രദേശങ്ങളിൽ<ph name="END_LINK" /> മാത്രമേ സജീവമായിട്ടുള്ളൂ.</translation>
 <translation id="6033245666633565791">ഓപ്പൺ വെബിനെ പരിരക്ഷിക്കുമ്പോൾ തന്നെ <ph name="BEGIN_LINK" />സ്വകാര്യതാ സാൻഡ്‌ബോക്‌സ്<ph name="END_LINK" /> ഉപയോഗിച്ച് ക്രോസ്-സെെറ്റ് ട്രാക്കിംഗിൽ നിന്ന് നിങ്ങളെ സംരക്ഷിക്കാൻ പുതിയ സാങ്കേതികവിദ്യകൾ Chrome വികസിപ്പിക്കുന്നു.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">പേര് വളരെ വലുതാണ്</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# ചിത്രം}other{# ചിത്രങ്ങൾ}}</translation>
 <translation id="6447558397796644647">ആ ബുക്‌മാർക്ക് കണ്ടെത്താനാവുന്നില്ല. അക്ഷരത്തെറ്റ് പരിശോധിക്കുക അല്ലെങ്കിൽ പുതിയ ബുക്‌മാർക്ക് ചേർക്കുക.</translation>
+<translation id="6459045781120991510">സർവേകൾ</translation>
 <translation id="6461962085415701688">ഫയൽ തുറക്കാൻ കഴിയില്ല</translation>
 <translation id="6464977750820128603">നിങ്ങൾ Chrome- ൽ സന്ദർശിക്കുന്ന സൈറ്റുകൾ കാണാനും അവയ്ക്ക് ടൈമറുകൾ സജ്ജീകരിക്കാനുമാവും.\n\nനിങ്ങൾ ടൈമറുകൾ സജ്ജീകരിക്കുന്ന സൈറ്റുകളെക്കുറിച്ചും നിങ്ങൾ എത്ര സമയം അവ സന്ദർശിക്കുന്നു എന്നതിനെക്കുറിച്ചും Google ന് വിവരങ്ങൾ ലഭിക്കുന്നു. ഡിജിറ്റൽ ആരോഗ്യം മെച്ചപ്പെടുത്താൻ ഈ വിവരം ഉപയോഗിക്കുന്നു.</translation>
 <translation id="6475951671322991020">വീഡിയോ ഡൗൺലോഡ് ചെയ്യുക</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">നിങ്ങൾക്കും വെബിലെ എല്ലാവർക്കും സുരക്ഷ മെച്ചപ്പെടുത്തുന്നു.</translation>
 <translation id="6618554661997243500">നിങ്ങൾക്കുള്ള പ്രധാന സൈറ്റുകളും സ്‌റ്റോറികളും കാണാൻ, ഹോം ബട്ടൺ ടാപ്പ് ചെയ്യുക</translation>
 <translation id="6627583120233659107">ഫോൾഡർ എഡിറ്റ് ചെയ്യുക</translation>
-<translation id="6635718764393004944"><ph name="DSE" /> ആണ് നിങ്ങളുടെ തിരയൽ യന്ത്രം. ബാധകമെങ്കിൽ, നിങ്ങളുടെ തിരയൽ ചരിത്രം ഇല്ലാതാക്കാൻ അവരുടെ നിർദ്ദേശങ്ങൾ കാണുക.</translation>
 <translation id="663674369910034433">സ്വകാര്യത, സുരക്ഷ, ഡാറ്റാ ശേഖരണം എന്നിവയുമായി ബന്ധപ്പെട്ട കൂടുതൽ ക്രമീകരണത്തിന് <ph name="BEGIN_LINK1" />സമന്വയവും<ph name="END_LINK1" /> <ph name="BEGIN_LINK2" />Google സേവനങ്ങളും<ph name="END_LINK2" /> കാണുക</translation>
 <translation id="6643016212128521049">മായ്‌ക്കുക</translation>
 <translation id="6643649862576733715">സംരക്ഷിച്ച ഡാറ്റയുടെ അളവിനനുസരിച്ച് അടുക്കുക</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">പ്രത്യേക സ്റ്റൈലിൽ ആക്കിയ ഹൈലൈറ്റ് <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Chrome-ൽ <ph name="TARGET_DEVICE_NAME" /> ഉപകരണത്തിലെ സമന്വയിപ്പിക്കൽ ഓണാക്കിയിട്ടുണ്ടെന്ന് ഉറപ്പാക്കുക</translation>
 <translation id="7252076891734325316">നിങ്ങളുടെ ഫോൺ കമ്പ്യൂട്ടറിന്റെ അടുത്ത് വയ്ക്കുക</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" />-ലേക്ക് <ph name="ONE_TIME_CODE" /> നൽകണോ?</translation>
 <translation id="7274013316676448362">സൈറ്റ് ബ്ലോക്ക് ചെയ്‌തു</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> മാറ്റണോ?</translation>
 <translation id="7290209999329137901">പേര് മാറ്റൽ ലഭ്യമല്ല</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
index fbe28d55..2de5119 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Тооцоолж байна...</translation>
 <translation id="1383876407941801731">Хайлт</translation>
 <translation id="1384704387250346179">Google Дурангаар зураг орчуул <ph name="BEGIN_NEW" />Шинэ<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Тодруулгыг стильжүүлэх</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> өдрийн өмнөөс идэвхтэй</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" />-р хайх</translation>
 <translation id="1406000523432664303">“Бүү дага”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> товчлуур</translation>
 <translation id="2000419248597011803">Таны өгөгдмөл хайлтын системд хаяг оруулах хэсэг, хайх хэсгийн зарим күүки болон хайлтыг илгээдэг</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Файл}other{# Файл}}</translation>
-<translation id="2017836877785168846">Түүх, хаяг оруулах хэсгийн автомат гүйцээлтийг устгана.</translation>
 <translation id="2021896219286479412">Бүтэн дэлгэцийн сайтын хяналт</translation>
 <translation id="2038563949887743358">Сайтыг компьютерийн горимоор харах хүсэлтийг асаах</translation>
 <translation id="2039379262107991683">Сануулагч авахын тулд хуудаснуудыг Унших жагсаалтдаа нэмнэ үү</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Хэл</translation>
 <translation id="4183868528246477015">Google дуран <ph name="BEGIN_NEW" />Шинэ<ph name="END_NEW" />-р хайх</translation>
 <translation id="4195643157523330669">Шинэ таб дээр нээх</translation>
+<translation id="4196597275619698563">Карт үүсгэх</translation>
 <translation id="4198423547019359126">Татах боломжтой байршил алга</translation>
-<translation id="4206707945726604465">Түүхийн бусад хэлбэрийг арилгахын тулд <ph name="BEGIN_LINK1" />Миний Google-н үйл ажиллагаа<ph name="END_LINK1" />-д зочилно уу</translation>
 <translation id="4209895695669353772">Google-с санал болгосон хувийн болгосон агуулгыг авахын тулд синкийг асаана уу</translation>
 <translation id="4225895483398857530">Самбарын товчлол</translation>
 <translation id="4242533952199664413">Нээлттэй тохиргоо</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Татаж байна…</translation>
 <translation id="4404568932422911380">Хавчуурга алга</translation>
 <translation id="4405224443901389797">руу зөөх…</translation>
+<translation id="4409271659088619928">Таны хайлтын систем <ph name="DSE" /> байна. Хэрэв боломжтой бол хайлтын түүхээ устгахын тулд үүний зааварчилгааг харна уу.</translation>
 <translation id="4411535500181276704">Lite горим</translation>
 <translation id="4415276339145661267">Google Бүртгэлээ удирдах</translation>
 <translation id="4427306783828095590">Сайжруулсан хамгаалалт нь фишинг болон хортой кодыг блоклохын тулд илүү ихийг хийдэг</translation>
@@ -773,7 +772,6 @@
 <translation id="5979084224081478209">Нууц үгийг шалгах</translation>
 <translation id="6000066717592683814">Google хэвээр байлгах</translation>
 <translation id="6000203700195075278">Дахин дагах</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Хайлт<ph name="END_LINK1" /> эсвэл түүхийн бусад хэлбэрийг арилгахын тулд <ph name="BEGIN_LINK2" />Миний Google-н үйл ажиллагаа<ph name="END_LINK2" />-нд зочилно уу</translation>
 <translation id="6005538289190791541">Санал болгосон нууц үг</translation>
 <translation id="6032091552407840792">Энэ туршилт зөвхөн <ph name="BEGIN_LINK" />зарим бүс нутагт<ph name="END_LINK" /> идэвхтэй байна.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />-р Chrome нээлттэй вебийг хадгалах явцдаа таныг сайт хооронд хянахаас хамгаалах шинэ технологийг хөгжүүлж байна.
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Таны болон веб дэх хүн бүрийн аюулгүй байдлыг нэмэгдүүлдэг.</translation>
 <translation id="6618554661997243500">Шилдэг сайт, мэдээ нийтлэлүүдийг үзэхийн тулд Нүүр хуудасны товчлуурыг товшино уу</translation>
 <translation id="6627583120233659107">Хавтас засах</translation>
-<translation id="6635718764393004944">Таны хайлтын систем <ph name="DSE" /> байна. Хэрэв боломжтой бол хайлтын түүхээ устгахын тулд зааварчилгааг нь харна уу.</translation>
 <translation id="663674369910034433">Нууцлал, аюулгүй байдал болон өгөгдөл цуглуулахтай холбоотой бусад тохиргоог <ph name="BEGIN_LINK1" />Синк хийх<ph name="END_LINK1" /> болон <ph name="BEGIN_LINK2" />Google-н үйлчилгээнүүд<ph name="END_LINK2" />-ээс харна уу.</translation>
 <translation id="6643016212128521049">Цэвэрлэх</translation>
 <translation id="6643649862576733715">Хадгалсан өгөгдлийг хэмжээгээр нь эрэмбэлэх</translation>
@@ -1049,6 +1046,7 @@
 <translation id="7704317875155739195">Хайлт болон URL-г автоматаар гүйцээх</translation>
 <translation id="7707922173985738739">Мобайл дата ашиглах</translation>
 <translation id="7725024127233776428">Таны хавчуурга хийсэн хуудас энд харагдана</translation>
+<translation id="7731260005404856143">Таныг нэвтэрсэн үед <ph name="BEGIN_LINK1" />бусад төрлийн үйл ажиллагааг<ph name="END_LINK1" /> Google Бүртгэлд тань хадгалж магадгүй. Та хүссэн үедээ тэдгээрийг устгах боломжтой.</translation>
 <translation id="7757787379047923882"><ph name="DEVICE_NAME" />-с текстийг хуваалцсан</translation>
 <translation id="7761849928583394409">Огноо болон цаг сонгох</translation>
 <translation id="7762668264895820836">SD Карт <ph name="SD_CARD_NUMBER" /></translation>
@@ -1239,6 +1237,7 @@
 <translation id="8854223127042600341">Офлайн файлуудаа харах</translation>
 <translation id="8856607253650333758">Тайлбар авах</translation>
 <translation id="8873817150012960745">Эхлүүлэхийн тулд энд товшино уу</translation>
+<translation id="8881973373982641723">Түүхийг арилгана. Үүнд хайх хэсгийн түүх багтана.</translation>
 <translation id="889338405075704026">Chrome-н тохиргоо хэсэгт очих</translation>
 <translation id="8898822736010347272">Шинэ аюул заналыг олж илрүүлэх болон веб дээрх бүх хүнийг хамгаалахад туслахын тулд таны зочилдог зарим хуудасны URL, системийн хязгаарлагдмал мэдээлэл болон хуудасны зарим контентыг Google рүү илгээдэг.</translation>
 <translation id="8909135823018751308">Мэдээллийг хуваалцах ...</translation>
@@ -1292,6 +1291,7 @@
 <translation id="9209888181064652401">Дуудлага хийх боломжгүй байна</translation>
 <translation id="9212845824145208577">Доошлох боломжгүй. Дараагийн хуудасны доод хэсгээс эхлүүлж үзнэ үү.</translation>
 <translation id="9219103736887031265">Зураг</translation>
+<translation id="923957533152125119">Таныг нэвтэрсэн үед <ph name="BEGIN_LINK1" />хайлтын түүх<ph name="END_LINK1" /> болон <ph name="BEGIN_LINK2" />бусад төрлийн үйл ажиллагааг<ph name="END_LINK2" /> Google Бүртгэлд тань хадгалж магадгүй. Та хүссэн үедээ тэдгээрийг устгах боломжтой.</translation>
 <translation id="926205370408745186">Chrome-н үйл ажиллагаагаа Дижитал хэрэглээнээс устгах</translation>
 <translation id="927968626442779827">Google Chrome дээр Lite горимыг ашиглаарай</translation>
 <translation id="932327136139879170">Нүүр хуудас</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 63ae002c..d8b566b 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">गणना करत आहे...</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lens <ph name="BEGIN_NEW" />नवीन<ph name="END_NEW" /> सह इमेजचे भाषांतर करा</translation>
-<translation id="1385855801883526502">हायलाइट स्टायलाइझ करा</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> दिवसांपूर्वी ॲक्टिव्ह होते</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> सह शोधा</translation>
 <translation id="1406000523432664303">“Do Not Track”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> बटण</translation>
 <translation id="2000419248597011803">ॲड्रेस बार आणि सर्च बॉक्समधून तुमच्या डीफॉल्ट शोध इंजिनला काही कुकीज आणि शोध पाठवते</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# फाइल}other{# फाइल}}</translation>
-<translation id="2017836877785168846">ॲड्रेस बारमधील इतिहास आणि आपोआप पूर्ण केलेले साफ करते.</translation>
 <translation id="2021896219286479412">फुल स्क्रीन साइट नियंत्रणे</translation>
 <translation id="2038563949887743358">डेस्कटॉप साइट विनंती सुरू करा</translation>
 <translation id="2039379262107991683">रिमाइंडर मिळवण्यासाठी तुमच्या वाचन सूची यामध्ये पेज जोडा</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015"><ph name="BEGIN_NEW" />नवीन<ph name="END_NEW" /> Google लेन्स वापरून शोधा</translation>
 <translation id="4195643157523330669">नवीन टॅबमध्ये उघडा</translation>
 <translation id="4198423547019359126">कोणतीही डाउनलोड स्थाने उपलब्ध नाहीत</translation>
-<translation id="4206707945726604465">इतर प्रकारचा इतिहास साफ करण्यासाठी, <ph name="BEGIN_LINK1" />माझी Google अ‍ॅक्टिव्हिटी<ph name="END_LINK1" /> ला भेट द्या</translation>
 <translation id="4209895695669353772">Google ने सुचवलेला पर्सनलाइझ केलेला आशय मिळवण्यासाठी, सिंक सुरू करा</translation>
 <translation id="4225895483398857530">टूलबार शॉर्टकट</translation>
 <translation id="4242533952199664413">सेटिंग्ज उघडा</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - डाउनलोड करत आहे…</translation>
 <translation id="4404568932422911380">कोणतेही बुकमार्क नाहीत</translation>
 <translation id="4405224443901389797">यामध्ये हलवा…</translation>
+<translation id="4409271659088619928"><ph name="DSE" /> हे तुमचे शोध इंजीन आहे. लागू असल्यास, तुमचा शोध इतिहास हटवण्यासाठी, त्याच्या सूचना पहा.</translation>
 <translation id="4411535500181276704">लाइट मोड</translation>
 <translation id="4415276339145661267">तुमचे Google खाते व्यवस्थापित करा</translation>
 <translation id="4427306783828095590">वर्धित सुरक्षितता फिशिंग आणि मालवेअर अधिक चांगल्यारितीने ब्लॉक करते</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">पासवर्ड तपासा</translation>
 <translation id="6000066717592683814">Google ठेवा</translation>
 <translation id="6000203700195075278">पुन्हा फॉलो करा</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />शोध<ph name="END_LINK1" /> किंवा इतिहासाचे इतर प्रकार साफ करण्यासाठी, <ph name="BEGIN_LINK2" />माझी Google अ‍ॅक्टिव्हिटी<ph name="END_LINK2" /> ला भेट द्या</translation>
 <translation id="6005538289190791541">सुचवलेला पासवर्ड</translation>
 <translation id="6032091552407840792">ही चाचणी फक्त <ph name="BEGIN_LINK" />काही प्रदेश<ph name="END_LINK" /> यांमध्ये ॲक्टिव्ह आहे.</translation>
 <translation id="6033245666633565791">खुल्या वेबचे संरक्षण करत असताना, क्रॉस-साइट ट्रॅकिंगपासून तुमचे रक्षण करण्यासाठी, <ph name="BEGIN_LINK" />प्रायव्हसी सॅंडबाॅक्स<ph name="END_LINK" /> च्या आधारे Chrome नवीन तंत्रज्ञाने विकसित करत आहे.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">तुमच्यासाठी आणि वेबवरील प्रत्येकजणासाठी सुरक्षिततेत सुधारणा करते.</translation>
 <translation id="6618554661997243500">तुमच्यासाठी टॉप साइट आणि स्टोरी पाहण्यासाठी, होम बटणावर टॅप करा</translation>
 <translation id="6627583120233659107">फोल्डर संपादित करा</translation>
-<translation id="6635718764393004944"><ph name="DSE" /> हे तुमचे शोध इंजीन आहे. लागू असल्यास, तुमचा शोध इतिहास हटवण्यासाठी, त्यांच्या सूचना पहा.</translation>
 <translation id="663674369910034433">गोपनीयता, सुरक्षा आणि डेटा संग्रह यांच्याशी संबंधित आणखी सेटिंग्जसाठी, <ph name="BEGIN_LINK1" />सिंक<ph name="END_LINK1" /> आणि <ph name="BEGIN_LINK2" />Google सेवा<ph name="END_LINK2" /> पाहा</translation>
 <translation id="6643016212128521049">साफ करा</translation>
 <translation id="6643649862576733715">वाचवलेल्या डेटानुसार क्रमाने लावा</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 3e2e856..933fd92 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Mengira...</translation>
 <translation id="1383876407941801731">Carian</translation>
 <translation id="1384704387250346179">Terjemahkan imej dengan Google Lens <ph name="BEGIN_NEW" />Baharu<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Gayakan serlahan</translation>
 <translation id="1386674309198842382">Aktif <ph name="LAST_UPDATED" /> hari lalu</translation>
 <translation id="1397811292916898096">Cari dengan <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Jangan Kesan”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Butang <ph name="LINK_NAME" /> <ph name="MESSAGE" /></translation>
 <translation id="2000419248597011803">Menghantar beberapa kuki dan carian daripada bar alamat dan kotak carian ke enjin carian lalai anda</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Fail}other{# Fail}}</translation>
-<translation id="2017836877785168846">Kosongkan sejarah dan pelengkapan automatik dalam bar alamat.</translation>
 <translation id="2021896219286479412">Kawalan tapak skrin penuh</translation>
 <translation id="2038563949887743358">Hidupkan Minta tapak desktop</translation>
 <translation id="2039379262107991683">Tambahkan halaman pada Senarai Bacaan anda untuk mendapatkan peringatan</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Cari dengan Google Lens <ph name="BEGIN_NEW" />Baharu<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Buka dalam tab baharu</translation>
 <translation id="4198423547019359126">Tiada lokasi muat turun tersedia</translation>
-<translation id="4206707945726604465">Untuk mengosongkan bentuk sejarah lain, lawati <ph name="BEGIN_LINK1" />Aktiviti Google Saya<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Hidupkan penyegerakan untuk mendapatkan kandungan diperibadikan yang dicadangkan oleh Google</translation>
 <translation id="4225895483398857530">Pintasan bar alat</translation>
 <translation id="4242533952199664413">Buka tetapan</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Memuat turun…</translation>
 <translation id="4404568932422911380">Tiada penanda halaman</translation>
 <translation id="4405224443901389797">Alihkan ke…</translation>
+<translation id="4409271659088619928">Enjin carian anda ialah <ph name="DSE" />. Lihat arahan enjin carian itu untuk memadamkan sejarah carian anda, jika berkenaan.</translation>
 <translation id="4411535500181276704">Mod Ringkas</translation>
 <translation id="4415276339145661267">Urus Akaun Google anda</translation>
 <translation id="4427306783828095590">Perlindungan yang dipertingkatkan melakukan pelbagai lagi perkara untuk menyekat pancingan data dan perisian hasad</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Semak kata laluan</translation>
 <translation id="6000066717592683814">Kekalkan Google</translation>
 <translation id="6000203700195075278">Ikuti semula</translation>
-<translation id="6002623704405939939">Untuk mengosongkan <ph name="BEGIN_LINK1" />carian<ph name="END_LINK1" /> atau bentuk sejarah lain, lawati <ph name="BEGIN_LINK2" />Aktiviti Google Saya<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Kata laluan yang disyorkan</translation>
 <translation id="6032091552407840792">Percubaan ini hanya aktif di <ph name="BEGIN_LINK" />sesetengah rantau<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Dengan <ph name="BEGIN_LINK" />Kotak Pasir Privasi<ph name="END_LINK" />, Chrome membangunkan teknologi baharu untuk melindungi anda daripada penjejakan rentas laman sambil memelihara web terbuka.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Meningkatkan keselamatan untuk anda dan semua orang yang melayari web.</translation>
 <translation id="6618554661997243500">Untuk melihat tapak web dan cerita yang paling kerap anda lawati, ketik butang Skrin Utama</translation>
 <translation id="6627583120233659107">Edit folder</translation>
-<translation id="6635718764393004944">Enjin carian anda ialah <ph name="DSE" />. Jika berkenaan, lihat arahan enjin carian itu untuk memadamkan sejarah carian anda.</translation>
 <translation id="663674369910034433">Untuk mendapatkan pelbagai lagi tetapan yang berkaitan dengan privasi, keselamatan dan pengumpulan data, lihat <ph name="BEGIN_LINK1" />Penyegerakan<ph name="END_LINK1" /> dan <ph name="BEGIN_LINK2" />perkhidmatan Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Kosongkan</translation>
 <translation id="6643649862576733715">Isih mengikut jumlah penjimatan data</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
index 4e2a75b..1d1317a0 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">တွက်ချက်နေသည်…</translation>
 <translation id="1383876407941801731">ရှာဖွေမှု</translation>
 <translation id="1384704387250346179">Google Lens ဖြင့် ပုံကိုပြန်ဆိုရန် <ph name="BEGIN_NEW" />အသစ်<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">မြင်သာအောင်လုပ်ထားသည်ကို ပုံစံထည့်ရန်</translation>
 <translation id="1386674309198842382">ပြီးခဲ့သော <ph name="LAST_UPDATED" /> ရက်က အသုံးပြုထားသည်</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ဖြင့် ရှာပါ</translation>
 <translation id="1406000523432664303">'ခြေရာမခံပါနှင့်'</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ခလုတ်</translation>
 <translation id="2000419248597011803">လိပ်စာဘားနှင့် ရှာဖွေမှုအကွက်ထဲရှိ အချို့သော ကွတ်ကီးများနှင့် ရှာဖွေမှုများကို သင်၏မူရင်းရှာဖွေမှုအင်ဂျင်သို့ ပို့သည်</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ဖိုင်}other{# ဖိုင်}}</translation>
-<translation id="2017836877785168846">လိပ်စာဘားရှိ မှတ်တမ်းနှင့် အလိုအလျောက်ဖြည့်ခြင်းများကို ရှင်းလင်းရန်</translation>
 <translation id="2021896219286479412">မျက်နှာပြင်အပြည့် ထိန်းချုပ်မှု</translation>
 <translation id="2038563949887743358">ဆိုဒ်ကြီး တောင်းဆိုမှု ဖွင့်မည်</translation>
 <translation id="2039379262107991683">သတိပေးချက်ရယူရန် စာမျက်နှာများကို သင်၏ 'ဖတ်ရန်စာရင်း' သို့ ပေါင်းထည့်ပါ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens <ph name="BEGIN_NEW" />အသစ်<ph name="END_NEW" /> ဖြင့်ရှာခြင်း</translation>
 <translation id="4195643157523330669">တဘ်အသစ်တွင် ဖွင့်ရန်</translation>
 <translation id="4198423547019359126">ဒေါင်းလုဒ်တည်နေရာ မရှိပါ</translation>
-<translation id="4206707945726604465">အခြား မှတ်တမ်းပုံစံများကို ရှင်းထုတ်ရန် <ph name="BEGIN_LINK1" />ကျွန်ုပ်၏ Google လုပ်ဆောင်ချက်<ph name="END_LINK1" /> တွင် ဝင်ကြည့်ပါ</translation>
 <translation id="4209895695669353772">Google က အကြံပြုထားသည့် ပုဂ္ဂိုလ်ရေးသီးသန့် အကြောင်းအရာများကို ရယူရန် စင့်ခ်လုပ်ခြင်းကို ဖွင့်ပါ</translation>
 <translation id="4225895483398857530">ကိရိယာဘား ဖြတ်လမ်းလင့်ခ်</translation>
 <translation id="4242533952199664413">ဆက်တင်များကို ဖွင့်ရန်</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ဒေါင်းလုဒ်လုပ်နေသည်…</translation>
 <translation id="4404568932422911380">မည်သည့်လိပ်စာမျှ မရှိပါ</translation>
 <translation id="4405224443901389797">ဤနေရာသို့ ရွှေ့ရန်…</translation>
+<translation id="4409271659088619928">သင်၏ရှာဖွေရေး အင်ဂျင်သည် <ph name="DSE" /> ဖြစ်သည်။ သက်ဆိုင်မှုရှိပါက သင်၏ရှာဖွေမှတ်တမ်းကို ဖျက်ရန်အတွက် ၎င်း၏ ညွှန်ကြားချက်များကို ကြည့်ပါ။</translation>
 <translation id="4411535500181276704">အပေါ့စားမုဒ်</translation>
 <translation id="4415276339145661267">သင့် Google Account ကို စီမံခြင်း</translation>
 <translation id="4427306783828095590">အဆင့်မြှင့်တင်ထားသော ကာကွယ်မှုက ဖြားယောင်းမှုနှင့် မဲလ်ဝဲများကို ပိုမိုပိတ်ဆို့ပေးသည်</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">စကားဝှက်များ စစ်ဆေးရန်</translation>
 <translation id="6000066717592683814">Google ကို ဆက်သုံးရန်</translation>
 <translation id="6000203700195075278">ပြန်လည်လိုက်ကြည့်ရန်</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ရှာဖွေမှု<ph name="END_LINK1" /> (သို့) အခြား မှတ်တမ်းပုံစံများကို ရှင်းထုတ်ရန် <ph name="BEGIN_LINK2" />ကျွန်ုပ်၏ Google လုပ်ဆောင်ချက်<ph name="END_LINK2" /> တွင် ဝင်ကြည့်ပါ</translation>
 <translation id="6005538289190791541">အကြံပြုထားသည့် စကားဝှက်</translation>
 <translation id="6032091552407840792">ဤအစမ်းသုံးမှုကို <ph name="BEGIN_LINK" />ဒေသအချို့<ph name="END_LINK" /> တွင်သာ ရနိုင်သည်။</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />ပုဂ္ဂိုလ်ရေးဆိုင်ရာ လုံခြုံသည့်နေရာ<ph name="END_LINK" /> ဖြင့် Chrome သည် အများသုံးဝဘ်၏ လည်ပတ်မှုကို ထိန်းသိမ်းပေးပြီး ဝဘ်ဆိုက်အမျိုးမျိုးရှိ ခြေရာခံခြင်းများမှ သင့်ကိုကာကွယ်ပေးမည့် နည်းပညာအသစ်များကို ရေးဆွဲနေပါသည်။
@@ -885,7 +882,6 @@
 <translation id="661266467055912436">သင်နှင့် ဝဘ်ပေါ်ရှိ လူအားလုံးအတွက် လုံခြုံရေးကို တိုးမြှင့်ထားသည်။</translation>
 <translation id="6618554661997243500">သင့်အတွက် ထိပ်တန်းဝဘ်ဆိုက်များနှင့် သတင်းဆောင်းပါးများကြည့်ရန် 'ပင်မခလုတ်' ကို တို့ပါ</translation>
 <translation id="6627583120233659107">ဖိုလ်ဒါ တည်းဖြတ်ရန်</translation>
-<translation id="6635718764393004944">သင်၏ရှာဖွေရေး အင်ဂျင်သည် <ph name="DSE" /> ဖြစ်သည်။ သက်ဆိုင်မှုရှိပါက သင့်ရှာဖွေမှတ်တမ်းကို ဖျက်ရန် ၎င်း၏ညွှန်ကြားချက်များကို ကြည့်ပါ။</translation>
 <translation id="663674369910034433">ပုဂ္ဂိုလ်ရေးဆိုင်ရာ၊ လုံခြုံရေး၊ ဒေတာစုဆောင်းမှုတို့နှင့် ဆက်စပ်နေသည့် နောက်ထပ် ဆက်တင်များအတွက် <ph name="BEGIN_LINK1" />စင့်ခ်လုပ်ခြင်း<ph name="END_LINK1" /> နှင့် <ph name="BEGIN_LINK2" />Google ဝန်ဆောင်မှုများ<ph name="END_LINK2" /> ကို ကြည့်ပါ</translation>
 <translation id="6643016212128521049">ရှင်းရန်</translation>
 <translation id="6643649862576733715">သိမ်းဆည်းလိုက်သည့် ဒေတာပမာဏအလိုက် စီရန်</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
index b553a04..fa759ab 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">हिसाब गर्दै…</translation>
 <translation id="1383876407941801731">खोज्नुहोस्</translation>
 <translation id="1384704387250346179">Google लेन्स प्रयोग गरी फोटोमा भएका कुरा अनुवाद गर्नुहोस् <ph name="BEGIN_NEW" />नयाँ<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">हाइलाइट गरिएको पाठ अर्को शैलीको बनाउनुहोस्</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> दिनअघि सक्रिय</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> मार्फत खोज्नुहोस्</translation>
 <translation id="1406000523432664303">“ट्रयाक नगर्नुहोस्”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> बटन</translation>
 <translation id="2000419248597011803">यसले ठेगाना पट्टी र खोज बाकसका केही कुकी र खोजहरूलाई तपाईंको डिफल्ट खोज इन्जिनमा पठाउँछ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# फाइल}other{# फाइलहरू}}</translation>
-<translation id="2017836877785168846">ठेगाना पट्टीबाट इतिहास र स्वतः पूर्णतासम्बन्धी सुविधाहरूलाई खाली गर्दछ।</translation>
 <translation id="2021896219286479412">पूर्ण स्क्रिनको साइटका नियन्त्रणहरू</translation>
 <translation id="2038563949887743358">अनुरोध डेस्कटप साइट खोल्नुहोस्</translation>
 <translation id="2039379262107991683">पेजहरूबारे रिमाइन्डर प्राप्त गर्न ती पेजहरू आफ्नो अध्ययन सूचीमा हाल्नुहोस्।</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens प्रयोग गरी खोज्नुहोस् <ph name="BEGIN_NEW" />नयाँ<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">नयाँ ट्याबमा खोल्नुहोस्</translation>
 <translation id="4198423547019359126">डाउनलोडसम्बन्धी कुनै पनि स्थानहरू उपलब्ध छैनन्</translation>
-<translation id="4206707945726604465">अन्य प्रकारका इतिहास मेटाउन <ph name="BEGIN_LINK1" />My Google Activity<ph name="END_LINK1" /> मा जानुहोस्</translation>
 <translation id="4209895695669353772">Google ले सिफारिस गरेको वैयक्तीकृत सामग्री प्राप्त गर्न सिंक गर्ने सुविधा सक्रिय गर्नुहोस्</translation>
 <translation id="4225895483398857530">टुलबारको सर्टकट</translation>
 <translation id="4242533952199664413">सेटिङहरू खोल्नुहोस्</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - डाउनलोड गरिँदै छ…</translation>
 <translation id="4404568932422911380">कुनै पनि पुस्तक चिन्ह छैन</translation>
 <translation id="4405224443901389797">यहाँ सार्नुहोस्…</translation>
+<translation id="4409271659088619928">तपाईंको डिफल्ट सर्च इन्जिन <ph name="DSE" /> हो। तपाईंको सर्च इन्जिनमा खोजको इतिहास मेटाउन मिल्छ भने खोज इतिहास मेटाउन सर्च इन्जिनले उपलब्ध गराएका निर्देशनहरू हेर्नुहोस्।</translation>
 <translation id="4411535500181276704">लाइट मोड</translation>
 <translation id="4415276339145661267">आफ्नो Google खाताको व्यवस्थापन गर्नुहोस्</translation>
 <translation id="4427306783828095590">परिष्कृत सुरक्षा प्रयोग गरी फिसिङ तथा मालवेयरमाथि अझ राम्रोसँग रोक लगाउन सकिन्छ</translation>
@@ -773,7 +771,6 @@
 <translation id="5979084224081478209">पासवर्डहरूको जाँच गर्नुहोस्</translation>
 <translation id="6000066717592683814">Google लाई डिफल्ट खोज इञ्जिनका रूपमा कायम राख्नुहोस्</translation>
 <translation id="6000203700195075278">पुनः फलो गर्नुहोस्</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />खोज इतिहास<ph name="END_LINK1" /> वा अन्य प्रकार का इतिहास मेटाउन '<ph name="BEGIN_LINK2" />मैले Google मा गरेका क्रियाकलाप<ph name="END_LINK2" />'मा जानुहोस्</translation>
 <translation id="6005538289190791541">सिफारिस गरिएको पासवर्ड</translation>
 <translation id="6032091552407840792">यो ट्रायल सुविधा <ph name="BEGIN_LINK" />केही क्षेत्र<ph name="END_LINK" />मा मात्र सक्रिय छ।</translation>
 <translation id="6033245666633565791">खुला वेबको जीवन्तता कायम राख्दै विभिन्न साइटमा प्रयोग गरिने क्रियाकलाप ट्र्याक गर्ने प्रविधिबाट तपाईंलाई सुरक्षित राख्नका निम्ति Chrome ले <ph name="BEGIN_LINK" />प्राइभेसी स्यान्डबक्स<ph name="END_LINK" />का सहायताले नयाँ प्रविधिहरू विकास गर्दै छ।
@@ -852,6 +849,7 @@
 <translation id="6441734959916820584">नाम अत्यन्तै लामो छ</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# छवि}other{# फोटो}}</translation>
 <translation id="6447558397796644647">उक्त पुस्तक चिन्ह फेला पार्न सकिएन। आफ्नो हिज्जे जाँच्नुहोस् वा कुनै नयाँ पुस्तक चिन्ह थप्नुहोस्।</translation>
+<translation id="6459045781120991510">सर्वेक्षणहरू</translation>
 <translation id="6461962085415701688">फाइल खोल्न सकिँदैन</translation>
 <translation id="6464977750820128603">तपाईं आफूले Chrome मार्फत भ्रमण गर्ने साइटहरू हेर्न र तिनमा टाइमर सेट गर्न सक्नुहुन्छ।\n\nGoogle ले तपाईंले टाइमर सेट गर्नुभएका साइटहरू तथा उक्त साइट भ्रमण गर्दा बिताउनुभएको समयसम्बन्धी जानकारी प्राप्त गर्छ। यो जानकारी डिजिटल वेलबिइङ सुविधालाई अझ राम्रो बनाउनका निम्ति प्रयोग गरिन्छ।</translation>
 <translation id="6475951671322991020">भिडियो डाउनलोड गर्नुहोस्</translation>
@@ -884,7 +882,6 @@
 <translation id="661266467055912436">तपाईं र वेब प्रयोग गर्ने सम्पूर्ण प्रयोगकर्ताहरूलाई झन् सुरक्षित पार्छ।</translation>
 <translation id="6618554661997243500">तपाईं आफ्ना लागि सिफारिस गरिएका शीर्ष साइट तथा समाचारहरू हेर्न चाहनुहुन्न भने होम बटनमा ट्याप गर्नुहोस्</translation>
 <translation id="6627583120233659107">फोल्डर सम्पादन गर्नुहोस्</translation>
-<translation id="6635718764393004944">तपाईंको डिफल्ट सर्च इन्जिन <ph name="DSE" /> हो। लागू हुन्छ भने आफ्नो खोजको इतिहास मेटाउन सो सर्च इन्जिनमा दिइएका निर्देशहरू हेर्नुहोस्।</translation>
 <translation id="663674369910034433">गोपनीयता, सुरक्षा र डेटाको सङ्कलनसँग सम्बन्धित थप सेटिङका लागि <ph name="BEGIN_LINK1" />सिंक<ph name="END_LINK1" /> तथा <ph name="BEGIN_LINK2" />Google का सेवाहरू<ph name="END_LINK2" /> नामक खण्ड हेर्नुहोस्</translation>
 <translation id="6643016212128521049">खालि गर्नुहोस्</translation>
 <translation id="6643649862576733715">बचत गरिएको डेटाको मात्राद्वारा क्रमबद्ध गर्नुहोस्</translation>
@@ -968,6 +965,7 @@
 <translation id="7242755609445462077">शैलीबद्ध हाइलाइट <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558"><ph name="TARGET_DEVICE_NAME" /> को Chrome मा सिंक सुविधा सक्रिय गरिएको छ भन्ने कुरा सुनिश्चित गर्नुहोस्</translation>
 <translation id="7252076891734325316">आफ्नो फोन कम्प्युटरको छेउमा राख्नुहोस्</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" /> मा <ph name="ONE_TIME_CODE" /> पेस गर्ने हो?</translation>
 <translation id="7274013316676448362">रोक लगाइएका साइटहरू</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> परिवर्तन गर्ने हो?</translation>
 <translation id="7290209999329137901">नाम बदल्ने सुविधा उपलब्ध छैन</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 e308542..703440d 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Berekenen…</translation>
 <translation id="1383876407941801731">Zoeken</translation>
 <translation id="1384704387250346179">Afbeelding vertalen met Google Lens <ph name="BEGIN_NEW" />Nieuw<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Markering stylen</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> dagen geleden actief</translation>
 <translation id="1397811292916898096">Zoeken met <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Niet bijhouden</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knop</translation>
 <translation id="2000419248597011803">Hiermee worden bepaalde cookies en de zoekopdrachten in de adresbalk en in het zoekvak verzonden naar je standaard zoekmachine</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# bestand}other{# bestanden}}</translation>
-<translation id="2017836877785168846">Wist de geschiedenis en automatische aanvullingen in de adresbalk.</translation>
 <translation id="2021896219286479412">Siteopties op volledig scherm</translation>
 <translation id="2038563949887743358">'Desktopsite aanvragen' aanzetten</translation>
 <translation id="2039379262107991683">Voeg pagina's aan je leeslijst toe om een herinnering te krijgen</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Talen</translation>
 <translation id="4183868528246477015">Zoeken met Google Lens <ph name="BEGIN_NEW" />Nieuw<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Openen op nieuw tabblad</translation>
+<translation id="4196597275619698563">Kaart maken</translation>
 <translation id="4198423547019359126">Geen beschikbare downloadlocaties</translation>
-<translation id="4206707945726604465">Als je andere soorten geschiedenis wilt wissen, ga je naar <ph name="BEGIN_LINK1" />Mijn Google-activiteit<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Zet de synchronisatie aan om suggesties voor gepersonaliseerde content van Google te ontvangen</translation>
 <translation id="4225895483398857530">Snelkoppeling voor werkbalk</translation>
 <translation id="4242533952199664413">Instellingen openen</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Downloaden…</translation>
 <translation id="4404568932422911380">Geen bookmarks</translation>
 <translation id="4405224443901389797">Verplaatsen naar…</translation>
+<translation id="4409271659088619928">Je zoekmachine is <ph name="DSE" />. Bekijk de instructies van je zoekmachine voor het verwijderen van je zoekgeschiedenis (indien van toepassing).</translation>
 <translation id="4411535500181276704">Lite-versie</translation>
 <translation id="4415276339145661267">Je Google-account beheren</translation>
 <translation id="4427306783828095590">Geoptimaliseerde beveiliging die je nog beter beschermt tegen phishing en malware</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">Wachtwoorden controleren</translation>
 <translation id="6000066717592683814">Google blijven gebruiken</translation>
 <translation id="6000203700195075278">Opnieuw volgen</translation>
-<translation id="6002623704405939939">Als je je <ph name="BEGIN_LINK1" />zoekgeschiedenis<ph name="END_LINK1" /> of andere geschiedenis wilt wissen, ga je naar <ph name="BEGIN_LINK2" />Mijn Google-activiteit<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Voorgesteld wachtwoord</translation>
 <translation id="6032091552407840792">Deze proef is alleen actief in <ph name="BEGIN_LINK" />bepaalde regio's<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Met <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> ontwikkelt Chrome nieuwe technologieën om je te beschermen tegen tracking op verschillende sites terwijl het open web behouden blijft.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">Verbetert de beveiliging voor jou en alle andere internetgebruikers.</translation>
 <translation id="6618554661997243500">Tik op de startknop om je populaire sites en recente artikelen te bekijken</translation>
 <translation id="6627583120233659107">Map bewerken</translation>
-<translation id="6635718764393004944">Je zoekmachine is <ph name="DSE" />. Bekijk indien van toepassing de bijbehorende instructies om je zoekgeschiedenis te verwijderen.</translation>
 <translation id="663674369910034433">Bekijk <ph name="BEGIN_LINK1" />Synchronisatie<ph name="END_LINK1" /> en <ph name="BEGIN_LINK2" />Google-services<ph name="END_LINK2" /> voor meer instellingen over privacy, beveiliging en gegevensverzameling.</translation>
 <translation id="6643016212128521049">Wissen</translation>
 <translation id="6643649862576733715">Sorteren op hoeveelheid bespaarde data</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">Zoekopdrachten en URL's automatisch aanvullen</translation>
 <translation id="7707922173985738739">Mobiele data gebruiken</translation>
 <translation id="7725024127233776428">Hier zie je pagina's waaraan je een bookmark toevoegt</translation>
+<translation id="7731260005404856143">Er kunnen <ph name="BEGIN_LINK1" />andere vormen van activiteit<ph name="END_LINK1" /> worden opgeslagen op je Google-account als je bent ingelogd. Je kunt ze verwijderen wanneer je wilt.</translation>
 <translation id="7757787379047923882">Tekst gedeeld vanaf <ph name="DEVICE_NAME" /></translation>
 <translation id="7761849928583394409">Datum en tijd kiezen</translation>
 <translation id="7762668264895820836">SD-kaart <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">Je offline bestanden bekijken</translation>
 <translation id="8856607253650333758">Beschrijvingen ophalen</translation>
 <translation id="8873817150012960745">Tik hier om te beginnen</translation>
+<translation id="8881973373982641723">Hiermee wis je de geschiedenis, waaronder die in het zoekvak.</translation>
 <translation id="889338405075704026">Naar Chrome-instellingen</translation>
 <translation id="8898822736010347272">Stuurt URL's van sommige pagina's die je bezoekt, beperkte systeeminformatie en bepaalde paginacontent naar Google om nieuwe dreigingen te ontdekken en iedereen op internet te beschermen.</translation>
 <translation id="8909135823018751308">Delen</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">Kan niet bellen</translation>
 <translation id="9212845824145208577">Kan niet verder omlaag gaan. Probeer lager op de pagina te beginnen.</translation>
 <translation id="9219103736887031265">Afbeeldingen</translation>
+<translation id="923957533152125119"><ph name="BEGIN_LINK1" />Zoekgeschiedenis<ph name="END_LINK1" /> en <ph name="BEGIN_LINK2" />andere vormen van activiteit<ph name="END_LINK2" /> kunnen worden opgeslagen op je Google-account als je bent ingelogd. Je kunt ze verwijderen wanneer je wilt.</translation>
 <translation id="926205370408745186">Je Chrome-activiteit verwijderen uit Digitaal welzijn</translation>
 <translation id="927968626442779827">Lite-versie van Google Chrome gebruiken</translation>
 <translation id="932327136139879170">Homepage</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
index df020ad..03364dc7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Beregner …</translation>
 <translation id="1383876407941801731">Søk</translation>
 <translation id="1384704387250346179">Oversett bildet med Google Lens <ph name="BEGIN_NEW" />Nyhet<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stiliser høydepunkt</translation>
 <translation id="1386674309198842382">Aktiv for <ph name="LAST_UPDATED" /> dager siden</translation>
 <translation id="1397811292916898096">Søk med <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">«Ingen sporing»</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />-knapp</translation>
 <translation id="2000419248597011803">Sender noen informasjonskapsler og søk fra adressefeltet og søkefeltet samt noen informasjonskapsler til standardsøkemotoren din</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fil}other{# filer}}</translation>
-<translation id="2017836877785168846">Tømmer loggen og fjerner automatiske fullføringer fra adressefeltet.</translation>
 <translation id="2021896219286479412">Navigering i full skjerm</translation>
 <translation id="2038563949887743358">Slå på Bruk skrivebordsversjon</translation>
 <translation id="2039379262107991683">Legg til sider på leselisten for å få påminnelser</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Søk med Google Lens <ph name="BEGIN_NEW" />Nyhet<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Åpne i ny fane</translation>
 <translation id="4198423547019359126">Ingen tilgjengelige nedlastingssteder</translation>
-<translation id="4206707945726604465">For å slette andre former for logg, besøk <ph name="BEGIN_LINK1" />Min Google-aktivitet<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">For å få forslag om personlig tilpasset innhold fra Google, slå på synkronisering</translation>
 <translation id="4225895483398857530">Verktøylinje-snarvei</translation>
 <translation id="4242533952199664413">Åpne innstillingene</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Laster ned …</translation>
 <translation id="4404568932422911380">Ingen bokmerker</translation>
 <translation id="4405224443901389797">Flytt til …</translation>
+<translation id="4409271659088619928">Søkemotoren din er <ph name="DSE" />. Se eventuelt instruksjonene deres om hvordan du sletter søkeloggen din.</translation>
 <translation id="4411535500181276704">Forenklet modus</translation>
 <translation id="4415276339145661267">Administrer Google-kontoen din</translation>
 <translation id="4427306783828095590">Økt beskyttelse gjør mer for å blokkere nettfisking og skadelig programvare</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Kontrollér passordene</translation>
 <translation id="6000066717592683814">Behold Google</translation>
 <translation id="6000203700195075278">Følg på nytt</translation>
-<translation id="6002623704405939939">For å tømme <ph name="BEGIN_LINK1" />søkeloggen<ph name="END_LINK1" /> eller andre logger, besøk <ph name="BEGIN_LINK2" />Min Google-aktivitet<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Foreslått passord</translation>
 <translation id="6032091552407840792">Denne utprøvingen er kun aktiv i <ph name="BEGIN_LINK" />enkelte regioner<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Med <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />utvikler Chrome nye teknologier for å sikre deg fra sporing på tvers av sider samtidig som det åpne nettet ivaretas.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Øker sikkerheten for deg og alle andre på nettet.</translation>
 <translation id="6618554661997243500">For å se anbefalte nettsteder og nyhetssaker for deg, trykk på knappen Gå til startsiden</translation>
 <translation id="6627583120233659107">Rediger mappen</translation>
-<translation id="6635718764393004944">Søkemotoren din er <ph name="DSE" />. Se eventuelt instruksjonene deres for hvordan du sletter søkeloggen din.</translation>
 <translation id="663674369910034433">Se <ph name="BEGIN_LINK1" />Synkronisering<ph name="END_LINK1" /> og <ph name="BEGIN_LINK2" />Google-tjenester<ph name="END_LINK2" /> for flere innstillinger knyttet til personvern, sikkerhet og datainnsamling.</translation>
 <translation id="6643016212128521049">Tøm</translation>
 <translation id="6643649862576733715">Sortér etter mengden data som er spart</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
index 9a3b4f06..710df2f6 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ଗଣନା ହେଉଛି…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">Google Lens ସହ ଛବି ଅନୁବାଦ <ph name="BEGIN_NEW" />ନୂଆ<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ହାଇଲାଇଟ୍ କରାଯାଇଥିବା ଟେକ୍ସଟକୁ ଷ୍ଟାଇଲାଇଜ୍ କରନ୍ତୁ</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> ଦିନ ପୂର୍ବେ ସକ୍ରିୟ ଥିଲା</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ମାଧ୍ୟମରେ ସନ୍ଧାନ କରନ୍ତୁ</translation>
 <translation id="1406000523432664303">“ଟ୍ରାକ୍ କରନ୍ତୁ ନାହିଁ”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ବଟନ୍</translation>
 <translation id="2000419248597011803">ଆପଣଙ୍କର ଡିଫଲ୍ଟ ସନ୍ଧାନ ଇଞ୍ଜିନ୍‌କୁ ଠିକଣା ବାର୍‌ ଏବଂ ସନ୍ଧାନ ବାକ୍ସରୁ କିଛି କୁକୀ ଏବଂ ସନ୍ଧାନ ପଠାନ୍ତୁ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{#ଟି ଫାଇଲ୍}other{#ଟି ଫାଇଲ୍}}</translation>
-<translation id="2017836877785168846">ଠିକଣା ବାର୍‌ରେ ଥିବା ଇତିବୃତ୍ତି ଓ ଅଟୋକମ୍ପ୍ଲିସେନ୍‍ଗୁଡ଼ିକୁ ଖାଲି କରନ୍ତୁ।</translation>
 <translation id="2021896219286479412">ପୂର୍ଣ୍ଣ-ସ୍କ୍ରିନ୍ ସାଇଟ୍ ନିୟନ୍ତ୍ରଣ</translation>
 <translation id="2038563949887743358">ଅନୁରୋଧ ଡେକ୍ସଟପ୍ ସାଇଟ୍ ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="2039379262107991683">ଏକ ରିମାଇଣ୍ଡର୍ ପାଇବା ପାଇଁ ଆପଣଙ୍କ ପଢ଼ିବା ତାଲିକାରେ ପୃଷ୍ଠାଗୁଡ଼ିକୁ ଯୋଗ କରନ୍ତୁ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens <ph name="BEGIN_NEW" />New<ph name="END_NEW" /> ରେ ଖୋଜନ୍ତୁ</translation>
 <translation id="4195643157523330669">ନୂତନ ଟ୍ୟାବରେ ଖୋଲନ୍ତୁ</translation>
 <translation id="4198423547019359126">କୌଣସି ଡାଉନ୍‍‍‍ଲୋଡ୍ ହୋଇଥିବା ଲୋକେସନ୍ ଉପଲବ୍ଧ ନାହିଁ</translation>
-<translation id="4206707945726604465">ଅନ୍ୟ ଫର୍ମର ଇତିହାସକୁ ଖାଲି କରିବା ପାଇଁ <ph name="BEGIN_LINK1" />ମୋ Google କାର୍ଯ୍ୟକଳାପ<ph name="END_LINK1" />କୁ ଭିଜିଟ୍ କରନ୍ତୁ</translation>
 <translation id="4209895695669353772">Google ଦ୍ୱାରା ପ୍ରସ୍ତାବିତ ବ୍ୟକ୍ତିଗତକୃତ ବିଷୟବସ୍ତୁ ପ୍ରାପ୍ତ କରିବା ପାଇଁ, ସିଙ୍କ ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="4225895483398857530">ଟୁଲବାର୍ ସର୍ଟକଟ୍</translation>
 <translation id="4242533952199664413">ସେଟିଂସ୍‌ ଖୋଲନ୍ତୁ</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ଡାଉନଲୋଡ୍ ହେଉଛି…</translation>
 <translation id="4404568932422911380">କୌଣସି ବୁକ୍‍ମାର୍କ ନାହିଁ</translation>
 <translation id="4405224443901389797">ଏଥିକୁ ଘୁଞ୍ଚାନ୍ତୁ…</translation>
+<translation id="4409271659088619928">ଆପଣଙ୍କ ସନ୍ଧାନ ଇଞ୍ଜିନ୍ ହେଉଛି <ph name="DSE" />। ଯଦି ଲାଗୁ ହୁଏ, ତେବେ ଆପଣଙ୍କ ସନ୍ଧାନ ଇତିହାସକୁ ଡିଲିଟ୍ କରିବା ପାଇଁ ସେଗୁଡ଼ିକର ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ।</translation>
 <translation id="4411535500181276704">ଲାଇଟ୍ ମୋଡ୍</translation>
 <translation id="4415276339145661267">ଆପଣଙ୍କର Google ଆକାଉଣ୍ଟ ପରିଚାଳନା କରନ୍ତୁ</translation>
 <translation id="4427306783828095590">ଉନ୍ନତ ସୁରକ୍ଷା ଫିସିଂ ଓ ମାଲୱେୟାରକୁ ବ୍ଲକ୍ କରିବାକୁ ଅନେକ କିଛି କରେ</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">ପାସ୍‌ୱାର୍ଡଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ</translation>
 <translation id="6000066717592683814">Googleକୁ ଡିଫଲ୍ଟ ଭାବେ ରଖନ୍ତୁ</translation>
 <translation id="6000203700195075278">ପୁଣି ଅନୁସରଣ କରନ୍ତୁ</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ସନ୍ଧାନ<ph name="END_LINK1" /> କିମ୍ବା ଅନ୍ୟ ଫର୍ମର ଇତିହାସଗୁଡ଼ିକୁ ଖାଲି କରିବା ପାଇଁ, <ph name="BEGIN_LINK2" />ମୋ Google କାର୍ଯ୍ୟକଳାପ<ph name="END_LINK2" />କୁ ଭିଜିଟ୍ କରନ୍ତୁ</translation>
 <translation id="6005538289190791541">ପ୍ରସ୍ତାବିତ ପାସ୍‌ୱାର୍ଡ</translation>
 <translation id="6032091552407840792">ଏହି ଟ୍ରାଏଲ୍ କେବଳ <ph name="BEGIN_LINK" />କିଛି ଅଞ୍ଚଳ<ph name="END_LINK" />ରେ ସକ୍ରିୟ ଅଛି।</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> ସହିତ Chrome ଓପନ ୱେବକୁ ସଂରକ୍ଷିତ କରିବା ସମୟରେ କ୍ରସ୍-ସାଇଟ୍ ଟ୍ରାକିଂରୁ ଆପଣଙ୍କୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ନୂଆ ଟେକ୍ନୋଲୋଜିଗୁଡ଼ିକୁ ବିକଶିତ କରୁଛି।
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">ନାମଟି ବହୁତ ଲମ୍ବା ଅଟେ</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{#ଟି ଛବି}other{#ଟି ଛବି}}</translation>
 <translation id="6447558397796644647">ସେହି ବୁକମାର୍କ ମିଳୁନାହିଁ। ଆପଣଙ୍କର ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଏକ ନୂଆ ବୁକମାର୍କ ଯୋଗ କରନ୍ତୁ।</translation>
+<translation id="6459045781120991510">ସର୍ଭେଗୁଡ଼ିକ</translation>
 <translation id="6461962085415701688">ଫାଇଲ୍ ଖୋଲିପାରିବ ନାହିଁ</translation>
 <translation id="6464977750820128603">ଆପଣ Chromeରେ ଯେଉଁ ସାଇଟ୍‍ଗୁଡ଼ିକୁ ଯାଆନ୍ତି, ସେଗୁଡ଼ିକୁ ଦେଖିପାରିବେ ଏବଂ ସେଗୁଡ଼ିକ ପାଇଁ ଟାଇମର୍‌ଗୁଡ଼ିକ ସେଟ୍‌ କରିପାରିବେ। \n\nଆପଣ କେଉଁ ସାଇଟ୍‍ଗୁଡ଼ିକ ପାଇଁ ଟାଇମର୍‌ଗୁଡ଼ିକ ସେଟ୍‌ କରନ୍ତି ଏବଂ ଆପଣ ସେଗୁଡ଼ିକୁ କେତେ ସମୟ ପାଇଁ ଯାଆନ୍ତି, Google ସେହି ବିଷୟରେ ସୂଚନା ପ୍ରାପ୍ତ କରେ। ଡିଜିଟାଲ୍ ୱେଲ୍‍ବିଂକୁ ଉନ୍ନତ କରିବାରେ ଏହି ସୂଚନା ବ୍ୟବହାର କରାଯାଏ।</translation>
 <translation id="6475951671322991020">ଭିଡିଓ ଡାଉନ୍‌ଲୋଡ୍ କରନ୍ତୁ</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">ଆପଣ ଏବଂ ୱେବରେ ଥିବା ପ୍ରତ୍ୟେକ ବ୍ୟକ୍ତିଙ୍କ ପାଇଁ ସୁରକ୍ଷାକୁ ଉନ୍ନତ କରେ।</translation>
 <translation id="6618554661997243500">ଆପଣଙ୍କ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଶ୍ରେଷ୍ଠ ସାଇଟ୍ ଏବଂ ଷ୍ଟୋରୀଗୁଡ଼ିକୁ ଦେଖିବାକୁ, ହୋମ୍ ବଟନରେ ଟାପ୍ କରନ୍ତୁ</translation>
 <translation id="6627583120233659107">ଫୋଲ୍ଡର୍ ଏଡିଟ୍ କରନ୍ତୁ</translation>
-<translation id="6635718764393004944">ଆପଣଙ୍କ ସନ୍ଧାନ ଇଞ୍ଜିନ୍ ହେଉଛି <ph name="DSE" />। ଯଦି ଲାଗୁ ହୁଏ, ଆପଣଙ୍କ ସନ୍ଧାନ ଇତିହାସ ଡିଲିଟ୍ କରିବାକୁ ସେମାନଙ୍କ ନିର୍ଦ୍ଦେଶଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ।</translation>
 <translation id="663674369910034433">ଗୋପନୀୟତା, ସୁରକ୍ଷା ଏବଂ ଡାଟା ସଂଗ୍ରହ ସମ୍ବନ୍ଧିତ ଅଧିକ ସେଟିଂସ୍ ପାଇଁ <ph name="BEGIN_LINK1" />ସିଙ୍କ୍<ph name="END_LINK1" /> ଏବଂ <ph name="BEGIN_LINK2" />Google ସେବାଗୁଡ଼ିକୁ<ph name="END_LINK2" /> ଦେଖନ୍ତୁ</translation>
 <translation id="6643016212128521049">ଖାଲି କରନ୍ତୁ</translation>
 <translation id="6643649862576733715">ସେଭ୍ କରାଯାଇଥିବା ଡାଟାର ପରିଣାମ ଅନୁଯାୟୀ କ୍ରମବଦ୍ଧ କରାଯାଇଛି</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">ଷ୍ଟାଇଲାଇଜଡ୍ ହାଇଲାଇଟ୍ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Chromeରେ <ph name="TARGET_DEVICE_NAME" />ର ସିଙ୍କ୍ ଚାଲୁ ହୋଇଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ</translation>
 <translation id="7252076891734325316">ଆପଣଙ୍କ ଫୋନକୁ କମ୍ପ୍ୟୁଟର ପାଖରେ ରଖନ୍ତୁ</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" />ରେ <ph name="ONE_TIME_CODE" /> ଦାଖଲ କରିବେ?</translation>
 <translation id="7274013316676448362">ବ୍ଲକ୍ କରାଯାଇଥିବା ସାଇଟ୍</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> ପରିବର୍ତ୍ତନ କରିବେ?</translation>
 <translation id="7290209999329137901">ଯାହା ଉପଲବ୍ଧ ନାହିଁ ତା’କୁ ରିନେମ୍ କରନ୍ତୁ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
index 60d66dd..0e91814 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ਗਣਨਾ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…</translation>
 <translation id="1383876407941801731">ਖੋਜੋ</translation>
 <translation id="1384704387250346179">Google Lens ਨਾਲ ਚਿੱਤਰ ਦਾ ਅਨੁਵਾਦ ਕਰੋ <ph name="BEGIN_NEW" />ਨਵਾਂ<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ਹਾਈਲਾਈਟ ਸਟਾਈਲਾਈਜ਼ ਕਰੋ</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> ਦਿਨ ਪਹਿਲਾਂ ਕਿਰਿਆਸ਼ੀਲ</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ਨਾਲ ਖੋਜੋ</translation>
 <translation id="1406000523432664303">‘ਟਰੈਕ ਨਾ ਕਰੋ’</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> ਬਟਨ</translation>
 <translation id="2000419248597011803">ਪਤਾ ਬਾਰ ਅਤੇ ਖੋਜ ਬਾਕਸ ਤੋਂ ਕੁਝ ਕੁਕੀਜ਼ ਅਤੇ ਖੋਜਾਂ ਤੁਹਾਡੇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਖੋਜ ਇੰਜਣ ਨੂੰ ਭੇਜਦੀ ਹੈ</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ਫ਼ਾਈਲ}one{# ਫ਼ਾਈਲ}other{# ਫ਼ਾਈਲਾਂ}}</translation>
-<translation id="2017836877785168846">ਪਤਾ ਪੱਟੀ ਵਿੱਚੋਂ ਇਤਿਹਾਸ ਅਤੇ ਸਵੈ-ਪੂਰਨਤਾਵਾਂ ਨੂੰ ਕਲੀਅਰ ਕਰਦੀ ਹੈ।</translation>
 <translation id="2021896219286479412">ਪੂਰੀ ਸਕ੍ਰੀਨ ਦੇ ਸਾਈਟ ਕੰਟਰੋਲ</translation>
 <translation id="2038563949887743358">ਬੇਨਤੀ ਡੈਸਕਟਾਪ ਸਾਈਟ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="2039379262107991683">ਰਿਮਾਈਂਡਰ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਪੰਨਿਆਂ ਨੂੰ ਆਪਣੀ ਪੜ੍ਹਨ-ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">'Google ਲੈਂਜ਼' ਨਾਲ ਖੋਜੋ <ph name="BEGIN_NEW" />ਨਵਾਂ<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਖੋਲ੍ਹੋ</translation>
 <translation id="4198423547019359126">ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਕੋਈ ਟਿਕਾਣਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ</translation>
-<translation id="4206707945726604465">ਹੋਰ ਕਿਸਮਾਂ ਦੇ ਇਤਿਹਾਸ ਨੂੰ ਕਲੀਅਰ ਕਰਨ ਲਈ, <ph name="BEGIN_LINK1" />ਮੇਰੀ Google ਸਰਗਰਮੀ<ph name="END_LINK1" /> 'ਤੇ ਜਾਓ</translation>
 <translation id="4209895695669353772">Google ਵੱਲੋਂ ਸੁਝਾਈ ਵਿਅਕਤੀਗਤ ਬਣਾਈ ਗਈ ਸਮੱਗਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ, ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="4225895483398857530">ਟੂਲਬਾਰ ਸ਼ਾਰਟਕੱਟ</translation>
 <translation id="4242533952199664413">ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ਨੂੰ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…</translation>
 <translation id="4404568932422911380">ਕੋਈ ਬੁੱਕਮਾਰਕ ਨਹੀਂ</translation>
 <translation id="4405224443901389797">ਇਸ ਵਿੱਚ ਲਿਜਾਓ…</translation>
+<translation id="4409271659088619928">ਤੁਹਾਡਾ ਖੋਜ ਇੰਜਣ <ph name="DSE" /> ਹੈ। ਲਾਗੂ ਹੋਣ 'ਤੇ, ਆਪਣਾ ਖੋਜ ਇਤਿਹਾਸ ਮਿਟਾਉਣ ਲਈ ਉਹਨਾਂ ਦੀਆਂ ਹਿਦਾਇਤਾਂ ਦੇਖੋ।</translation>
 <translation id="4411535500181276704">ਲਾਈਟ ਮੋਡ</translation>
 <translation id="4415276339145661267">ਆਪਣੇ Google ਖਾਤੇ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ</translation>
 <translation id="4427306783828095590">ਧੋਖਾਧੜੀ ਅਤੇ ਮਾਲਵੇਅਰ ਨੂੰ ਬਲਾਕ ਕਰਨ ਵਾਸਤੇ ਵਿਸਤ੍ਰਿਤ ਸੁਰੱਖਿਆ ਹੋਰ ਵੱਧ ਕੰਮ ਕਰਦੀ ਹੈ</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">ਪਾਸਵਰਡਾਂ ਦੀ ਜਾਂਚ ਕਰੋ</translation>
 <translation id="6000066717592683814">Google ਰੱਖੋ</translation>
 <translation id="6000203700195075278">ਮੁੜ-ਅਨੁਸਰਣ ਕਰੋ</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />ਖੋਜ<ph name="END_LINK1" /> ਜਾਂ ਹੋਰ ਕਿਸਮ ਦੇ ਇਤਿਹਾਸ ਨੂੰ ਕਲੀਅਰ ਕਰਨ ਲਈ, <ph name="BEGIN_LINK2" />ਮੇਰੀ Google ਸਰਗਰਮੀ<ph name="END_LINK2" /> 'ਤੇ ਜਾਓ</translation>
 <translation id="6005538289190791541">ਸੁਝਾਇਆ ਗਿਆ ਪਾਸਵਰਡ</translation>
 <translation id="6032091552407840792">ਇਹ ਪਰਖ ਸਿਰਫ਼ <ph name="BEGIN_LINK" />ਕੁਝ ਖੇਤਰਾਂ<ph name="END_LINK" /> ਵਿੱਚ ਹੀ ਕਿਰਿਆਸ਼ੀਲ ਹੈ।</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />ਪ੍ਰਾਈਵੇਸੀ ਸੈਂਡਬਾਕਸ<ph name="END_LINK" /> ਦੇ ਨਾਲ, Chrome ਨਵੀਆਂ ਤਕਨਾਲੋਜੀਆਂ ਦਾ ਵਿਕਾਸ ਕਰ ਰਿਹਾ ਹੈ, ਤਾਂਕਿ ਖੁੱਲੇ ਵੈੱਬ ਨੂੰ ਸੰਭਾਲ ਕੇ ਰੱਖਣ ਦੇ ਨਾਲ-ਨਾਲ ਤੁਹਾਨੂੰ ਕ੍ਰਾਸ-ਸਾਈਟ ਟਰੈਕਿੰਗ ਤੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਿਆ ਜਾ ਸਕੇ।
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">ਨਾਮ ਬਹੁਤ ਲੰਬਾ ਹੈ</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# ਚਿੱਤਰ}one{# ਚਿੱਤਰ}other{# ਚਿੱਤਰ}}</translation>
 <translation id="6447558397796644647">ਬੁੱਕਮਾਰਕ ਲੱਭਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ। ਆਪਣੇ ਸ਼ਬਦ-ਜੋੜਾਂ ਦੀ ਜਾਂਚ ਕਰੋ ਜਾਂ ਕੋਈ ਨਵਾਂ ਬੁੱਕਮਾਰਕ ਸ਼ਾਮਲ ਕਰੋ।</translation>
+<translation id="6459045781120991510">ਸਰਵੇਖਣ</translation>
 <translation id="6461962085415701688">ਫ਼ਾਈਲ ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ</translation>
 <translation id="6464977750820128603">ਤੁਸੀਂ ਉਨ੍ਹਾਂ ਸਾਈਟਾਂ ਨੂੰ ਦੇਖ ਸਕਦੇ ਹੋ ਜਿਨ੍ਹਾਂ 'ਤੇ ਤੁਸੀਂ Chrome ਵਿੱਚ ਜਾਂਦੇ ਹੋ ਅਤੇ ਉਨ੍ਹਾਂ ਲਈ ਟਾਈਮਰ ਸੈੱਟ ਕਰ ਸਕਦੇ ਹੋ।\n\nGoogle ਉਨ੍ਹਾਂ ਸਾਈਟਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਲਈ ਤੁਸੀਂ ਟਾਈਮਰ ਸੈੱਟ ਕੀਤਾ ਹੁੰਦਾ ਹੈ ਅਤੇ ਨਾਲ ਹੀ ਇਹ ਜਾਣਕਾਰੀ ਵੀ ਪ੍ਰਾਪਤ ਕਰਦਾ ਹੈ ਕਿ ਤੁਸੀਂ ਉਨ੍ਹਾਂ ਸਾਈਟਾਂ ਨੂੰ ਕਿੰਨੀ ਦੇਰ ਤੱਕ ਦੇਖਦੇ ਰਹੇ ਹੋ। ਇਹ ਜਾਣਕਾਰੀ ਡਿਜੀਟਲ ਜੀਵਨਸ਼ੈਲੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ ਵਰਤੀ ਜਾਂਦੀ ਹੈ।</translation>
 <translation id="6475951671322991020">ਵੀਡੀਓ ਡਾਊਨਲੋਡ ਕਰੋ</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">ਵੈੱਬ 'ਤੇ ਤੁਹਾਡੇ ਅਤੇ ਹਰ ਕਿਸੇ ਲਈ ਸੁਰੱਖਿਆ ਨੂੰ ਬਿਹਤਰ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ।</translation>
 <translation id="6618554661997243500">ਤੁਹਾਡੇ ਲਈ ਪ੍ਰਮੁੱਖ ਸਾਈਟਾਂ ਅਤੇ ਕਹਾਣੀਆਂ ਨੂੰ ਦੇਖਣ ਲਈ, ਹੋਮ ਬਟਨ 'ਤੇ ਟੈਪ ਕਰੋ</translation>
 <translation id="6627583120233659107">ਫੋਲਡਰ ਸੰਪਾਦਿਤ ਕਰੋ</translation>
-<translation id="6635718764393004944">ਤੁਹਾਡਾ ਖੋਜ ਇੰਜਣ <ph name="DSE" /> ਹੈ। ਲਾਗੂ ਹੋਣ 'ਤੇ, ਆਪਣੇ ਖੋਜ ਇਤਿਹਾਸ ਨੂੰ ਮਿਟਾਉਣ ਲਈ ਉਹਨਾਂ ਦੀਆਂ ਹਿਦਾਇਤਾਂ ਦੇਖੋ।</translation>
 <translation id="663674369910034433">ਪਰਦੇਦਾਰੀ, ਸੁਰੱਖਿਆ ਅਤੇ ਡਾਟਾ ਸੰਗ੍ਰਹਿ ਨਾਲ ਸੰਬੰਧਿਤ ਹੋਰ ਸੈਟਿੰਗਾਂ ਲਈ, <ph name="BEGIN_LINK1" />ਸਮਕਾਲੀਕਰਨ<ph name="END_LINK1" /> ਅਤੇ <ph name="BEGIN_LINK2" />Google ਸੇਵਾਵਾਂ<ph name="END_LINK2" /> ਦੇਖੋ</translation>
 <translation id="6643016212128521049">ਹਟਾਓ</translation>
 <translation id="6643649862576733715">ਰੱਖਿਅਤ ਕੀਤੇ ਗਏ ਡਾਟੇ ਦੀ ਮਾਤਰਾ ਮੁਤਾਬਕ ਕ੍ਰਮ-ਬੱਧ ਕਰੋ</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">ਸਟਾਈਲਬੱਧ ਹਾਈਲਾਈਟ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">ਪੱਕਾ ਕਰੋ ਕਿ <ph name="TARGET_DEVICE_NAME" /> ਦੇ Chrome ਵਿੱਚ ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਹੋਵੇ</translation>
 <translation id="7252076891734325316">ਆਪਣਾ ਫ਼ੋਨ ਕੰਪਿਊਟਰ ਦੇ ਨੇੜੇ ਰੱਖੋ</translation>
+<translation id="727288900855680735">ਕੀ <ph name="ORIGIN" /> ਵਿੱਚ <ph name="ONE_TIME_CODE" /> ਨੂੰ ਸਪੁਰਦ ਕਰਨਾ ਹੈ?</translation>
 <translation id="7274013316676448362">ਬਲਾਕ ਕੀਤੀ ਸਾਈਟ</translation>
 <translation id="7286572596625053347">ਕੀ <ph name="LANGUAGE" /> ਬਦਲਣੀ ਹੈ?</translation>
 <translation id="7290209999329137901">ਨਾਮ ਬਦਲਣਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
index aa7a7870..842c1290 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Obliczam…</translation>
 <translation id="1383876407941801731">Szukaj</translation>
 <translation id="1384704387250346179">Przetłumacz obraz za pomocą Obiektywu Google <ph name="BEGIN_NEW" />Nowość<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stylizowane wyróżnienie</translation>
 <translation id="1386674309198842382">Aktywność <ph name="LAST_UPDATED" /> dni temu</translation>
 <translation id="1397811292916898096">Szukaj w <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Bez śledzenia”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Przycisk <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Niektóre pliki cookie oraz zapytania wpisane na pasku adresu i w polu wyszukiwania zostaną wysłane do domyślnej wyszukiwarki</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# plik}few{# pliki}many{# plików}other{# pliku}}</translation>
-<translation id="2017836877785168846">Usuwa historię i wpisy autouzupełniania w pasku adresu.</translation>
 <translation id="2021896219286479412">Elementy sterowania stroną na pełnym ekranie</translation>
 <translation id="2038563949887743358">Włącz opcję „Wersja na komputer”</translation>
 <translation id="2039379262107991683">Aby otrzymać przypomnienie, dodaj strony do listy Do przeczytania</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Szukaj z Obiektywem Google <ph name="BEGIN_NEW" />Nowość<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otwórz w nowej karcie</translation>
 <translation id="4198423547019359126">Brak dostępnych miejsc zapisu pobieranych plików</translation>
-<translation id="4206707945726604465">Aby wyczyścić inne rodzaje historii, otwórz <ph name="BEGIN_LINK1" />Moją aktywność w Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Aby uzyskać dostęp do spersonalizowanej treści proponowanej przez Google, włącz synchronizację</translation>
 <translation id="4225895483398857530">Skrót na pasku narzędzi</translation>
 <translation id="4242533952199664413">Otwórz ustawienia</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – pobieram…</translation>
 <translation id="4404568932422911380">Brak zakładek</translation>
 <translation id="4405224443901389797">Przenieś do…</translation>
+<translation id="4409271659088619928">Twoja wyszukiwarka to <ph name="DSE" />. Zapoznaj się z jej instrukcjami, jeśli chcesz usunąć historię wyszukiwania.</translation>
 <translation id="4411535500181276704">Wersja uproszczona</translation>
 <translation id="4415276339145661267">Zarządzaj kontem Google</translation>
 <translation id="4427306783828095590">Silniejsza ochrona lepiej chroni przed phishingiem i złośliwym oprogramowaniem</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Sprawdź hasła</translation>
 <translation id="6000066717592683814">Zachowaj Google</translation>
 <translation id="6000203700195075278">Ponownie dodaj do obserwowanych</translation>
-<translation id="6002623704405939939">Aby wyczyścić historię <ph name="BEGIN_LINK1" />wyszukiwania<ph name="END_LINK1" /> lub innych zdarzeń, otwórz <ph name="BEGIN_LINK2" />Moją aktywność w Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Proponowane hasło</translation>
 <translation id="6032091552407840792">Wersja próbna jest dostępna tylko w <ph name="BEGIN_LINK" />niektórych regionach<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">W ramach <ph name="BEGIN_LINK" />Piaskownicy prywatności<ph name="END_LINK" /> Chrome rozwija nowe technologie chroniące przed śledzeniem w różnych witrynach przy zachowaniu otwartego charakteru internetu.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Zwiększa bezpieczeństwo Twoje i pozostałych użytkowników internetu.</translation>
 <translation id="6618554661997243500">Aby zobaczyć najciekawsze strony i artykuły dla Ciebie, naciśnij przycisk strony głównej</translation>
 <translation id="6627583120233659107">Edytuj folder</translation>
-<translation id="6635718764393004944">Twoja wyszukiwarka to <ph name="DSE" />. Jeśli chcesz usunąć historię wyszukiwania, w razie potrzeby zajrzyj do instrukcji tej usługi.</translation>
 <translation id="663674369910034433">Więcej ustawień związanych z prywatnością, bezpieczeństwem i zbieraniem danych znajdziesz w sekcjach <ph name="BEGIN_LINK1" />Synchronizacja<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />Usługi Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Wyczyść</translation>
 <translation id="6643649862576733715">Sortuj według ilości zaoszczędzonych danych</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
index 547d2e5d..ed41ab4 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Calculando…</translation>
 <translation id="1383876407941801731">Pesquisar</translation>
 <translation id="1384704387250346179">Traduzir imagem com o Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Destaque de estilização</translation>
 <translation id="1386674309198842382">Ativado há <ph name="LAST_UPDATED" /> dias</translation>
 <translation id="1397811292916898096">Pesquisar com o <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Não rastrear"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> botão <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envia alguns cookies e pesquisas da barra de endereço e da caixa de pesquisa para seu mecanismo de pesquisa padrão.</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# arquivo}one{# arquivo}other{# arquivos}}</translation>
-<translation id="2017836877785168846">Limpa o histórico e o preenchimento automático na barra de endereço.</translation>
 <translation id="2021896219286479412">Controles de site em tela cheia</translation>
 <translation id="2038563949887743358">Ativar "Ver versão para computador"</translation>
 <translation id="2039379262107991683">Adicionar páginas à Lista de leitura para receber um lembrete</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Pesquisar com Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Abrir em uma nova guia</translation>
 <translation id="4198423547019359126">Não há locais de download disponíveis</translation>
-<translation id="4206707945726604465">Para limpar outros tipos de histórico, acesse a página <ph name="BEGIN_LINK1" />Minha atividade no Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para receber conteúdo personalizado sugerido pelo Google, ative a sincronização</translation>
 <translation id="4225895483398857530">Atalho da barra de ferramentas</translation>
 <translation id="4242533952199664413">Abrir configurações.</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" />: fazendo o download…</translation>
 <translation id="4404568932422911380">Nenhum favorito</translation>
 <translation id="4405224443901389797">Mover para…</translation>
+<translation id="4409271659088619928">Seu mecanismo de pesquisa é o <ph name="DSE" />. Veja as instruções dele para excluir o histórico de pesquisa, se aplicável.</translation>
 <translation id="4411535500181276704">Modo Lite</translation>
 <translation id="4415276339145661267">Gerenciar sua Conta do Google</translation>
 <translation id="4427306783828095590">A Proteção reforçada é mais eficiente no combate a golpes de phishing e malware</translation>
@@ -775,7 +773,6 @@
 <translation id="5979084224081478209">Verificar senhas</translation>
 <translation id="6000066717592683814">Continuar usando o Google</translation>
 <translation id="6000203700195075278">Voltar a seguir</translation>
-<translation id="6002623704405939939">Para limpar a <ph name="BEGIN_LINK1" />pesquisa<ph name="END_LINK1" /> ou outras formas de histórico, acesse a página <ph name="BEGIN_LINK2" />Minha atividade no Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Senha sugerida</translation>
 <translation id="6032091552407840792">Esse teste está disponível apenas em <ph name="BEGIN_LINK" />algumas regiões<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Com o <ph name="BEGIN_LINK" />Sandbox de privacidade<ph name="END_LINK" />, o Chrome está desenvolvendo novas tecnologias de proteção contra mecanismos de rastreamento entre sites, preservando uma Internet livre.
@@ -887,7 +884,6 @@
 <translation id="661266467055912436">Melhora a segurança para você e para todos na Web.</translation>
 <translation id="6618554661997243500">Para ver os principais sites e matérias para você, toque no botão "Início"</translation>
 <translation id="6627583120233659107">Editar pasta</translation>
-<translation id="6635718764393004944">Seu mecanismo de pesquisa é o <ph name="DSE" />. Veja as instruções específicas dele para excluir o histórico de pesquisa, se aplicável.</translation>
 <translation id="663674369910034433">Para ver mais configurações relacionadas à privacidade, segurança e coleta de dados, acesse <ph name="BEGIN_LINK2" />Serviços do Google<ph name="END_LINK2" /> e de <ph name="BEGIN_LINK1" />sincronização<ph name="END_LINK1" /></translation>
 <translation id="6643016212128521049">Limpar</translation>
 <translation id="6643649862576733715">Classificar pelo volume de dados economizados</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
index 9726097..aa78f234 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">A calcular…</translation>
 <translation id="1383876407941801731">Pesquisar</translation>
 <translation id="1384704387250346179">Traduzir imagem com Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Estilizar realce</translation>
 <translation id="1386674309198842382">Ativo há <ph name="LAST_UPDATED" /> dias</translation>
 <translation id="1397811292916898096">Pesquisar com o <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Não monitorizar"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Botão <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Envia alguns cookies e pesquisas da barra de endereço e da caixa de pesquisa para o motor de pesquisa predefinido.</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ficheiro}other{# ficheiros}}</translation>
-<translation id="2017836877785168846">Limpa o histórico e os preenchimentos automáticos da barra de endereço.</translation>
 <translation id="2021896219286479412">Controlos de site em ecrã int.</translation>
 <translation id="2038563949887743358">Ativar Pedir site para computador</translation>
 <translation id="2039379262107991683">Adicione páginas à sua Lista de leitura para receber um lembrete</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Pesquisar com Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Abrir num novo separador</translation>
 <translation id="4198423547019359126">Não existem localizações de transferência disponíveis.</translation>
-<translation id="4206707945726604465">Para limpar outras formas do histórico, visite <ph name="BEGIN_LINK1" />A minha atividade Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Para obter conteúdo personalizado sugerido pelo Google, ative a sincronização.</translation>
 <translation id="4225895483398857530">Atalho da barra de ferramentas</translation>
 <translation id="4242533952199664413">Abrir definições</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – A transferir…</translation>
 <translation id="4404568932422911380">Sem marcadores</translation>
 <translation id="4405224443901389797">Mover para…</translation>
+<translation id="4409271659088619928">O seu motor de pesquisa é o <ph name="DSE" />. Se aplicável, consulte as instruções para eliminar o histórico de pesquisas.</translation>
 <translation id="4411535500181276704">Modo Lite</translation>
 <translation id="4415276339145661267">Gerir a sua Conta Google</translation>
 <translation id="4427306783828095590">A proteção melhorada vai mais além para bloquear o phishing e o software malicioso.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Verificar palavras-passe</translation>
 <translation id="6000066717592683814">Manter o Google</translation>
 <translation id="6000203700195075278">Voltar a seguir</translation>
-<translation id="6002623704405939939">Para limpar a <ph name="BEGIN_LINK1" />pesquisa<ph name="END_LINK1" /> ou outras formas do histórico, visite <ph name="BEGIN_LINK2" />A minha atividade Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Palavra-passe sugerida</translation>
 <translation id="6032091552407840792">Esta avaliação está ativa apenas em <ph name="BEGIN_LINK" />algumas regiões<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Com a <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, o Chrome está a desenvolver novas tecnologias que protegem da monitorização entre sites, ao mesmo tempo que preservam a Web aberta.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Melhora a segurança para si e todas as pessoas na Web.</translation>
 <translation id="6618554661997243500">Para ver os sites e as notícias principais para si, toque no botão página inicial.</translation>
 <translation id="6627583120233659107">Editar pasta</translation>
-<translation id="6635718764393004944">O seu motor de pesquisa é o <ph name="DSE" />. Se aplicável, veja as respetivas instruções para eliminar o seu histórico de pesquisas.</translation>
 <translation id="663674369910034433">Para obter mais definições relacionadas com privacidade, segurança e recolha de dados, consulte <ph name="BEGIN_LINK1" />Sincronização<ph name="END_LINK1" /> e <ph name="BEGIN_LINK2" />Serviços Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Limpar</translation>
 <translation id="6643649862576733715">Ordenar por quantidade de dados poupados</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
index 78f23c2..00ce47e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Se calculează…</translation>
 <translation id="1383876407941801731">Caută</translation>
 <translation id="1384704387250346179">Tradu imaginea cu Google Lens <ph name="BEGIN_NEW" />Nou<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizează evidențierea</translation>
 <translation id="1386674309198842382">Activ acum <ph name="LAST_UPDATED" /> zile</translation>
 <translation id="1397811292916898096">Caută folosind <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Nu urmări”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> Butonul <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Trimite anumite cookie-uri și căutări din bara de adrese și din caseta de căutare în motorul de căutare prestabilit</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{Un fișier}few{# fișiere}other{# de fișiere}}</translation>
-<translation id="2017836877785168846">Șterge istoricul și completările automate din bara de adrese.</translation>
 <translation id="2021896219286479412">Comenzi site în ecran complet</translation>
 <translation id="2038563949887743358">Activează opțiunea Versiune site pentru desktop</translation>
 <translation id="2039379262107991683">Adaugă pagini în Lista de lecturi pentru a primi un memento</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Caută folosind Google Lens <ph name="BEGIN_NEW" />Nou<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Deschide în filă nouă</translation>
 <translation id="4198423547019359126">Nu există locații de descărcare disponibile</translation>
-<translation id="4206707945726604465">Pentru a șterge alte tipuri de istoric, accesează <ph name="BEGIN_LINK1" />Activitatea mea de pe Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Pentru a obține sugestii de conținut personalizat de la Google, activează sincronizarea</translation>
 <translation id="4225895483398857530">Comanda rapidă spre bara de instrumente</translation>
 <translation id="4242533952199664413">Deschide setările</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Se descarcă…</translation>
 <translation id="4404568932422911380">Niciun marcaj</translation>
 <translation id="4405224443901389797">Mută în…</translation>
+<translation id="4409271659088619928">Motorul tău de căutare este <ph name="DSE" />. Vezi instrucțiunile pentru ștergerea istoricului căutărilor, dacă este cazul.</translation>
 <translation id="4411535500181276704">Modul Lite</translation>
 <translation id="4415276339145661267">Gestionează-ți Contul Google</translation>
 <translation id="4427306783828095590">Protecția îmbunătățită face mai multe pentru blocarea phishingului și a programelor malware</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Verifică parolele</translation>
 <translation id="6000066717592683814">Păstrează Google</translation>
 <translation id="6000203700195075278">Urmărește din nou</translation>
-<translation id="6002623704405939939">Pentru a șterge istoricul <ph name="BEGIN_LINK1" />căutărilor<ph name="END_LINK1" /> sau alte tipuri de istoric, accesează <ph name="BEGIN_LINK2" />Activitatea mea de pe Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Parola sugerată</translation>
 <translation id="6032091552407840792">Această versiune de încercare este activă numai în <ph name="BEGIN_LINK" />anumite regiuni<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Cu <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome dezvoltă noi tehnologii care te apără de mecanismele de urmărire de pe mai multe site-uri, păstrând un web deschis.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Îmbunătățește securitatea pe web pentru tine și toți ceilalți.</translation>
 <translation id="6618554661997243500">Pentru a vedea principalele site-uri și subiecte pentru tine, atinge butonul ecran de pornire</translation>
 <translation id="6627583120233659107">Editați dosarul</translation>
-<translation id="6635718764393004944">Motorul tău de căutare este <ph name="DSE" />. Dacă este cazul, consultă instrucțiunile pentru a șterge istoricul căutărilor.</translation>
 <translation id="663674369910034433">Pentru mai multe setări privind confidențialitatea, securitatea și colectarea datelor, consultă <ph name="BEGIN_LINK1" />Sincronizarea<ph name="END_LINK1" /> și <ph name="BEGIN_LINK2" />Serviciile Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Șterge</translation>
 <translation id="6643649862576733715">Sortează după volumul de date salvate</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
index 7ad6e24..934d8a52 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Подсчет…</translation>
 <translation id="1383876407941801731">Поиск</translation>
 <translation id="1384704387250346179">Перевести с помощью Google Объектива <ph name="BEGIN_NEW" />Новинка<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стилизовать выделенные объекты</translation>
 <translation id="1386674309198842382">Последние действия: <ph name="LAST_UPDATED" /> дн. назад</translation>
 <translation id="1397811292916898096">Поиск в <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Запрет отслеживания</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Отправлять некоторые файлы cookie и поисковые запросы из адресной строки в поисковую систему по умолчанию</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}one{# файл}few{# файла}many{# файлов}other{# файла}}</translation>
-<translation id="2017836877785168846">Будет удалена история и варианты автозаполнения в адресной строке.</translation>
 <translation id="2021896219286479412">Настройки полноэкранного режима</translation>
 <translation id="2038563949887743358">Включить полную версию сайта</translation>
 <translation id="2039379262107991683">Добавляйте страницы в список для чтения и получайте напоминания, чтобы не забыть к ним вернуться</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Найти через Google Объектив <ph name="BEGIN_NEW" />Новинка<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Открыть в новой вкладке</translation>
 <translation id="4198423547019359126">Нет доступных мест для скачивания</translation>
-<translation id="4206707945726604465">Чтобы удалить другие данные из истории, перейдите на страницу <ph name="BEGIN_LINK1" />Мои действия в Google<ph name="END_LINK1" />.</translation>
 <translation id="4209895695669353772">Чтобы мы могли рекомендовать вам интересный контент, включите синхронизацию.</translation>
 <translation id="4225895483398857530">Кнопка на панели инструментов</translation>
 <translation id="4242533952199664413">Открыть настройки</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – скачивание…</translation>
 <translation id="4404568932422911380">Нет закладок</translation>
 <translation id="4405224443901389797">Переместить в…</translation>
+<translation id="4409271659088619928">Ваша поисковая система – <ph name="DSE" />. Изучите инструкции по удалению истории поиска в справочных материалах указанной поисковой системы.</translation>
 <translation id="4411535500181276704">Упрощенный режим</translation>
 <translation id="4415276339145661267">Перейти в настройки аккаунта Google</translation>
 <translation id="4427306783828095590">В режиме "Улучшенная защита" фишинговые атаки и вредоносное ПО блокируются ещё эффективнее.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Проверить пароли</translation>
 <translation id="6000066717592683814">Использовать Google</translation>
 <translation id="6000203700195075278">Снова подписаться</translation>
-<translation id="6002623704405939939">Чтобы удалить <ph name="BEGIN_LINK1" />поисковые запросы<ph name="END_LINK1" /> или другие данные о вашей активности, перейдите на страницу <ph name="BEGIN_LINK2" />Мои действия в Google<ph name="END_LINK2" />.</translation>
 <translation id="6005538289190791541">Предложенный пароль</translation>
 <translation id="6032091552407840792">Эта пробная функция доступна только в <ph name="BEGIN_LINK" />некоторых регионах<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> – инициатива Chrome по разработке новых технологий, которые позволят защитить пользователей от межсайтового отслеживания и при этом сохранить интернет открытым.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Делает Интернет безопаснее для вас и других пользователей.</translation>
 <translation id="6618554661997243500">Нажмите эту кнопку, чтобы увидеть интересные вам сайты и новости</translation>
 <translation id="6627583120233659107">Изменить папку</translation>
-<translation id="6635718764393004944">Ваша поисковая система – <ph name="DSE" />. Если возможно, следуйте инструкциям по удалению истории поиска для этой системы.</translation>
 <translation id="663674369910034433">Другие настройки, связанные с конфиденциальностью, безопасностью и сбором данных, можно найти в разделах <ph name="BEGIN_LINK1" />Синхронизация<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />Сервисы Google<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Удалить</translation>
 <translation id="6643649862576733715">Сортировать по объему сохраненного трафика</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
index ec33331c..7c6d138 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">ගණනය කරමින්...</translation>
 <translation id="1383876407941801731">සොයන්න</translation>
 <translation id="1384704387250346179">Google Lens සමග රූපය පරිවර්තනය ක. <ph name="BEGIN_NEW" />නව<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">උද්දීපනය ශෛලිගත කරන්න</translation>
 <translation id="1386674309198842382">දින <ph name="LAST_UPDATED" /> කට පෙර ක්‍රියාත්මකයි</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> සමඟ සොයන්න</translation>
 <translation id="1406000523432664303">“හඹා නොයන්න”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> බොත්තම</translation>
 <translation id="2000419248597011803">ලිපින තීරුවේ සහ සෙවීම් පෙට්ටියේ ඇතැම් කුකී සහ සෙවීම් ඔබගේ පෙරනිමි සෙවීම් එන්ජිමට යවයි</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ගොනුවක්}one{ගොනු #ක්}other{ගොනු #ක්}}</translation>
-<translation id="2017836877785168846">ලිපින තීරුව තුළ ඉතිහාසය හා ස්වයං සම්පූර්ණ කිරීම් හිස් කරයි.</translation>
 <translation id="2021896219286479412">පූර්ණ තිර අඩවි පාලන</translation>
 <translation id="2038563949887743358">ඩෙස්ක්ටොප් අඩවිය ඉල්ලීම ක්‍රියාත්මක කරන්න</translation>
 <translation id="2039379262107991683">සිහිකැඳවීමක් ලබා ගැනීම සඳහා ඔබගේ කියවීම් ලැයිස්තුවට පිටු එක් කරන්න</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">භාෂා</translation>
 <translation id="4183868528246477015">Google Lens සමඟ සොයන්න <ph name="BEGIN_NEW" />නව<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">නව ටැබයක විවෘත කරන්න</translation>
+<translation id="4196597275619698563">කාඩ්පත තනන්න</translation>
 <translation id="4198423547019359126">බාගැනීම් ස්ථාන කිසිවක් නැත</translation>
-<translation id="4206707945726604465">වෙනත් ආකාරයේ ඉතිහාසය හිස් කිරීමට, <ph name="BEGIN_LINK1" />මගේ Google ක්‍රියාකාරකම්<ph name="END_LINK1" /> වෙත පිවිසෙන්න</translation>
 <translation id="4209895695669353772">Google විසින් යෝජනා කරන ලද පෞද්ගලීකරණය කළ අන්තර්ගතය ලබා ගැනීමට, සමමුහුර්තය ක්‍රියාත්මක කරන්න</translation>
 <translation id="4225895483398857530">මෙවලම් තීරු කෙටිමඟ</translation>
 <translation id="4242533952199664413">සැකසීම් විවෘත කරන්න</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - බාගනිමින්…</translation>
 <translation id="4404568932422911380">පිටුසන් නැත</translation>
 <translation id="4405224443901389797">වෙත ගෙන යන්න…</translation>
+<translation id="4409271659088619928">ඔබගේ සෙවීම් යන්ත්‍රය වන්නේ <ph name="DSE" />. අදාළ වන්නේ නම්, ඔබගේ සෙවීම් ඉතිහාසය මැකීම සඳහා ඔවුන්ගේ උපදෙස් බලන්න.</translation>
 <translation id="4411535500181276704">සැහැල්ලු ප්‍රකාරය</translation>
 <translation id="4415276339145661267">ඔබේ Google ගිණුම කළමනාකරණය</translation>
 <translation id="4427306783828095590">තතුබෑම් සහ අනිෂ්ට මෘදුකාංග අවහිර කිරීමට වැඩි දියුණු කළ ආරක්ෂාව වැඩි දෙයක් කරයි</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">මුරපද පරීක්‍ෂා කරන්න</translation>
 <translation id="6000066717592683814">Keep Google</translation>
 <translation id="6000203700195075278">නැවත අනුගමනය කරන්න</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />සෙවීම්<ph name="END_LINK1" /> හෝ වෙනත් ආකාරවල ඉතිහාසය හිස් කිරීමට, <ph name="BEGIN_LINK2" />මගේ Google ක්‍රියාකාරකම්<ph name="END_LINK2" /> වෙත පිවිසෙන්න</translation>
 <translation id="6005538289190791541">යෝජිත මුරපදය</translation>
 <translation id="6032091552407840792">මෙම අත්හදා බැලීම <ph name="BEGIN_LINK" />සමහර කලාප<ph name="END_LINK" /> තුළ පමණක් සක්‍රියයි.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />පෞද්ගලිකත්ව සෑන්ඩ්බොක්ස්<ph name="END_LINK" /> සමග, Chrome විවෘත වෙබය ආරක්ෂා කරන අතරම හරස් අඩවි හඹා යාමෙන් ඔබව ආරක්ෂා කිරීම සඳහා නව තාක්ෂණ සංවර්ධනය කරයි.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">ඔබේ සහ වෙබය මත සියලු දෙනාගේම ආරක්‍ෂාව වැඩිදියුණු කරයි.</translation>
 <translation id="6618554661997243500">ඔබ සඳහා ඉහළම අඩවි සහ කථාන්දර බැලීමට, මුල් පිටු බොත්තම තට්ටු කරන්න</translation>
 <translation id="6627583120233659107">ෆෝල්ඩරය සංස්කරණය කරන්න</translation>
-<translation id="6635718764393004944">ඔබගේ සෙවීම් යන්ත්‍රය වන්නේ <ph name="DSE" />. අදාළ නම්, ඔබගේ සෙවීම් ඉතිහාසය මැකීමට ඔවුන්ගේ උපදෙස් බලන්න.</translation>
 <translation id="663674369910034433">රහස්‍යතාව, ආරක්ෂාව, සහ දත්ත රැස් කිරීමට අදාළ තවත් සැකසීම් සඳහා, <ph name="BEGIN_LINK1" />සමමුහුර්තකරණය<ph name="END_LINK1" /> සහ <ph name="BEGIN_LINK2" />Google සේවා<ph name="END_LINK2" /> බලන්න</translation>
 <translation id="6643016212128521049">මකන්න</translation>
 <translation id="6643649862576733715">සුරැකි දත්ත ප්‍රමාණයේ එකතුව අනුව අනුපිළිවෙලට සකසන්න</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">සෙවීම් සහ URL ලිපින ස්වයංව සම්පූර්ණ කරන්න</translation>
 <translation id="7707922173985738739">ජංගම දත්ත භාවිත කරන්න</translation>
 <translation id="7725024127233776428">ඔබ පිටුසන් කරන පිටු මෙහි දිස් වෙති</translation>
+<translation id="7731260005404856143"><ph name="BEGIN_LINK1" />ක්‍රියාකාරකම්වල වෙනත් ආකාර<ph name="END_LINK1" /> ඔබ පුරන විට ඔබගේ Google ගිණුමේ සුරැකිය හැකිය. ඔබට ඒවා ඕනෑම අවස්ථාවක මැකිය හැකිය.</translation>
 <translation id="7757787379047923882"><ph name="DEVICE_NAME" /> වෙතින් බෙදා ගත් පාඨය</translation>
 <translation id="7761849928583394409">දිනය සහ වේලාව තෝරන්න</translation>
 <translation id="7762668264895820836">SD පත <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">ඔබේ නොබැඳි ගොනු බලන්න</translation>
 <translation id="8856607253650333758">විස්තර ලබා ගන්න</translation>
 <translation id="8873817150012960745">ආරම්භ කිරීමට මෙහි තට්ටු කරන්න</translation>
+<translation id="8881973373982641723">සෙවීම් කොටුවේ ඇතුළුව, ඉතිහාසය හිස් කරයි</translation>
 <translation id="889338405075704026">Chrome සැකසීම් වෙත යන්න</translation>
 <translation id="8898822736010347272">වෙබය මත නව තර්ජන සොයා ගෙන සියලු දෙනා ආරක්ෂා කිරීමට උදවු කිරීමට Google වෙත ඔබ පැමිණෙන සමහර පිටුවල URL, සීමිත පද්ධති තොරතුරු, සහ යම් පිටු අන්තර්ගතය යවයි.</translation>
 <translation id="8909135823018751308">බෙදාගන්න…</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">ඇමතුම් කළ නොහැක</translation>
 <translation id="9212845824145208577">පහළට යාමට නොහැකිය. පිටුවේ තවදුරටත් පහළින් ආරම්භ කිරීමට උත්සාහ කරන්න.</translation>
 <translation id="9219103736887031265">රූප</translation>
+<translation id="923957533152125119"><ph name="BEGIN_LINK1" />සෙවීම් ඉතිහාසය<ph name="END_LINK1" /> සහ <ph name="BEGIN_LINK2" />ක්‍රියාකාරකම්වල වෙනත් ආකාර<ph name="END_LINK2" /> ඔබ පුරන විට ඔබගේ Google ගිණුමේ සුරැකිය හැකිය. ඔබට ඒවා ඕනෑම අවස්ථාවක මැකිය හැකිය.</translation>
 <translation id="926205370408745186">ඩිජිටල් සුවතාව වෙතින් ඔබේ Chrome ක්‍රියාකාරකම් ඉවත් කරන්න</translation>
 <translation id="927968626442779827">Google Chrome හි සැහැල්ලු ප්‍රකාරය භාවිත කරන්න</translation>
 <translation id="932327136139879170">මුල් පිටුව</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
index 63f451e5..c6cd2de 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Vypočítava sa…</translation>
 <translation id="1383876407941801731">Vyhľadávanie</translation>
 <translation id="1384704387250346179">Preklad obrázka funkciou Google Lens <ph name="BEGIN_NEW" />Novinka<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Štylizovať zvýraznenie</translation>
 <translation id="1386674309198842382">Aktívne pred <ph name="LAST_UPDATED" /> dňami</translation>
 <translation id="1397811292916898096">Hľadať pomocou vyhľadávača <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Nesledovať</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> tlačidlo <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Odošle niektoré súbory cookie a vyhľadávania z panela s adresou a vyhľadávacieho poľa do vášho predvoleného vyhľadávača</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# súbor}few{# súbory}many{# Files}other{# súborov}}</translation>
-<translation id="2017836877785168846">Vymaže históriu a automaticky doplňované výrazy v paneli s adresou.</translation>
 <translation id="2021896219286479412">Ovládanie webu na celú obrazovku</translation>
 <translation id="2038563949887743358">Zapnutie žiadosti o verziu stránok pre počítače</translation>
 <translation id="2039379262107991683">Pridajte si stránky do čitateľského zoznamu a dostávajte pripomenutia</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Hľadať cez Google Lens <ph name="BEGIN_NEW" />Novinka<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otvoriť na novej karte</translation>
 <translation id="4198423547019359126">Nie sú k dispozícii žiadne umiestnenia stiahnutých súborov</translation>
-<translation id="4206707945726604465">Ak chcete vymazať ostatné formy histórie, navštívite <ph name="BEGIN_LINK1" />Moju aktivitu na Googli<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Ak chcete získavať prispôsobený obsah navrhnutý Googlom, zapnite synchronizáciu</translation>
 <translation id="4225895483398857530">Skratka panela s nástrojmi</translation>
 <translation id="4242533952199664413">Otvoriť nastavenia</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – sťahuje sa…</translation>
 <translation id="4404568932422911380">Žiadne záložky</translation>
 <translation id="4405224443901389797">Presunúť do…</translation>
+<translation id="4409271659088619928">Používate vyhľadávač <ph name="DSE" />. Prečítajte si jeho pokyny, ako odstrániť históriu vyhľadávania (ak je to možné).</translation>
 <translation id="4411535500181276704">Zjednodušený režim</translation>
 <translation id="4415276339145661267">Spravovať účet Google</translation>
 <translation id="4427306783828095590">Rozšírená ochrana efektívnejšie blokuje phishing aj malvér</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Skontrolovať heslá</translation>
 <translation id="6000066717592683814">Ponechať Google</translation>
 <translation id="6000203700195075278">Znova sledovať</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Vyhľadávanie<ph name="END_LINK1" /> alebo iné formy histórie môžete vymazať na stránke <ph name="BEGIN_LINK2" />Moja aktivita na Googli<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Navrhované heslo</translation>
 <translation id="6032091552407840792">Skúšobné obdobie je aktívne iba v <ph name="BEGIN_LINK" />niektorých oblastiach<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Pomocou technológií <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> vyvíja Chrome nové technológie, ktoré vás ochránia pred mechanizmami sledovania na rôznych weboch a súčasne zachovajú internet otvorený.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Zvyšuje zabezpečenie na internete pre vás aj ostatných.</translation>
 <translation id="6618554661997243500">Ak si chcete zobraziť najobľúbenejšie weby a odporúčané správy, klepnite na tlačidlo plochy</translation>
 <translation id="6627583120233659107">Upraviť priečinok</translation>
-<translation id="6635718764393004944">Používate vyhľadávač <ph name="DSE" />. V náležitých prípadoch si v ňom prečítajte pokyny na odstránenie histórie vyhľadávania.</translation>
 <translation id="663674369910034433">Ďalšie nastavenia týkajúce sa ochrany súkromia, zabezpečenia a zhromažďovania údajov nájdete v sekciách <ph name="BEGIN_LINK1" />Synchronizácia<ph name="END_LINK1" /> a <ph name="BEGIN_LINK2" />služby Googlu<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Vymazať</translation>
 <translation id="6643649862576733715">Zoradiť podľa množstva ušetrených dát</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
index e014f8e..e851931 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Računanje …</translation>
 <translation id="1383876407941801731">Išči</translation>
 <translation id="1384704387250346179">Prevedi sliko z Googlom Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Slogovno oblikuj označitev</translation>
 <translation id="1386674309198842382">Aktivna pred toliko dnevi: <ph name="LAST_UPDATED" /></translation>
 <translation id="1397811292916898096">Iskanje z iskalnikom <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">»Ne sledi«</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Gumb <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Pošilja nekatere piškotke in iskanja iz naslovne vrstice ter iskalnega polja privzetemu iskalniku</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# datoteka}one{# datoteka}two{# datoteki}few{# datoteke}other{# datotek}}</translation>
-<translation id="2017836877785168846">Izbriše zgodovino in samodokončanja v naslovni vrstici.</translation>
 <translation id="2021896219286479412">Kontrol. za mesto v celo. načinu</translation>
 <translation id="2038563949887743358">Vklop možnosti »Zahteva za namizno spletno mesto«</translation>
 <translation id="2039379262107991683">Dodajte strani na bralni seznam, če želite prejeti opomnik.</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Iskanje z Google Lens <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Odpri v novem zavihku</translation>
 <translation id="4198423547019359126">Ni razpoložljivih mest za prenos</translation>
-<translation id="4206707945726604465">Če želite izbrisati druge oblike zgodovine, obiščite <ph name="BEGIN_LINK1" />mojo dejavnost v Googlu<ph name="END_LINK1" />.</translation>
 <translation id="4209895695669353772">Če želite prejemati prilagojeno vsebino, ki jo predlaga Google, vklopite sinhronizacijo</translation>
 <translation id="4225895483398857530">Bližnjica do orodne vrstice</translation>
 <translation id="4242533952199664413">Odpri nastavitve</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – prenašanje …</translation>
 <translation id="4404568932422911380">Ni zaznamkov</translation>
 <translation id="4405224443901389797">Premakni v …</translation>
+<translation id="4409271659088619928">Vaš iskalnik je <ph name="DSE" />. Oglejte si navodila iskalnika za brisanje zgodovine iskanja, če je na voljo.</translation>
 <translation id="4411535500181276704">Lahki način</translation>
 <translation id="4415276339145661267">Upravljanje računa Google</translation>
 <translation id="4427306783828095590">Izboljšana zaščita učinkoviteje blokira lažno predstavljanje in zlonamerno programsko opremo.</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Preveri gesla</translation>
 <translation id="6000066717592683814">Ohrani Google</translation>
 <translation id="6000203700195075278">Znova spremljaj</translation>
-<translation id="6002623704405939939">Če želite počistiti <ph name="BEGIN_LINK1" />iskanje<ph name="END_LINK1" /> ali druge oblike zgodovine, obiščite <ph name="BEGIN_LINK2" />Mojo dejavnost v Googlu<ph name="END_LINK2" />.</translation>
 <translation id="6005538289190791541">Predlagano geslo</translation>
 <translation id="6032091552407840792">Ta preizkus je aktiven samo v <ph name="BEGIN_LINK" />nekaterih regijah<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Pri Chromu v okviru pobude <ph name="BEGIN_LINK" />Zasebni peskovnik<ph name="END_LINK" /> razvijamo nove tehnologije, ki vas varujejo pred sledenjem na več spletnih mestih, hkrati pa skrbijo za ohranitev odprtosti spleta.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Izboljšuje varnost za vas in vse druge v spletu.</translation>
 <translation id="6618554661997243500">Če si želite ogledati najbolj priljubljena spletna mesta in članke, se dotaknite gumba za domačo stran</translation>
 <translation id="6627583120233659107">Uredi mapo</translation>
-<translation id="6635718764393004944">Vaš iskalnik je <ph name="DSE" />. Če je mogoče, si oglejte navodila iskalnika glede izbrisa zgodovine iskanja.</translation>
 <translation id="663674369910034433">Če vas zanima več nastavitev, povezanih z zasebnostjo, varnostjo in zbiranjem podatkov, si oglejte razdelka <ph name="BEGIN_LINK1" />Sinhronizacija<ph name="END_LINK1" /> in <ph name="BEGIN_LINK2" />Googlove storitve<ph name="END_LINK2" />.</translation>
 <translation id="6643016212128521049">Izbriši</translation>
 <translation id="6643649862576733715">Razvrsti glede na prihranek pri količini prenesenih podatkov</translation>
@@ -970,7 +966,7 @@
 <translation id="7242755609445462077">Stilizirana oznaka <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Poskrbite, da ima naprava <ph name="TARGET_DEVICE_NAME" /> vklopljeno sinhronizacijo v Chromu</translation>
 <translation id="7252076891734325316">Postavite telefon blizu računalnika</translation>
-<translation id="727288900855680735">Želite, da se <ph name="ONE_TIME_CODE" /> pošlje na <ph name="ORIGIN" />?</translation>
+<translation id="727288900855680735">Želite, da se <ph name="ONE_TIME_CODE" /> pošlje <ph name="ORIGIN" />?</translation>
 <translation id="7274013316676448362">Blokirano spletno mesto</translation>
 <translation id="7286572596625053347">Želite spremeniti jezik <ph name="LANGUAGE" />?</translation>
 <translation id="7290209999329137901">Preimenovanje ni na voljo</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
index 83b6a8c9..5e61191 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Po llogarit...</translation>
 <translation id="1383876407941801731">Kërko</translation>
 <translation id="1384704387250346179">Përkthe imazhin me "Lenten e Google" <ph name="BEGIN_NEW" />E re<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizo theksimin</translation>
 <translation id="1386674309198842382">Aktiv <ph name="LAST_UPDATED" /> ditë më parë</translation>
 <translation id="1397811292916898096">Kërko me <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Mos gjurmo"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> buton</translation>
 <translation id="2000419248597011803">Dërgon disa kuki dhe kërkime nga shiriti i adresës dhe kutia e kërkimit te motori yt i parazgjedhur i kërkimit</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# skedar}other{# skedarë}}</translation>
-<translation id="2017836877785168846">Pastron historikun dhe plotësimet automatike në shiritin e adresës.</translation>
 <translation id="2021896219286479412">Kontrollet e sajtit në ekranin e plotë</translation>
 <translation id="2038563949887743358">Aktivizo "Kërko sajtin për desktop"</translation>
 <translation id="2039379262107991683">Shto faqe në listën tënde të leximit për të marrë një alarm rikujtues</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Kërko me "Lenten e Google" <ph name="BEGIN_NEW" />E re<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Hape në një skedë të re</translation>
 <translation id="4198423547019359126">Nuk ka vendndodhje shkarkimi</translation>
-<translation id="4206707945726604465">Për të pastruar format e tjera të historikut, vizito <ph name="BEGIN_LINK1" />Aktivitetin tim në Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Për të marrë përmbajtje të personalizuar të sugjeruar nga Google, aktivizo sinkronizimin</translation>
 <translation id="4225895483398857530">Shkurtorja e shiritit të veglave</translation>
 <translation id="4242533952199664413">Hap cilësimet</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Po shkarkohet…</translation>
 <translation id="4404568932422911380">Nuk ka faqeshënues</translation>
 <translation id="4405224443901389797">Zhvendos te…</translation>
+<translation id="4409271659088619928">Motori yt i kërkimit është <ph name="DSE" />. Shiko udhëzimet e motorit të kërkimit për fshirjen e historikut të kërkimit, nëse është e vlefshme.</translation>
 <translation id="4411535500181276704">Modaliteti i lehtë</translation>
 <translation id="4415276339145661267">Menaxho "Llogarinë tënde të Google"</translation>
 <translation id="4427306783828095590">Mbrojtja e përmirësuar bën edhe më shumë për bllokimin e mashtrimeve dhe softuerëve keqdashës</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Kontrollo fjalëkalimet</translation>
 <translation id="6000066717592683814">Mbaj Google</translation>
 <translation id="6000203700195075278">Ndiqe përsëri</translation>
-<translation id="6002623704405939939">Për të pastruar <ph name="BEGIN_LINK1" />kërkimin<ph name="END_LINK1" /> ose forma të tjera të historikut, vizito <ph name="BEGIN_LINK2" />Aktivitetin tim në Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Fjalëkalimi i sugjeruar</translation>
 <translation id="6032091552407840792">Kjo provë është aktive vetëm në <ph name="BEGIN_LINK" />disa rajone<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Me <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, Chrome po zhvillon teknologji të reja për të të mbrojtur nga gjurmimi nëpër sajtet e uebit, ndërkohë që vazhdon të ruajë uebin e hapur.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">Emri është tepër i gjatë</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# imazh}other{# Imazhe}}</translation>
 <translation id="6447558397796644647">Ai faqeshënues nuk mund të gjendet. Kontrollo nëse e ke shkruar saktë ose shto një faqeshënues të ri</translation>
+<translation id="6459045781120991510">Anketat</translation>
 <translation id="6461962085415701688">Skedari nuk mund të hapet</translation>
 <translation id="6464977750820128603">Mund të shikosh sajtet që viziton në Chrome dhe të caktosh kohëmatës për to.\n\nGoogle merr informacion rreth sajteve për të cilat cakton kohëmatës dhe për sa kohë i viziton ato. Ky informacion përdoret për të përmirësuar "Mirëqenien dixhitale".</translation>
 <translation id="6475951671322991020">Shkarko videon</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">Përmirëson sigurinë për ty dhe këdo në ueb.</translation>
 <translation id="6618554661997243500">Për të parë sajtet kryesore dhe historitë për ty, trokit te butoni "Kreu"</translation>
 <translation id="6627583120233659107">Modifiko dosjen</translation>
-<translation id="6635718764393004944">Motori yt i kërkimit është <ph name="DSE" />. Nëse zbatohet, shiko udhëzimet për të fshirë historikun tënd të kërkimit.</translation>
 <translation id="663674369910034433">Për cilësime të mëtejshme në lidhje me privatësinë, sigurinë dhe mbledhjen e të dhënave, shih <ph name="BEGIN_LINK1" />Shinkronizimi <ph name="END_LINK1" /> dhe <ph name="BEGIN_LINK2" />Shërbimet e Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Pastro</translation>
 <translation id="6643649862576733715">Rendit sipas sasisë së të dhënave të ruajtura</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">Theksimi i stilizuar (<ph name="CURRENT_DATE" />)</translation>
 <translation id="7248069434667874558">Sigurohu që <ph name="TARGET_DEVICE_NAME" /> të ketë të aktivizuar sinkronizimin në Chrome</translation>
 <translation id="7252076891734325316">Vendose telefonin tënd pranë kompjuterit</translation>
+<translation id="727288900855680735">Të dërgohet <ph name="ONE_TIME_CODE" /> te <ph name="ORIGIN" />?</translation>
 <translation id="7274013316676448362">Sajt i bllokuar</translation>
 <translation id="7286572596625053347">Të ndryshohet <ph name="LANGUAGE" />?</translation>
 <translation id="7290209999329137901">Riemërtimi nuk ofrohet</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb
index f930b18..c65b4b9 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Računa se…</translation>
 <translation id="1383876407941801731">Pretraži</translation>
 <translation id="1384704387250346179">Prev. sl. uz Google obj. <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilizuj istaknutu stavku</translation>
 <translation id="1386674309198842382">Poslednja aktivnost: pre <ph name="LAST_UPDATED" /> dan/a</translation>
 <translation id="1397811292916898096">Pretražite pomoću: <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Ne prati“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Dugme <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Podrazumevanom pretraživaču šalje neke kolačiće i pretrage iz trake za adresu i okvira za pretragu</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# datoteka}one{# datoteka}few{# datoteke}other{# datoteka}}</translation>
-<translation id="2017836877785168846">Briše istoriju i automatska dovršavanja u traci za adresu.</translation>
 <translation id="2021896219286479412">Kontrole sajta na celom ekranu</translation>
 <translation id="2038563949887743358">Uključi zahtevanje verzije sajta za računare</translation>
 <translation id="2039379262107991683">Dodajte stranice na Listu za čitanje da biste dobili podsetnik</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Traži uz Google objektiv <ph name="BEGIN_NEW" />Novo<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Otvori na novoj kartici</translation>
 <translation id="4198423547019359126">Nema dostupnih lokacija za preuzimanja</translation>
-<translation id="4206707945726604465">Da biste obrisali druge oblike istorije, posetite <ph name="BEGIN_LINK1" />Moje aktivnosti na Google-u<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Da biste dobijali personalizovani sadržaj koji predlaže Google, uključite sinhronizaciju</translation>
 <translation id="4225895483398857530">Prečica za traku s alatkama</translation>
 <translation id="4242533952199664413">Otvori podešavanja</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Preuzima se…</translation>
 <translation id="4404568932422911380">Nema obeleživača</translation>
 <translation id="4405224443901389797">Premesti u...</translation>
+<translation id="4409271659088619928">Vaš pretraživač je <ph name="DSE" />. Pogledajte uputstva tog pretraživača za brisanje istorije pretrage ako je to primenjivo.</translation>
 <translation id="4411535500181276704">Lite režim</translation>
 <translation id="4415276339145661267">Upravljajte Google nalogom</translation>
 <translation id="4427306783828095590">Poboljšana zaštita nudi više mogućnosti za blokiranje „pecanja“ i malvera</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Proveri lozinke</translation>
 <translation id="6000066717592683814">Zadrži Google</translation>
 <translation id="6000203700195075278">Ponovo prati</translation>
-<translation id="6002623704405939939">Da biste obrisali <ph name="BEGIN_LINK1" />pretragu<ph name="END_LINK1" /> ili druge oblike istorije, posetite <ph name="BEGIN_LINK2" />Moje aktivnosti na Google-u<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Predložena lozinka</translation>
 <translation id="6032091552407840792">Ova proba je aktivna samo u <ph name="BEGIN_LINK" />nekim regionima<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Sa <ph name="BEGIN_LINK" />Zaštićenim okruženjem privatnosti<ph name="END_LINK" /> Chrome razvija nove tehnologije koje će vas predostrožno zaštititi od praćenja na više sajtova uz očuvanje otvorenog veba.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Poboljšava bezbednost za vas i druge na vebu.</translation>
 <translation id="6618554661997243500">Da biste videli sajtove koje najčešće posećujete i vesti koje najčešće čitate, dodirnite dugme Početak</translation>
 <translation id="6627583120233659107">Izmeni direktorijum</translation>
-<translation id="6635718764393004944">Vaš pretraživač je <ph name="DSE" />. Ako je to primenjivo, pročitajte njegovo uputstvo za brisanje istorije pretrage.</translation>
 <translation id="663674369910034433">Više podešavanja u vezi sa privatnošću, bezbednošću i prikupljanjem podataka potražite u odeljku <ph name="BEGIN_LINK1" />Sinhronizacija<ph name="END_LINK1" /> i <ph name="BEGIN_LINK2" />Google usluge<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Obriši</translation>
 <translation id="6643649862576733715">Sortiraj po količini ušteđenih podataka</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
index a234e92..c119529 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Рачуна се…</translation>
 <translation id="1383876407941801731">Претражи</translation>
 <translation id="1384704387250346179">Прев. сл. уз Google обј. <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стилизуј истакнуту ставку</translation>
 <translation id="1386674309198842382">Последња активност: пре <ph name="LAST_UPDATED" /> дан/а</translation>
 <translation id="1397811292916898096">Претражите помоћу: <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">„Не прати“</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Дугме <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Подразумеваном претраживачу шаље неке колачиће и претраге из траке за адресу и оквира за претрагу</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# датотека}one{# датотека}few{# датотеке}other{# датотека}}</translation>
-<translation id="2017836877785168846">Брише историју и аутоматска довршавања у траци за адресу.</translation>
 <translation id="2021896219286479412">Контроле сајта на целом екрану</translation>
 <translation id="2038563949887743358">Укључи захтевање верзије сајта за рачунаре</translation>
 <translation id="2039379262107991683">Додајте странице на Листу за читање да бисте добили подсетник</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Тражи уз Google објектив <ph name="BEGIN_NEW" />Ново<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Отвори на новој картици</translation>
 <translation id="4198423547019359126">Нема доступних локација за преузимања</translation>
-<translation id="4206707945726604465">Да бисте обрисали друге облике историје, посетите <ph name="BEGIN_LINK1" />Моје активности на Google-у<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Да бисте добијали персонализовани садржај који предлаже Google, укључите синхронизацију</translation>
 <translation id="4225895483398857530">Пречица за траку с алаткама</translation>
 <translation id="4242533952199664413">Отвори подешавања</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Преузима се…</translation>
 <translation id="4404568932422911380">Нема обележивача</translation>
 <translation id="4405224443901389797">Премести у...</translation>
+<translation id="4409271659088619928">Ваш претраживач је <ph name="DSE" />. Погледајте упутства тог претраживача за брисање историје претраге ако је то примењиво.</translation>
 <translation id="4411535500181276704">Lite режим</translation>
 <translation id="4415276339145661267">Управљајте Google налогом</translation>
 <translation id="4427306783828095590">Побољшана заштита нуди више могућности за блокирање „пецања“ и малвера</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Провери лозинке</translation>
 <translation id="6000066717592683814">Задржи Google</translation>
 <translation id="6000203700195075278">Поново прати</translation>
-<translation id="6002623704405939939">Да бисте обрисали <ph name="BEGIN_LINK1" />претрагу<ph name="END_LINK1" /> или друге облике историје, посетите <ph name="BEGIN_LINK2" />Моје активности на Google-у<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Предложена лозинка</translation>
 <translation id="6032091552407840792">Ова проба је активна само у <ph name="BEGIN_LINK" />неким регионима<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Са <ph name="BEGIN_LINK" />Заштићеним окружењем приватности<ph name="END_LINK" /> Chrome развија нове технологије које ће вас предострожно заштитити од праћења на више сајтова уз очување отвореног веба.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Побољшава безбедност за вас и друге на вебу.</translation>
 <translation id="6618554661997243500">Да бисте видели сајтове које најчешће посећујете и вести које најчешће читате, додирните дугме Почетак</translation>
 <translation id="6627583120233659107">Измени директоријум</translation>
-<translation id="6635718764393004944">Ваш претраживач је <ph name="DSE" />. Ако је то примењиво, прочитајте његово упутство за брисање историје претраге.</translation>
 <translation id="663674369910034433">Више подешавања у вези са приватношћу, безбедношћу и прикупљањем података потражите у одељку <ph name="BEGIN_LINK1" />Синхронизација<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />Google услуге<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Обриши</translation>
 <translation id="6643649862576733715">Сортирај по количини уштеђених података</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
index 6e55ec8..610b226f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Beräknar …</translation>
 <translation id="1383876407941801731">Sök</translation>
 <translation id="1384704387250346179">Översätta bild med Lens <ph name="BEGIN_NEW" />Nyhet<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Stilisera markering</translation>
 <translation id="1386674309198842382">Aktiv för <ph name="LAST_UPDATED" /> dagar sedan</translation>
 <translation id="1397811292916898096">Sök med <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">Do Not Track</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> – knapp för <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Skickar vissa cookies och sökningar från adressfältet och sökrutan till standardsökmotorn</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# fil}other{# filer}}</translation>
-<translation id="2017836877785168846">Rensar historik och autoslutföranden i adressfältet.</translation>
 <translation id="2021896219286479412">Helskärmskontroller på webbsidan</translation>
 <translation id="2038563949887743358">Aktivera begäran av skrivbordsversion</translation>
 <translation id="2039379262107991683">Lägg till sidor i läslistan om du vill få en påminnelse</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Sök med Google Lens <ph name="BEGIN_NEW" />Nyhet<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Öppna i ny flik</translation>
 <translation id="4198423547019359126">Det fins inga tillgängliga nedladdningsplatser</translation>
-<translation id="4206707945726604465">Du kan rensa annan historik på <ph name="BEGIN_LINK1" />Min aktivitet på Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Aktivera synkronisering om du vill få förslag på anpassat innehåll från Google</translation>
 <translation id="4225895483398857530">Genväg i verktygsfältet</translation>
 <translation id="4242533952199664413">Öppna Inställningar</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Laddar ned …</translation>
 <translation id="4404568932422911380">Inga bokmärken</translation>
 <translation id="4405224443901389797">Flytta till …</translation>
+<translation id="4409271659088619928">Du använder <ph name="DSE" /> som sökmotor. Läs den sökmotorns anvisningar för att radera sökhistoriken om tillämpligt.</translation>
 <translation id="4411535500181276704">Begränsat läge</translation>
 <translation id="4415276339145661267">Hantera Google-kontot</translation>
 <translation id="4427306783828095590">Förbättrat skydd är bättre på att blockera nätfiske och skadlig programvara</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Kontrollera lösenord</translation>
 <translation id="6000066717592683814">Behåll Google</translation>
 <translation id="6000203700195075278">Följ på nytt</translation>
-<translation id="6002623704405939939">Du kan rensa <ph name="BEGIN_LINK1" />sökhistoriken<ph name="END_LINK1" /> och annan historik på <ph name="BEGIN_LINK2" />Min aktivitet på Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Föreslaget lösenord</translation>
 <translation id="6032091552407840792">Provperioden är endast aktiv i <ph name="BEGIN_LINK" />vissa regioner<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Med <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> utvecklar vi ny teknik för Chrome som skyddar dig från att bli spårad från webbplats till webbplats samtidigt som vi värnar den öppna webben.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Förbättrar säkerheten för dig och alla andra på webben.</translation>
 <translation id="6618554661997243500">Tryck på hemknappen om du vill se dina mest besökta webbplatser och artiklar för dig</translation>
 <translation id="6627583120233659107">Redigera mapp</translation>
-<translation id="6635718764393004944">Din sökmotor är <ph name="DSE" />. Följ eventuella anvisningar från sökmotorn för att radera din sökhistorik.</translation>
 <translation id="663674369910034433">Fler inställningar som rör integritet, säkerhet och datainsamling finns under <ph name="BEGIN_LINK1" />Synk<ph name="END_LINK1" /> och <ph name="BEGIN_LINK2" />Googles tjänster<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Rensa</translation>
 <translation id="6643649862576733715">Sortera efter databesparing</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
index de71f64..f673e2c 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Inakokotoa...</translation>
 <translation id="1383876407941801731">Tafuta</translation>
 <translation id="1384704387250346179">Tafsiri picha ukitumia Lenzi ya Google <ph name="BEGIN_NEW" />Mpya<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Weka mitindo kwenye maandishi yaliyoangaziwa</translation>
 <translation id="1386674309198842382">Ilitumika siku <ph name="LAST_UPDATED" /> zilizopita</translation>
 <translation id="1397811292916898096">Tafuta kwa <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Usifuatilie”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Kitufe cha <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Hutuma baadhi ya vidakuzi na utafutaji kutoka kwenye sehemu ya anwani na kisanduku cha kutafutia kwenye mtambo wako chaguomsingi wa kutafuta</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{Faili #}other{Faili #}}</translation>
-<translation id="2017836877785168846">Hufuta historia na ujazaji kiotomatiki katika sehemu ya anwani.</translation>
 <translation id="2021896219286479412">Vidhibiti vya tovuti vya skrini nzima</translation>
 <translation id="2038563949887743358">Washa Omba Tovuti ya Eneo-kazi</translation>
 <translation id="2039379262107991683">Weka kurasa kwenye Orodha yako ya Kusoma ili upate kikumbusho</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Tafuta na Lenzi ya Google <ph name="BEGIN_NEW" />Mpya<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Fungua katika kichupo kipya</translation>
 <translation id="4198423547019359126">Hakuna maeneno ya upakuaji</translation>
-<translation id="4206707945726604465">Ili uweze kufuta historia ya aina nyingine, tembelea <ph name="BEGIN_LINK1" />Shughuli Zangu Kwenye Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Washa kipengele cha usawazishaji ili Google ikupendekezee maudhui yanayokufaa</translation>
 <translation id="4225895483398857530">Njia ya mkato ya upau wa vidhibiti</translation>
 <translation id="4242533952199664413">Fungua mipangilio</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Inapakuliwa…</translation>
 <translation id="4404568932422911380">Hakuna alamisho</translation>
 <translation id="4405224443901389797">Hamishia kwenye…</translation>
+<translation id="4409271659088619928">Mtambo wako wa kutafuta ni <ph name="DSE" />. Angalia maagizo ya mtambo huo wa kutafuta, ikiwa yapo, kuhusu jinsi ya kufuta historia ya mambo uliyotafuta.</translation>
 <translation id="4411535500181276704">Hali nyepesi</translation>
 <translation id="4415276339145661267">Dhibiti Akaunti yako ya Google</translation>
 <translation id="4427306783828095590">Kipengele cha ulinzi wa hali ya juu hufanya mengi zaidi ili kuzuia programu hasidi na wizi wa data binafsi</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Kagua manenosiri</translation>
 <translation id="6000066717592683814">Endelea Kutumia Google</translation>
 <translation id="6000203700195075278">Fuatilia tena</translation>
-<translation id="6002623704405939939">Ili ufute historia ya <ph name="BEGIN_LINK1" />utafutaji<ph name="END_LINK1" /> au historia nyingine, tembelea <ph name="BEGIN_LINK2" />Shughuli Zangu Kwenye Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Nenosiri linalopendekezwa</translation>
 <translation id="6032091552407840792">Jaribio hili linatumika katika <ph name="BEGIN_LINK" />baadhi ya maeneo<ph name="END_LINK" /> pekee.</translation>
 <translation id="6033245666633565791">Kwa kutumia <ph name="BEGIN_LINK" />Utaratibu wa kuwekea vikwazo vya faragha<ph name="END_LINK" />, Chrome inakuza teknolojia mpya zitakazokulinda dhidi ya ufuatiliaji wa data kwenye tovuti nyingi huku zikidumisha wavuti huria.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Huboresha usalama wako na wa kila mtu kwenye wavuti.</translation>
 <translation id="6618554661997243500">Ili uone tovuti na taarifa maarufu unazopendekezewa, gusa kitufe cha Ukurasa wa mwanzo</translation>
 <translation id="6627583120233659107">Badilisha folda</translation>
-<translation id="6635718764393004944">Mtambo wako wa kutafuta ni <ph name="DSE" />. Ikiwa yapo, angalia maagizo yake ya kufuta historia ya mambo uliyoyafuta.</translation>
 <translation id="663674369910034433">Ili upate mipangilio zaidi inayohusiana na faragha, usalama na ukusanyaji wa data, angalia <ph name="BEGIN_LINK1" />Usawazishaji<ph name="END_LINK1" /> na <ph name="BEGIN_LINK2" />huduma za Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Futa</translation>
 <translation id="6643649862576733715">Panga kulingana na kiasi cha data kilichookolewa</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
index 0a992b8..bf2ca51 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">கணக்கிடுகிறது…</translation>
 <translation id="1383876407941801731">Search</translation>
 <translation id="1384704387250346179">படத்திலுள்ளதை Google Lens மூலம் மொழிபெயர் <ph name="BEGIN_NEW" />புதிது<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ஹைலைட்டை மெருகூட்டு</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> நாட்களுக்கு முன் பயன்படுத்தியுள்ளார்</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> மூலம் தேடுக</translation>
 <translation id="1406000523432664303">'கண்காணிக்க வேண்டாம்'</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> பட்டன்</translation>
 <translation id="2000419248597011803">முகவரிப் பட்டியிலிருந்தும், தேடல் பெட்டியிலிருந்தும் சில குக்கீகளையும் தேடல்களையும் உங்கள் இயல்புத் தேடல் இன்ஜினுக்கு அனுப்பும்</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# கோப்பு}other{# கோப்புகள்}}</translation>
-<translation id="2017836877785168846">முகவரிப் பட்டியில் வரலாற்றையும் தானே நிரப்புதல்களையும் அழிக்கும்.</translation>
 <translation id="2021896219286479412">முழுத் திரை தளக் கட்டுப்பாடுகள்</translation>
 <translation id="2038563949887743358">டெஸ்க்டாப் தளத்திற்கான கோரிக்கையை இயக்கு</translation>
 <translation id="2039379262107991683">நினைவூட்டலைப் பெற உங்கள் வாசிப்புப் பட்டியலில் பக்கங்களைச் சேருங்கள்</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens மூலம் தேடுக <ph name="BEGIN_NEW" />புதிது<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">புதிய தாவலில் திற</translation>
 <translation id="4198423547019359126">பதிவிறக்க இருப்பிடம் எதுவும் இல்லை</translation>
-<translation id="4206707945726604465">பிற தேடல் விவரங்களை அழிக்க <ph name="BEGIN_LINK1" />எனது Google செயல்பாடு<ph name="END_LINK1" /> பக்கத்திற்குச் செல்லவும்</translation>
 <translation id="4209895695669353772">Google பரிந்துரைக்கும் பிரத்யேக உள்ளடக்கத்தைப் பெற, ஒத்திசைவை இயக்கவும்</translation>
 <translation id="4225895483398857530">கருவிப்பட்டி ஷார்ட்கட்</translation>
 <translation id="4242533952199664413">அமைப்புகளைத் திற</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - மொழியைப் பதிவிறக்குகிறது…</translation>
 <translation id="4404568932422911380">புக்மார்க்குகள் இல்லை</translation>
 <translation id="4405224443901389797">இங்கு நகர்த்து…</translation>
+<translation id="4409271659088619928"><ph name="DSE" /> என்பதே உங்கள் தேடல் இன்ஜின். அதன் வழிமுறைகளைப் பார்த்து தேடல் விவரங்களை நீக்குங்கள் (நீக்க அனுமதி இருந்தால்).</translation>
 <translation id="4411535500181276704">லைட் பயன்முறை</translation>
 <translation id="4415276339145661267">Google கணக்கை நிர்வகி</translation>
 <translation id="4427306783828095590">ஃபிஷிங்கையும் மால்வேரையும் தடுக்க மேம்பட்ட பாதுகாப்பு உதவுகிறது</translation>
@@ -676,7 +674,7 @@
 <translation id="5424588387303617268"><ph name="GIGABYTES" /> ஜி.பை. உள்ளது</translation>
 <translation id="543338862236136125">கடவுச்சொல்லை மாற்று</translation>
 <translation id="5433691172869980887">பயனர்பெயர் நகலெடுக்கப்பட்டது</translation>
-<translation id="543509235395288790"><ph name="COUNT" /> கோப்புகளைப் பதிவிறக்குகிறது (<ph name="MEGABYTES" />).</translation>
+<translation id="543509235395288790"><ph name="COUNT" /> ஃபைல்களைப் பதிவிறக்குகிறது (<ph name="MEGABYTES" />).</translation>
 <translation id="5441466871879044658">இலக்கு மொழி</translation>
 <translation id="5441522332038954058">முகவரிப் பட்டிக்குச் செல்லும்</translation>
 <translation id="544776284582297024">ஒரே நேரத்தில் தாவல்களைத் திறந்து வெவ்வேறு பக்கங்களைப் பார்வையிட, 'திறக்கப்பட்டுள்ள தாவல்கள்' பட்டனைத் தட்டவும்</translation>
@@ -691,7 +689,7 @@
 <translation id="5500777121964041360">உங்கள் நாட்டில் இல்லாமல் இருக்கக்கூடும்</translation>
 <translation id="5512137114520586844">இந்தக் கணக்கு <ph name="PARENT_NAME" /> ஆல் நிர்வகிக்கப்படுகிறது.</translation>
 <translation id="5514904542973294328">இந்தச் சாதனத்தின் நிர்வாகி முடக்கியுள்ளார்</translation>
-<translation id="5515439363601853141">கடவுச்சொல்லைப் பார்க்க, திறக்கவும்</translation>
+<translation id="5515439363601853141">கடவுச்சொல்லைப் பார்க்க, அன்லாக் செய்யவும்</translation>
 <translation id="5517095782334947753"><ph name="FROM_ACCOUNT" /> இன் புக்மார்க்குகள், வரலாறு, கடவுச்சொற்கள் மற்றும் பிற அமைப்புகள் உள்ளன.</translation>
 <translation id="5524843473235508879">திசைதிருப்புவது தடுக்கப்பட்டது.</translation>
 <translation id="5534640966246046842">தளம் நகலெடுக்கப்பட்டது</translation>
@@ -726,7 +724,7 @@
 <translation id="5726692708398506830">பக்கத்திலுள்ள அனைத்தையும் பெரிதாக்கும்</translation>
 <translation id="5733983706093266635">QR குறியீட்டை உருவாக்க முடியவில்லை. URL <ph name="CHARACTER_LIMIT" /> எழுத்துகளுக்கு அதிகமாக உள்ளது.</translation>
 <translation id="5748802427693696783">இயல்பான தாவல்களுக்கு மாற்றப்பட்டது</translation>
-<translation id="5749068826913805084">கோப்புகளைப் பதிவிறக்க Chromeக்கு சேமிப்பிட அணுகல் தேவை.</translation>
+<translation id="5749068826913805084">ஃபைல்களைப் பதிவிறக்க Chromeக்கு சேமிப்பிட அணுகல் தேவை.</translation>
 <translation id="5749237766298580851">முடக்கப்பட்டுள்ளது <ph name="SEPARATOR" /> பரிந்துரைக்கப்படவில்லை</translation>
 <translation id="5754350196967618083">Discoverரைப் புதுப்பிக்க முடியவில்லை</translation>
 <translation id="5763382633136178763">மறைநிலைத் தாவல்கள்</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">கடவுச்சொற்களைச் சோதித்துப் பார்க்கவும்</translation>
 <translation id="6000066717592683814">Googleஐ இயல்பு இன்ஜினாக வைத்திரு</translation>
 <translation id="6000203700195075278">மீண்டும் பின்தொடர்க</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />இதுவரை தேடியவற்றையும்<ph name="END_LINK1" /> பிற தரவையும் அழிக்க, <ph name="BEGIN_LINK2" />எனது Google செயல்பாடு<ph name="END_LINK2" /> பக்கத்திற்குச் செல்லவும்</translation>
 <translation id="6005538289190791541">பரிந்துரைக்கப்படும் கடவுச்சொல்</translation>
 <translation id="6032091552407840792">இந்தச் சோதனை <ph name="BEGIN_LINK" />சில பிராந்தியங்களில்<ph name="END_LINK" /> மட்டுமே செயலில் இருக்கும்.</translation>
 <translation id="6033245666633565791">பொது இணையத்தைப் பாதுகாக்கும் அதே வேளையில் தளங்களுக்கு இடையே மாறும்போது கண்காணிக்கப்படுவதில் இருந்து உங்களைப் பாதுகாக்க, <ph name="BEGIN_LINK" />தனியுரிமை சாண்ட்பாக்ஸ்<ph name="END_LINK" /> மூலம் புதிய தொழில்நுட்பங்களை Chrome உருவாக்குகிறது.
@@ -808,7 +805,7 @@
 <translation id="6192907950379606605">பட விளக்கங்களைப் பெறு</translation>
 <translation id="6210748933810148297"><ph name="EMAIL" /> இல்லையா?</translation>
 <translation id="6211386937064921208">இந்தப் பக்கத்தின் மாதிரிக்காட்சி</translation>
-<translation id="6221633008163990886">உங்கள் கடவுச்சொற்களை ஏற்ற, திறக்கவும்</translation>
+<translation id="6221633008163990886">உங்கள் கடவுச்சொற்களை ஏற்ற, அன்லாக் செய்யவும்</translation>
 <translation id="6232535412751077445">‘கண்காணிக்க வேண்டாம்’ என்பதை இயக்குவதால் உங்கள் உலாவல் டிராஃபிக்குடன் கோரிக்கை ஒன்று இணைக்கப்படும். கோரிக்கைக்கு இணையதளம் எவ்வாறு பதிலளிக்கிறது என்பதையும் கோரிக்கையானது எவ்வாறு புரிந்து கொள்ளப்படுகிறது என்பதையும் பொருத்து எந்தவொரு விளைவும் இருக்கும்.
 
 எடுத்துக்காட்டாக, சில இணையதளங்கள் நீங்கள் பார்வையிட்ட பிற இணையதளங்களின் அடிப்படையில் இல்லாத விளம்பரங்களைக் காட்டுவதன் மூலம் இந்தக் கோரிக்கைக்குப் பதிலளிக்கலாம். பல இணையதளங்கள் நீங்கள் உலாவிய தரவைத் தொடர்ந்து சேகரித்துப் பயன்படுத்தும் - எடுத்துக்காட்டாக பாதுகாப்பை மேம்படுத்த, உள்ளடக்கம், விளம்பரங்கள் மற்றும் பரிந்துரைகளை வழங்க, அறிக்கைப் புள்ளிவிவரங்களை உருவாக்க நீங்கள் உலாவிய தரவைப் பயன்படுத்தலாம்.</translation>
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">பெயர் மிக நீளமாக உள்ளது</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# படம்}other{# படங்கள்}}</translation>
 <translation id="6447558397796644647">அந்த புக்மார்க்கைக் கண்டறிய இயலவில்லை. எழுத்துவரிசையைச் சரிபார்க்கவும் அல்லது புதிய புக்மார்க்கைச் சேர்க்கவும்.</translation>
+<translation id="6459045781120991510">கருத்துக்கணிப்புகள்</translation>
 <translation id="6461962085415701688">கோப்பைத் திறக்க முடியாது</translation>
 <translation id="6464977750820128603">Chromeமில் பார்த்தத் தளங்களைக் காணலாம், அவற்றுக்கு டைமர்களையும் அமைக்கலாம்.\n\nடைமர்களை அமைத்தத் தளங்களைப் பற்றிய விவரங்களையும் அவற்றில் செலவழித்த நேரத்தையும் Google சேகரிக்கும். இந்தத் தகவல் டிஜிட்டல் வெல்பீயிங்கை மேம்படுத்தப் பயன்படுத்தப்படும்.</translation>
 <translation id="6475951671322991020">வீடியோவைப் பதிவிறக்கு</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">வலையில் உள்ள உங்களுக்கும் அனைவருக்கும் பாதுகாப்பை மேம்படுத்தும்.</translation>
 <translation id="6618554661997243500">நீங்கள் அடிக்கடி பயன்படுத்தும் தளங்களையும் செய்திகளையும் பார்க்க, முகப்புப் பட்டனைத் தட்டவும்</translation>
 <translation id="6627583120233659107">கோப்புறையைத் திருத்து</translation>
-<translation id="6635718764393004944"><ph name="DSE" /> என்பதே உங்கள் தேடல் இன்ஜின். இதுவரை தேடியவற்றை நீக்க, அதன் வழிமுறைகளைப் (இருந்தால்) பார்க்கவும்.</translation>
 <translation id="663674369910034433">தனியுரிமை, பாதுகாப்பு, தரவுச் சேகரிப்பு ஆகியவற்றுடன் தொடர்புடைய கூடுதல் அமைப்புகளுக்கு, <ph name="BEGIN_LINK1" />ஒத்திசைவு<ph name="END_LINK1" /> &amp; <ph name="BEGIN_LINK2" />Google சேவைகள்<ph name="END_LINK2" />என்பதைப் பார்க்கவும்</translation>
 <translation id="6643016212128521049">அழி</translation>
 <translation id="6643649862576733715">சேமித்த தரவு அளவின்படி வரிசைப்படுத்தும்</translation>
@@ -926,7 +923,7 @@
 <translation id="6869056123412990582">கம்ப்யூட்டரில்</translation>
 <translation id="6882836635272038266">நிலையான பாதுகாப்பு பயன்முறையானது ஆபத்து என அறியப்படும் இணையதளங்கள், பதிவிறக்கங்கள், நீட்டிப்புகள் ஆகியவற்றுக்கு எதிரானது.</translation>
 <translation id="688738109438487280">ஏற்கனவே உள்ள தரவை <ph name="TO_ACCOUNT" /> இல் சேர்.</translation>
-<translation id="6891726759199484455">உங்கள் கடவுச்சொல்லை நகலெடுக்க, திறக்கவும்</translation>
+<translation id="6891726759199484455">உங்கள் கடவுச்சொல்லை நகலெடுக்க, அன்லாக் செய்யவும்</translation>
 <translation id="6896758677409633944">நகலெடு</translation>
 <translation id="6900532703269623216">மேம்பட்ட பாதுகாப்பு</translation>
 <translation id="6903907808598579934">ஒத்திசைவை இயக்கு</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">மெருகூட்டப்பட்ட ஹைலைட் <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Chromeமில் <ph name="TARGET_DEVICE_NAME" /> சாதன ஒத்திசைவு ஆன் செய்யப்பட்டுள்ளதை உறுதி செய்யவும்</translation>
 <translation id="7252076891734325316">கம்யூட்டருக்கு அருகில் உங்கள் மொபைலை வைக்கவும்</translation>
+<translation id="727288900855680735"><ph name="ONE_TIME_CODE" /> என்ற குறியீட்டை <ph name="ORIGIN" /> தளத்தில் சமர்ப்பிக்கவா?</translation>
 <translation id="7274013316676448362">தடுக்கப்பட்ட தளம்</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> மொழியை மாற்றவா?</translation>
 <translation id="7290209999329137901">இதை மறுபெயரிட இயலாது</translation>
@@ -1081,7 +1079,7 @@
 <translation id="789763218334337857">Chromeமை எப்படிப் பயன்படுத்துவது?</translation>
 <translation id="7903184275147100332">இதற்கு ஒரு நிமிடம் ஆகக்கூடும்</translation>
 <translation id="7919123827536834358">தானாக மொழிபெயர்க்கப்படும் மொழிகள்</translation>
-<translation id="7925590027513907933">{FILE_COUNT,plural, =1{கோப்பைப் பதிவிறக்குகிறது.}other{# கோப்புகளைப் பதிவிறக்குகிறது.}}</translation>
+<translation id="7925590027513907933">{FILE_COUNT,plural, =1{கோப்பைப் பதிவிறக்குகிறது.}other{# ஃபைல்களைப் பதிவிறக்குகிறது.}}</translation>
 <translation id="7926975587469166629">கார்டின் புனைப்பெயர்</translation>
 <translation id="7929962904089429003">மெனுவைத் திறக்கும்</translation>
 <translation id="7930998711684428189">தரவு மீறலினால் கடவுச்சொற்கள் வெளியாகியிருந்தால் அதுகுறித்து எச்சரிக்கும்.</translation>
@@ -1235,7 +1233,7 @@
 <translation id="8840953339110955557">ஆன்லைன் பதிப்பிலிருந்து இந்தப் பக்கம் வேறுபடலாம்.</translation>
 <translation id="8849001918648564819">மறைக்கப்பட்டுள்ளது</translation>
 <translation id="8853345339104747198"><ph name="TAB_TITLE" />, தாவல்</translation>
-<translation id="8854223127042600341">உங்கள் ஆஃப்லைன் கோப்புகளைப் பாருங்கள்</translation>
+<translation id="8854223127042600341">உங்கள் ஆஃப்லைன் ஃபைல்களைப் பாருங்கள்</translation>
 <translation id="8856607253650333758">விளக்கங்களைப் பெறுக</translation>
 <translation id="8873817150012960745">தேடுவதற்கு இங்கே தட்டவும்</translation>
 <translation id="889338405075704026">Chrome அமைப்புகளுக்குச் செல்</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
index e7876c1..4da38cd2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">గణిస్తోంది...</translation>
 <translation id="1383876407941801731">సెర్చ్</translation>
 <translation id="1384704387250346179"><ph name="BEGIN_NEW" />కొత్తది<ph name="END_NEW" /> Google Lensతో ఇమేజ్‌ను అనువదించండి</translation>
-<translation id="1385855801883526502">హైలైట్ శైలిని మార్చండి</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> రోజుల క్రితం యాక్టివ్‌గా ఉంది</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" />తో వెతకండి</translation>
 <translation id="1406000523432664303">“ట్రాక్ చేయవద్దు”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> బటన్</translation>
 <translation id="2000419248597011803">అడ్రస్ బార్, సెర్చ్ బాక్స్‌లలో చేసే సెర్చ్‌లు, కొన్ని కుక్కీలను మీరు ఆటోమేటిక్ ఆప్షన్‌గా సెట్ చేసిన సెర్చ్ ఇంజిన్‌కు పంపుతుంది</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ఫైల్}other{# ఫైల్‌లు}}</translation>
-<translation id="2017836877785168846">చిరునామా బార్‌లో చరిత్రను మరియు స్వీయ పూరణలను క్లియర్ చేస్తుంది.</translation>
 <translation id="2021896219286479412">పూర్తి స్క్రీన్ సైట్ నియంత్రణలు</translation>
 <translation id="2038563949887743358">డెస్క్‌టాప్ సైట్ అభ్యర్థనను ఆన్ చేయండి</translation>
 <translation id="2039379262107991683">రిమైండర్ పొందటానికి పేజీలను మీ చదవాల్సిన లిస్ట్‌కు జోడించండి</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google లెన్స్‌తో శోధన <ph name="BEGIN_NEW" />కొత్తది<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">కొత్త ట్యాబ్‌లో తెరువు</translation>
 <translation id="4198423547019359126">డౌన్‌లోడ్ స్థానాలు అందుబాటులో లేవు</translation>
-<translation id="4206707945726604465">ఇతర రకాల హిస్టరీని క్లియర్ చేయడానికి, <ph name="BEGIN_LINK1" />నా Google యాక్టివిటీ<ph name="END_LINK1" />ని సందర్శించండి</translation>
 <translation id="4209895695669353772">Google ద్వారా మీ అభిరుచికి తగిన కంటెంట్‌ను సిఫార్సుల రూపంలో పొందాలనుకుంటే, సమకాలీకరణ ఎంపికను ఆన్ చేయాలి</translation>
 <translation id="4225895483398857530">Toolbar షార్ట్‌కట్</translation>
 <translation id="4242533952199664413">సెట్టింగ్‌లను తెరువు</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - డౌన్‌లోడ్ చేస్తోంది…</translation>
 <translation id="4404568932422911380">బుక్‌మార్క్‌లు లేవు</translation>
 <translation id="4405224443901389797">ఇక్కడికి తరలించండి…</translation>
+<translation id="4409271659088619928">మీ సెర్చ్ ఇంజిన్ <ph name="DSE" />. వర్తిస్తే, మీ సెర్చ్ హిస్టరీని తొలగించడానికి దాని సూచనలను చూడండి.</translation>
 <translation id="4411535500181276704">లైట్ మోడ్</translation>
 <translation id="4415276339145661267">మీ Google ఖాతాను మేనేజ్ చేయండి</translation>
 <translation id="4427306783828095590">ఫిషింగ్, అలాగే మాల్‌వేర్‌ను బ్లాక్ చేయడానికి మెరుగుపరచిన రక్షణ మరింత చేయగలదు</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">పాస్‌వర్డ్‌లను చెక్ చేయండి</translation>
 <translation id="6000066717592683814">Googleని ఉంచు</translation>
 <translation id="6000203700195075278">మళ్లీ ఫాలో చేయి</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />సెర్చ్<ph name="END_LINK1" />ను, లేదా ఇతర రకాల హిస్టరీని క్లియర్ చేయడానికి, <ph name="BEGIN_LINK2" />నా Google యాక్టివిటీ<ph name="END_LINK2" />ని సందర్శించండి</translation>
 <translation id="6005538289190791541">సూచించబడిన పాస్‌వర్డ్‌</translation>
 <translation id="6032091552407840792">ఈ ట్రయల్ <ph name="BEGIN_LINK" />కొన్ని ప్రాంతాలలో<ph name="END_LINK" /> మాత్రమే యాక్టివ్‌గా ఉంది.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />గోప్యతా పరిరక్షణ టెక్నాలజీల సెట్<ph name="END_LINK" />‌తో, Chrome మిమ్మల్ని వెబ్‌ను సంరక్షించేటప్పుడు క్రాస్-సైట్ ట్రాకింగ్ నుండి రక్షించడానికి కొత్త టెక్నాలజీలను డెవలప్ చేస్తుంది.
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">పేరు చాలా పొడువు ఉంది</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# ఫోటో}other{# ఫోటోలు}}</translation>
 <translation id="6447558397796644647">ఆ బుక్‌మార్క్‌ను కనుగొనడం సాధ్యం కాలేదు. మీ స్పెల్లింగ్‌ను తనిఖీ చేయండి లేదా కొత్త బుక్‌మార్క్‌ను జోడించండి.</translation>
+<translation id="6459045781120991510">సర్వేలు</translation>
 <translation id="6461962085415701688">ఫైల్‌ను తెరవడం సాధ్యపడదు</translation>
 <translation id="6464977750820128603">Chromeలో మీరు ఏయే సైట్‌లను సందర్శించారో చూడవచ్చు, వాటికి టైమర్‌లను సెట్ చేయవచ్చు.\n\nమీరు టైమర్‌లను సెట్ చేసిన సైట్‌ల సమాచారం, మీరు ఎంతసేపు వాటిని సందర్శించారనే వివరాలు Googleకు అందించబడతాయి. డిజిటల్ సంక్షేమాన్ని మరింత మెరుగుపరచడానికి ఈ సమాచారం ఉపయోగించబడుతుంది.</translation>
 <translation id="6475951671322991020">వీడియోను డౌన్‌లోడ్ చేయి</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">మీకు, వెబ్‌లోని ప్రతి ఒక్కరికీ సెక్యూరిటీని మెరుగుపరుస్తుంది.</translation>
 <translation id="6618554661997243500">మీ కోసం టాప్ సైట్‌లు, అలాగే కథనాలను చూడటానికి హోమ్ బటన్‌ను ట్యాప్ చేయండి</translation>
 <translation id="6627583120233659107">ఫోల్డర్‌ను సవరించు</translation>
-<translation id="6635718764393004944">మీ సెర్చ్ ఇంజిన్ <ph name="DSE" />. వర్తించినట్లయితే, మీ సెర్చ్ హిస్టరీని తొలగించడానికి దాని సూచనలను చూడండి.</translation>
 <translation id="663674369910034433">గోప్యత, భద్రత అలాగే డేటా సేకరణకు సంబంధించిన మరిన్ని సెట్టింగ్‌ల కోసం, <ph name="BEGIN_LINK1" />సింక్<ph name="END_LINK1" />, <ph name="BEGIN_LINK2" />Google సర్వీస్‌ల<ph name="END_LINK2" />ను చూడండి</translation>
 <translation id="6643016212128521049">క్లియర్ చేయి</translation>
 <translation id="6643649862576733715">సేవ్ చేసిన డేటా పరిమాణం ద్వారా క్రమీకరించు</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">శైలీకరించిన హైలైట్ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">Chromeలో <ph name="TARGET_DEVICE_NAME" />కు సింక్ ఆన్ చేయబడి ఉందని నిర్ధారించుకోండి</translation>
 <translation id="7252076891734325316">మీ ఫోన్‌ను కంప్యూటర్‌కు దగ్గరగా ఉంచండి</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" />‌కు <ph name="ONE_TIME_CODE" />‌ను సమర్పించాలా?</translation>
 <translation id="7274013316676448362">బ్లాక్ చేసిన సైట్</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> మార్చాలా?</translation>
 <translation id="7290209999329137901">పేరు మార్పు అందుబాటులో లేదు</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
index ada8011..70a886e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">กำลังประมวลผล…</translation>
 <translation id="1383876407941801731">ค้นหา</translation>
 <translation id="1384704387250346179">แปลรูปภาพด้วย Google Lens <ph name="BEGIN_NEW" />ใหม่<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ไฮไลต์สไตไลซ์</translation>
 <translation id="1386674309198842382">ใช้งานเมื่อ <ph name="LAST_UPDATED" /> วันที่ผ่านมา</translation>
 <translation id="1397811292916898096">ค้นหาด้วย <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“ไม่ติดตาม”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> ปุ่ม<ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">ส่งคุกกี้และการค้นหาบางรายการจากแถบที่อยู่และช่องค้นหาไปยังเครื่องมือค้นหาเริ่มต้น</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ไฟล์}other{# ไฟล์}}</translation>
-<translation id="2017836877785168846">ล้างประวัติการเข้าชมและการเติมข้อความอัตโนมัติในแถบที่อยู่เว็บ</translation>
 <translation id="2021896219286479412">ส่วนควบคุมเว็บไซต์แบบเต็มหน้าจอ</translation>
 <translation id="2038563949887743358">เปิดการขอเว็บไซต์เดสก์ท็อป</translation>
 <translation id="2039379262107991683">เพิ่มหน้าเว็บในเรื่องรออ่านเพื่อรับการช่วยเตือน</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">ค้นหาด้วย Google Lens <ph name="BEGIN_NEW" />ใหม่<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">เปิดในแท็บใหม่</translation>
 <translation id="4198423547019359126">ไม่มีตำแหน่งการดาวน์โหลดที่ใช้ได้</translation>
-<translation id="4206707945726604465">หากต้องการล้างประวัติการเข้าชมรูปแบบอื่นๆ ให้ไปที่<ph name="BEGIN_LINK1" />กิจกรรมของฉันใน Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">เปิดการซิงค์เพื่อรับคำแนะนำเนื้อหาที่ปรับเปลี่ยนในแบบของคุณจาก Google</translation>
 <translation id="4225895483398857530">ทางลัดแถบเครื่องมือ</translation>
 <translation id="4242533952199664413">เปิดการตั้งค่า</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - กำลังดาวน์โหลด…</translation>
 <translation id="4404568932422911380">ไม่มีบุ๊กมาร์ก</translation>
 <translation id="4405224443901389797">ย้ายไปที่…</translation>
+<translation id="4409271659088619928">เครื่องมือค้นหาของคุณคือ <ph name="DSE" /> ดูวิธีลบประวัติการค้นหา (หากมี) ของเครื่องมือค้นหาที่คุณใช้</translation>
 <translation id="4411535500181276704">โหมด Lite</translation>
 <translation id="4415276339145661267">จัดการบัญชี Google</translation>
 <translation id="4427306783828095590">การปกป้องที่ปรับปรุงแล้วทำได้มากกว่าบล็อกฟิชชิงและมัลแวร์</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">ตรวจสอบรหัสผ่าน</translation>
 <translation id="6000066717592683814">ใช้ Google ต่อ</translation>
 <translation id="6000203700195075278">ติดตามอีกครั้ง</translation>
-<translation id="6002623704405939939">หากต้องการล้าง<ph name="BEGIN_LINK1" />การค้นหา<ph name="END_LINK1" />หรือประวัติการเข้าชมในรูปแบบอื่นๆ ให้ไปที่<ph name="BEGIN_LINK2" />กิจกรรมของฉันใน Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">รหัสผ่านที่แนะนำ</translation>
 <translation id="6032091552407840792">การทดลองใช้นี้ใช้งานได้ใน<ph name="BEGIN_LINK" />บางภูมิภาค<ph name="END_LINK" />เท่านั้น</translation>
 <translation id="6033245666633565791">การใช้ <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> ช่วยให้ Chrome พัฒนาเทคโนโลยีใหม่ๆ เพื่อปกป้องคุณจากการติดตามข้ามเว็บไซต์ในขณะที่ยังคงรักษาความเปิดกว้างของเว็บไว้
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">ปรับปรุงความปลอดภัยให้คุณและทุกคนที่ใช้อินเทอร์เน็ต</translation>
 <translation id="6618554661997243500">หากต้องการดูเว็บไซต์ยอดนิยมและเรื่องราวสำหรับคุณ ให้แตะปุ่มหน้าแรก</translation>
 <translation id="6627583120233659107">แก้ไขโฟลเดอร์</translation>
-<translation id="6635718764393004944">เครื่องมือค้นหาของคุณคือ <ph name="DSE" /> ดูวิธีการลบประวัติการค้นหา (หากมี)</translation>
 <translation id="663674369910034433">ดูการตั้งค่าเพิ่มเติมเกี่ยวกับความเป็นส่วนตัว ความปลอดภัย และการรวบรวมข้อมูลได้ที่<ph name="BEGIN_LINK1" />การซิงค์<ph name="END_LINK1" />และ<ph name="BEGIN_LINK2" />บริการต่างๆ ของ Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">ล้าง</translation>
 <translation id="6643649862576733715">จัดเรียงตามปริมาณเน็ตมือถือที่ประหยัดได้</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
index d1f612bf..6f7d76e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Hesaplanıyor…</translation>
 <translation id="1383876407941801731">Ara</translation>
 <translation id="1384704387250346179">Resmi Google Lens ile çevir <ph name="BEGIN_NEW" />Yeni<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Vurgulamayı stilize et</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> gün önce etkindi</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> ile ara</translation>
 <translation id="1406000523432664303">“Do Not Track”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> düğmesi</translation>
 <translation id="2000419248597011803">Adres çubuğundan ve arama kutusundan bazı çerezleri ve aramaları varsayılan arama motorunuza gönderir</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Dosya}other{# Dosya}}</translation>
-<translation id="2017836877785168846">Geçmişi ve adres çubuğundaki otomatik tamamlama bilgilerini temizler.</translation>
 <translation id="2021896219286479412">Tam ekran site kontrolleri</translation>
 <translation id="2038563949887743358">Masaüstü sitesi iste işlevini etkinleştir</translation>
 <translation id="2039379262107991683">Hatırlatıcı almak için sayfaları Okuma Listenize ekleyin</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Google Lens ile ara <ph name="BEGIN_NEW" />Yeni<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Yeni sekmede aç</translation>
 <translation id="4198423547019359126">Kullanılabilir indirme yeri yok</translation>
-<translation id="4206707945726604465">Diğer türdeki geçmiş verilerini temizlemek için <ph name="BEGIN_LINK1" />Google Etkinliğim<ph name="END_LINK1" />'i ziyaret edin</translation>
 <translation id="4209895695669353772">Google tarafından önerilen kişiselleştirilmiş içeriği almak için senkronizasyonu açın</translation>
 <translation id="4225895483398857530">Araç çubuğu kısayolu</translation>
 <translation id="4242533952199664413">Ayarları aç</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - İndiriliyor…</translation>
 <translation id="4404568932422911380">Yer işareti yok</translation>
 <translation id="4405224443901389797">Klasöre taşı…</translation>
+<translation id="4409271659088619928">Arama motorunuz <ph name="DSE" />. Arama geçmişinizi silmek için arama motorunuzun talimatlarını (varsa) inceleyin.</translation>
 <translation id="4411535500181276704">Basit mod</translation>
 <translation id="4415276339145661267">Google Hesabınızı yönetin</translation>
 <translation id="4427306783828095590">Gelişmiş koruma, kimlik avını ve kötü amaçlı yazılımları engellemek için daha fazla özellik sunar</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Şifreleri kontrol et</translation>
 <translation id="6000066717592683814">Google kalsın</translation>
 <translation id="6000203700195075278">Yeniden takip et</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Arama<ph name="END_LINK1" /> veya başka biçimlerdeki geçmişi temizlemek için <ph name="BEGIN_LINK2" />Google Etkinliğim<ph name="END_LINK2" />'i ziyaret edin</translation>
 <translation id="6005538289190791541">Önerilen şifre</translation>
 <translation id="6032091552407840792">Bu deneme yalnızca <ph name="BEGIN_LINK" />bazı bölgelerde<ph name="END_LINK" /> etkindir.</translation>
 <translation id="6033245666633565791">Chrome, <ph name="BEGIN_LINK" />Özel Korumalı Alan<ph name="END_LINK" /> girişimi kapsamında, açık web'i korurken sizi siteler arası izlemeden koruyacak yeni teknolojiler geliştiriyor.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Hem siz hem de web'deki herkes için güvenliği iyileştirir.</translation>
 <translation id="6618554661997243500">Size özel popüler siteleri ve haberleri görmek için Ana sayfa düğmesine dokunun</translation>
 <translation id="6627583120233659107">Klasörü düzenle</translation>
-<translation id="6635718764393004944">Arama motorunuz <ph name="DSE" />. Sağlanmışsa arama geçmişinizi silmek için arama motorunuzun talimatlarına bakın.</translation>
 <translation id="663674369910034433">Gizlilik, güvenlik ve veri toplamayla ilgili daha fazla ayar için <ph name="BEGIN_LINK1" />Senkronizasyon<ph name="END_LINK1" /> ve <ph name="BEGIN_LINK2" />Google hizmetleri<ph name="END_LINK2" /> konularına bakın.</translation>
 <translation id="6643016212128521049">Temizle</translation>
 <translation id="6643649862576733715">Tasarruf edilen veri miktarına göre sırala</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
index f19b39636..7c84b032 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Обчислення…</translation>
 <translation id="1383876407941801731">Пошук</translation>
 <translation id="1384704387250346179">Переклад через Об'єктив <ph name="BEGIN_NEW" />Нове<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Стилізувати виділений текст</translation>
 <translation id="1386674309198842382">У мережі <ph name="LAST_UPDATED" /> дн. тому</translation>
 <translation id="1397811292916898096">Шукати в <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">"Не відстежувати"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" />, кнопка <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Надсилає деякі файли cookie й пошукові запити з адресного рядка та вікна пошуку в пошукову систему за умовчанням</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# файл}one{# файл}few{# файли}many{# файлів}other{# файлу}}</translation>
-<translation id="2017836877785168846">Очищує історію й автозавершення в адресному рядку.</translation>
 <translation id="2021896219286479412">Керування повноекранним режимом</translation>
 <translation id="2038563949887743358">Увімкнути опцію "Запитувати версію сайту для комп’ютера"</translation>
 <translation id="2039379262107991683">Додавайте сторінки в список читання, щоб отримувати нагадування переглянути їх</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Пошук з Об'єктивом <ph name="BEGIN_NEW" />Новинка<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Відкрити в новій вкладці</translation>
 <translation id="4198423547019359126">Немає доступних місць для завантаження</translation>
-<translation id="4206707945726604465">Щоб очистити історію, перейдіть на сторінку <ph name="BEGIN_LINK1" />Мої дії в Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Щоб отримувати персоналізовані пропозиції від Google, увімкніть синхронізацію</translation>
 <translation id="4225895483398857530">Кнопка на панелі інструментів</translation>
 <translation id="4242533952199664413">Відкрити налаштування</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Завантаження…</translation>
 <translation id="4404568932422911380">Немає закладок</translation>
 <translation id="4405224443901389797">Перемістити в папку…</translation>
+<translation id="4409271659088619928">Ваша пошукова система – <ph name="DSE" />. Перегляньте її вказівки щодо того, як видалити історію пошуку (якщо вона є).</translation>
 <translation id="4411535500181276704">Спрощений режим</translation>
 <translation id="4415276339145661267">Керувати обліковим записом Google</translation>
 <translation id="4427306783828095590">Покращений захист ще ефективніше блокує фішинг і зловмисне програмне забезпечення</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Перевірити паролі</translation>
 <translation id="6000066717592683814">Залишити Google</translation>
 <translation id="6000203700195075278">Підписатися знову</translation>
-<translation id="6002623704405939939">Щоб очистити історію, наприклад <ph name="BEGIN_LINK1" />пошуку<ph name="END_LINK1" />, перейдіть на сторінку <ph name="BEGIN_LINK2" />Мої дії в Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Запропонований пароль</translation>
 <translation id="6032091552407840792">Ця пробна версія доступна лише в <ph name="BEGIN_LINK" />певних регіонах<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">За допомогою <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> команда Chrome розробляє нові технології, які захистять вас від механізмів відстеження на різних сайтах, зберігаючи відкритість і незалежність мережі Інтернет.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Покращує захист усіх користувачів в Інтернеті.</translation>
 <translation id="6618554661997243500">Щоб переглянути підібрані для вас сайти й новини, натисніть кнопку домашньої сторінки</translation>
 <translation id="6627583120233659107">Редагувати папку</translation>
-<translation id="6635718764393004944">Ваша пошукова система – <ph name="DSE" />. Щоб видалити історію пошуку, виконайте вказівки для цієї системи (якщо вони доступні).</translation>
 <translation id="663674369910034433">Інші налаштування конфіденційності, безпеки та збору даних доступні в розділах <ph name="BEGIN_LINK1" />Синхронізація<ph name="END_LINK1" /> та <ph name="BEGIN_LINK2" />Сервіси Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Очистити</translation>
 <translation id="6643649862576733715">Сортувати за кількістю заощадженого трафіку</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
index fc4c952..e9df39f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">شمار کیا جا رہا ہے…</translation>
 <translation id="1383876407941801731">تلاش کریں</translation>
 <translation id="1384704387250346179">‏Google لینز سے تصویر کا ترجمہ کریں <ph name="BEGIN_NEW" />نیا<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">ہائی لائٹ کو اسٹائلائز کریں</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> دن پہلے فعال تھا</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> کے ساتھ تلاش کریں</translation>
 <translation id="1406000523432664303">"ٹریک نہ کریں"</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> بٹن</translation>
 <translation id="2000419248597011803">پتہ بار اور تلاش خانے سے کچھ کوکیز اور تلاشیاں آپ کے ڈیفالٹ تلاش انجن کو بھیجتا ہے</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# فائل}other{# فائلیں}}</translation>
-<translation id="2017836877785168846">پتہ بار کی سرگزشت اور خودکار تکمیلات کو صاف کرتا ہے۔</translation>
 <translation id="2021896219286479412">پوری اسکرین کے سائٹ کنٹرولز</translation>
 <translation id="2038563949887743358">ڈیسک ٹاپ سائٹ کی درخواست کو آن کریں</translation>
 <translation id="2039379262107991683">یاد دہانی حاصل کرنے کے ليے اپنی پڑھنے کی فہرست میں صفحات شامل کریں</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">‏Google لینز سے تلاش کریں <ph name="BEGIN_NEW" />نیا<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">نئے ٹیب میں کھولیں</translation>
 <translation id="4198423547019359126">ڈاؤن لوڈ کیلئے کوئی مقام دستیاب نہیں ہے</translation>
-<translation id="4206707945726604465">‏سرگزشت کی دیگر فارمز کو صاف کرنے کیلئے <ph name="BEGIN_LINK1" />Google کی میری سرگرمی<ph name="END_LINK1" /> ملاحظہ کریں</translation>
 <translation id="4209895695669353772">‏Google کی جانب سے تجویز کردہ ذاتی نوعیت کا مواد حاصل کرنے کیلئے، سِنک کو آن کریں</translation>
 <translation id="4225895483398857530">ٹول بار کا شارٹ کٹ</translation>
 <translation id="4242533952199664413">ترتیبات کھولیں</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - ڈاؤن لوڈ ہو رہی ہے…</translation>
 <translation id="4404568932422911380">کوئی بُک مارک نہیں</translation>
 <translation id="4405224443901389797">اس میں منتقل کریں…</translation>
+<translation id="4409271659088619928">آپ کا سرچ انجن <ph name="DSE" /> ہے۔ اگر قابل اطلاق ہو تو اپنی تلاش کی سرگزشت حذف کرنے کے لیے ان کی ہدایات دیکھیں۔</translation>
 <translation id="4411535500181276704">لائٹ موڈ</translation>
 <translation id="4415276339145661267">‏اپنے Google اکاؤنٹ کا نظم کریں</translation>
 <translation id="4427306783828095590">فریب دہی اور میلوئیر کو مسدود کرنے کیلئے بہتر کردہ حفاظت مزید کام کرتی ہے</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">پاس ورڈز چیک کریں</translation>
 <translation id="6000066717592683814">‏Google کو رکھیں</translation>
 <translation id="6000203700195075278">دوبارہ پیروی کریں</translation>
-<translation id="6002623704405939939">‏<ph name="BEGIN_LINK1" />تلاش<ph name="END_LINK1" /> یا کسی اور طرح کی سرگزشت کو صاف کرنے کے لیے <ph name="BEGIN_LINK2" />Google کی میری سرگرمی<ph name="END_LINK2" /> ملاحظہ کریں</translation>
 <translation id="6005538289190791541">تجویز کردہ پاس ورڈ</translation>
 <translation id="6032091552407840792">یہ ٹرائل صرف <ph name="BEGIN_LINK" />کچھ علاقوں<ph name="END_LINK" /> میں ہی فعال ہے۔</translation>
 <translation id="6033245666633565791">‏<ph name="BEGIN_LINK" />رازداری سینڈ باکس<ph name="END_LINK" /> کے ساتھ، Chrome آپ کو اوپن ویب کے تحفظ کے دوران کراس سائٹ کی ٹریکنگ سے محفوظ رکھنے کے لیے نئی ٹیکنالوجیز تیار کر رہا ہے۔
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">نام کافی بڑا ہے</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# تصویر}other{# تصاویر}}</translation>
 <translation id="6447558397796644647">وہ بُک مارک تلاش نہیں کیا جا سکا۔ اپنا املا چیک کریں یا ایک نیا بُک مارک شامل کریں۔</translation>
+<translation id="6459045781120991510">سرویز</translation>
 <translation id="6461962085415701688">فائل نہیں کھل سکتی</translation>
 <translation id="6464977750820128603">‏آپ Chrome میں اپنی ملاحظہ کردہ سائٹس کو دیکھ اور ان کے لیے ٹائمرز سیٹ کر سکتے ہیں۔\n\nجن سائٹس کے لیے آپ ٹائمرز سیٹ کرتے ہیں اور جتنی دیر تک آپ ان سائٹس کو ملاحظہ کرتے ہیں اس کے بارے میں Google معلومات حاصل کرتا ہے۔ ڈیجیٹل فلاح و بہبود کو بہتر بنانے کے لیے اس معلومات کا استعمال کیا جاتا ہے۔</translation>
 <translation id="6475951671322991020">ویڈیو ڈاؤن لوڈ کریں</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">آپ کے لیے اور ویب پر ہر کسی کے لیے سیکیورٹی کو بہتر بناتا ہے۔</translation>
 <translation id="6618554661997243500">اپنے لئے سر فہرست سائٹس اور کہانیاں دیکھنے کے لئے، ہوم بٹن پر تھپتھپائیں</translation>
 <translation id="6627583120233659107">فولڈر میں ترمیم کریں</translation>
-<translation id="6635718764393004944">آپ کا سرچ انجن <ph name="DSE" /> ہے۔ اگر قابل اطلاق ہو تو اپنی تلاش کی سرگزشت کو حذف کرنے کیلئے ان کی ہدایات دیکھیں۔</translation>
 <translation id="663674369910034433">‏رازداری، سیکیورٹی اور ڈیٹا جمع کرنے سے متعلق مزید ترتیبات کیلئے، <ph name="BEGIN_LINK1" />مطابقت پذیری<ph name="END_LINK1" /> اور <ph name="BEGIN_LINK2" />Google سروسز<ph name="END_LINK2" /> دیکھیں</translation>
 <translation id="6643016212128521049">صاف کریں</translation>
 <translation id="6643649862576733715">بچت کردہ ڈیٹا کی مقدار کے لحاظ سے ترتیب دیں</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">اسٹائلائزڈ ہائی لائٹ <ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">‏یہ یقینی بنائیں کہ Chrome پر <ph name="TARGET_DEVICE_NAME" /> کی مطابقت پذیری آن ہے</translation>
 <translation id="7252076891734325316">اپنا فون کمپیوٹر کے قریب رکھیں</translation>
+<translation id="727288900855680735"><ph name="ORIGIN" /> میں <ph name="ONE_TIME_CODE" /> کو جمع کرائیں؟</translation>
 <translation id="7274013316676448362">مسدود سائٹ</translation>
 <translation id="7286572596625053347"><ph name="LANGUAGE" /> تبدیل کریں؟</translation>
 <translation id="7290209999329137901">'نام تبدیل کریں' دستیاب نہیں ہے</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 2ebefa2..7e4fe2f 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
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Hisoblanmoqda…</translation>
 <translation id="1383876407941801731">Qidiruv</translation>
 <translation id="1384704387250346179">Google Lens yordamida tarjima <ph name="BEGIN_NEW" />Yangi<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Belgilov stili</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> kun oldin onlayn edi</translation>
 <translation id="1397811292916898096"><ph name="PRODUCT_NAME" /> orqali qidirish</translation>
 <translation id="1406000523432664303">“Kuzatilmasin”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Manzillar qatori va qidiruv oynasida kiritilgan so‘rovlar va ba’zi cookie ma’lumotlarni standart qidiruv tizimiga yuboradi</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# ta fayl}other{# ta fayl}}</translation>
-<translation id="2017836877785168846">Manzil qatoridan tarix va avtoto‘ldirishlarni tozalaydi.</translation>
 <translation id="2021896219286479412">To‘liq ekranli rejim sozlamalari</translation>
 <translation id="2038563949887743358">Saytning to‘liq versiyasini ko‘rish</translation>
 <translation id="2039379262107991683">Keyinroq eslatma olish uchun sahifalarni Saqlab oling.</translation>
@@ -490,8 +488,8 @@
 <translation id="4181841719683918333">Tillar</translation>
 <translation id="4183868528246477015"><ph name="BEGIN_NEW" />Yangi<ph name="END_NEW" /> Google Lens bilan qidiring</translation>
 <translation id="4195643157523330669">Yangi varaqda ochish</translation>
+<translation id="4196597275619698563">Karta yaratish</translation>
 <translation id="4198423547019359126">Yuklab olish uchun bo‘sh joy mavjud emas</translation>
-<translation id="4206707945726604465">Boshqa tarix qaydlarini tozalash uchun <ph name="BEGIN_LINK1" />Google xizmatidagi harakatlarim<ph name="END_LINK1" /> sahifasini oching</translation>
 <translation id="4209895695669353772">Bildirgilar Google tomonidan faqat sizning qiziqishlaringiz bo‘yicha taklif qilinishi uchun sinxronizatsiyani yoqing</translation>
 <translation id="4225895483398857530">Asboblar paneli yorligʻi</translation>
 <translation id="4242533952199664413">Sozlamalarni ochish</translation>
@@ -515,6 +513,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Yuklab olinmoqda…</translation>
 <translation id="4404568932422911380">Hech qanday xatcho‘p yo‘q</translation>
 <translation id="4405224443901389797">Boshqa joyga olish…</translation>
+<translation id="4409271659088619928">Qidiruv tizimingiz: <ph name="DSE" />. Imkon boʻlsa, qidiruv tarixini qanday tozalash haqidagi koʻrsatmalarni oching.</translation>
 <translation id="4411535500181276704">Lite rejimi</translation>
 <translation id="4415276339145661267">Google hisobingizni boshqaring</translation>
 <translation id="4427306783828095590">Kengaytirilgan himoya fishing va zararli dasturlarni bloklaydi</translation>
@@ -774,7 +773,6 @@
 <translation id="5979084224081478209">Parollarni tekshiring</translation>
 <translation id="6000066717592683814">Google qolaversin</translation>
 <translation id="6000203700195075278">Qayta obuna</translation>
-<translation id="6002623704405939939"><ph name="BEGIN_LINK1" />Qidiruv<ph name="END_LINK1" /> soʻrovlari yoki boshqa tarix qaydlarini tozalash uchun <ph name="BEGIN_LINK2" />Google xizmatidagi harakatlarim<ph name="END_LINK2" /> sahifasini oching</translation>
 <translation id="6005538289190791541">Taklif qilingan parol</translation>
 <translation id="6032091552407840792">Bu tajribaviy funksiya faqatgina <ph name="BEGIN_LINK" />ayrim mamlakatlarda<ph name="END_LINK" /> ishlaydi.</translation>
 <translation id="6033245666633565791"><ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> yordamida Chrome ochiq internetni rivojlantirishni qoʻllab-quvvatlovchi va foydalanuvchilarni kuzatuv mexanizmlaridan himoya qiladigan texnologiyalarni ishlab chiqadi.
@@ -886,7 +884,6 @@
 <translation id="661266467055912436">Siz va yaqinlaringizni internetdan yaxshiroq himoyalaydi.</translation>
 <translation id="6618554661997243500">Eng sara saytlar va maqolalarni koʻrish uchun bosh sahifa tugmasini bosing</translation>
 <translation id="6627583120233659107">Jildni tahrirlash</translation>
-<translation id="6635718764393004944">Qidiruv tizimingiz: <ph name="DSE" />. Imkon bo'lsa, qidiruv tarixini qanday tozalash mumkinligini ochish.</translation>
 <translation id="663674369910034433">Maxfiylik, xavfsizlik va axborotlar jamlanishi haqida batafsil axborot olish uchun <ph name="BEGIN_LINK1" />Sinxronlash<ph name="END_LINK1" /> va <ph name="BEGIN_LINK2" />Google xizmatlari<ph name="END_LINK2" /> bilan tanishing</translation>
 <translation id="6643016212128521049">Tozalash</translation>
 <translation id="6643649862576733715">Tejalgan trafik asosida saralash</translation>
@@ -1050,6 +1047,7 @@
 <translation id="7704317875155739195">Qidiruv va URL manzillarning avtomatik kiritilishi</translation>
 <translation id="7707922173985738739">Mobil internetdan foydalanish</translation>
 <translation id="7725024127233776428">Xatchoʻplarga saqlanadigan sahifalar shu yerda chiqadi</translation>
+<translation id="7731260005404856143">Google hisobingizga kirganingizda <ph name="BEGIN_LINK1" />boshqa shakldagi harakatlaringiz<ph name="END_LINK1" /> hisobingizga saqlanishi mumkin. Ularni istalgan vaqt oʻchirish mumkin.</translation>
 <translation id="7757787379047923882"><ph name="DEVICE_NAME" /> qurilmasidan ulashilgan matn</translation>
 <translation id="7761849928583394409">Sana va vaqtni tanlang</translation>
 <translation id="7762668264895820836">SD karta <ph name="SD_CARD_NUMBER" /></translation>
@@ -1240,6 +1238,7 @@
 <translation id="8854223127042600341">Oflayn fayllarni ochish</translation>
 <translation id="8856607253650333758">Tavsiflarini yuklash</translation>
 <translation id="8873817150012960745">Boshlash uchun bu yerga bosing</translation>
+<translation id="8881973373982641723">Qidiruv maydonchasidagi tarixni tozalaydi.</translation>
 <translation id="889338405075704026">Chrome sozlamalarini ochish</translation>
 <translation id="8898822736010347272">Ochilgan sahifalarning URL manzillari, cheklangan tizim va sahifalar axborotini anonim ravishda Google serverlariga yuboradi va internetdagi yangi tahdidlarni aniqlashga yordam berib, barcha foydalanuvchilarni bu tahdidlardan himoya qiladi.</translation>
 <translation id="8909135823018751308">Ulashish…</translation>
@@ -1293,6 +1292,7 @@
 <translation id="9209888181064652401">Telefon qilinmaydi</translation>
 <translation id="9212845824145208577">Bundan pasti olinmaydi. Sahifaning quyi qismidan qayta boshlang.</translation>
 <translation id="9219103736887031265">Rasmlar</translation>
+<translation id="923957533152125119">Google hisobingizga kirganingizda <ph name="BEGIN_LINK1" />Qidiruv tarixi<ph name="END_LINK1" /> va <ph name="BEGIN_LINK2" />boshqa shakldagi harakatlaringiz<ph name="END_LINK2" /> hisobingizga saqlanishi mumkin. Ularni istalgan vaqt oʻchirish mumkin.</translation>
 <translation id="926205370408745186">Chrome amallarini Raqamli qulaylikdan olib tashlash</translation>
 <translation id="927968626442779827">Google Chrome brauzerida Lite rejimidan foydalanish</translation>
 <translation id="932327136139879170">Bosh sahifa</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
index 068e643..d4931fa 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Đang tính toán...</translation>
 <translation id="1383876407941801731">Tìm kiếm</translation>
 <translation id="1384704387250346179">Dịch hình ảnh bằng Google Ống kính <ph name="BEGIN_NEW" />Mới<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Cách điệu nội dung được làm nổi bật</translation>
 <translation id="1386674309198842382">Hoạt động <ph name="LAST_UPDATED" /> ngày trước</translation>
 <translation id="1397811292916898096">Tìm kiếm bằng <ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">“Không theo dõi”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037">Nút <ph name="MESSAGE" /> <ph name="LINK_NAME" /></translation>
 <translation id="2000419248597011803">Gửi một số cookie và nội dung tìm kiếm từ thanh địa chỉ cũng như hộp tìm kiếm tới công cụ tìm kiếm mặc định</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# tệp}other{# tệp}}</translation>
-<translation id="2017836877785168846">Xóa lịch sử duyệt web và nội dung tự động hoàn thành trong thanh địa chỉ.</translation>
 <translation id="2021896219286479412">Kiểm soát trang toàn màn hình</translation>
 <translation id="2038563949887743358">Bật Yêu cầu trang web cho máy tính</translation>
 <translation id="2039379262107991683">Thêm trang vào Danh sách đọc để nhận lời nhắc</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Tìm bằng Google Ống kính <ph name="BEGIN_NEW" />Mới<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Mở trong thẻ mới</translation>
 <translation id="4198423547019359126">Không có vị trí tải xuống</translation>
-<translation id="4206707945726604465">Để xóa các dạng nhật ký khác, hãy truy cập trang <ph name="BEGIN_LINK1" />Hoạt động của tôi trên Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Để nhận nội dung do Google đề xuất riêng cho bạn, hãy bật tính năng đồng bộ hóa</translation>
 <translation id="4225895483398857530">Lối tắt trên thanh công cụ</translation>
 <translation id="4242533952199664413">Mở phần cài đặt</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> – Đang tải xuống…</translation>
 <translation id="4404568932422911380">Không có dấu trang nào</translation>
 <translation id="4405224443901389797">Chuyển tới...</translation>
+<translation id="4409271659088619928">Bạn đang dùng công cụ tìm kiếm <ph name="DSE" />. Để xóa nhật ký tìm kiếm, hãy xem hướng dẫn (nếu có) của công cụ tìm kiếm đó.</translation>
 <translation id="4411535500181276704">Chế độ thu gọn</translation>
 <translation id="4415276339145661267">Quản lý Tài khoản Google của bạn</translation>
 <translation id="4427306783828095590">Chế độ bảo vệ tăng cường giúp chặn phần mềm độc hại và hành vi lừa đảo hiệu quả hơn</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Kiểm tra mật khẩu</translation>
 <translation id="6000066717592683814">Giữ Google làm công cụ tìm kiếm mặc định</translation>
 <translation id="6000203700195075278">Theo dõi lại</translation>
-<translation id="6002623704405939939">Để xóa <ph name="BEGIN_LINK1" />nội dung tìm kiếm<ph name="END_LINK1" /> hoặc các dạng nhật ký khác, hãy truy cập vào trang <ph name="BEGIN_LINK2" />Hoạt động của tôi trên Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Mật khẩu đề xuất</translation>
 <translation id="6032091552407840792">Chế độ dùng thử này chỉ hoạt động ở <ph name="BEGIN_LINK" />một số khu vực<ph name="END_LINK" />.</translation>
 <translation id="6033245666633565791">Với <ph name="BEGIN_LINK" />Hộp cát về quyền riêng tư<ph name="END_LINK" />, Chrome sẽ phát triển các công nghệ mới để giúp bạn không bị theo dõi trên nhiều trang web trong khi vẫn duy trì môi trường web mở.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Tăng độ bảo mật cho bạn và mọi người trên web.</translation>
 <translation id="6618554661997243500">Để xem các trang web hàng đầu và tin nổi bật dành cho bạn, hãy nhấn vào nút Trang chủ</translation>
 <translation id="6627583120233659107">Chỉnh sửa thư mục</translation>
-<translation id="6635718764393004944">Bạn đang dùng công cụ tìm kiếm <ph name="DSE" />. Nếu có thể, hãy xem hướng dẫn của công cụ này về cách xóa nhật ký tìm kiếm.</translation>
 <translation id="663674369910034433">Bạn có thể xem thêm các tùy chọn cài đặt liên quan đến quyền riêng tư, bảo mật và hoạt động thu thập dữ liệu trong phần <ph name="BEGIN_LINK1" />Đồng bộ hóa<ph name="END_LINK1" /> và <ph name="BEGIN_LINK2" />Các dịch vụ của Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Xóa</translation>
 <translation id="6643649862576733715">Sắp xếp theo lượng dữ liệu tiết kiệm được</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
index 9a03d5e..7f6fcf2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">正在计算…</translation>
 <translation id="1383876407941801731">搜索</translation>
 <translation id="1384704387250346179">使用 Google 智能镜头翻译图片<ph name="BEGIN_NEW" />新<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">为突出显示的内容添加样式</translation>
 <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> 天前曾有活动</translation>
 <translation id="1397811292916898096">使用 <ph name="PRODUCT_NAME" /> 进行搜索</translation>
 <translation id="1406000523432664303">“不跟踪”</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />按钮</translation>
 <translation id="2000419248597011803">将一些 Cookie 以及地址栏和搜索框中的搜索字词发送给您的默认搜索引擎</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# 个文件}other{# 个文件}}</translation>
-<translation id="2017836877785168846">清除历史记录和地址栏中的自动补全项。</translation>
 <translation id="2021896219286479412">全屏网站控件</translation>
 <translation id="2038563949887743358">开启“请求切换到桌面版网站”</translation>
 <translation id="2039379262107991683">将网页添加到阅读清单中即可接收提醒</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">使用 Google 智能镜头进行搜索<ph name="BEGIN_NEW" />新功能<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">在新标签页中打开</translation>
 <translation id="4198423547019359126">没有可用的下载内容保存位置</translation>
-<translation id="4206707945726604465">若要清除其他形式的历史记录,请访问<ph name="BEGIN_LINK1" />我的 Google 活动记录<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">要获取 Google 推荐的个性化内容,请开启同步功能</translation>
 <translation id="4225895483398857530">工具栏中的快捷方式</translation>
 <translation id="4242533952199664413">打开“设置”</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - 正在下载…</translation>
 <translation id="4404568932422911380">没有书签</translation>
 <translation id="4405224443901389797">移动到…</translation>
+<translation id="4409271659088619928">您所用的搜索引擎是<ph name="DSE" />。请查看它的相关说明,了解如何删除您的搜索记录(若适用)。</translation>
 <translation id="4411535500181276704">精简模式</translation>
 <translation id="4415276339145661267">管理您的 Google 帐号</translation>
 <translation id="4427306783828095590">“增强型保护”选项在防范网上诱骗和恶意软件方面更高一筹</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">检查密码</translation>
 <translation id="6000066717592683814">继续使用 Google</translation>
 <translation id="6000203700195075278">重新关注</translation>
-<translation id="6002623704405939939">若要清除<ph name="BEGIN_LINK1" />搜索<ph name="END_LINK1" />记录或其他形式的历史记录,请前往<ph name="BEGIN_LINK2" />我的 Google 活动记录<ph name="END_LINK2" />页面</translation>
 <translation id="6005538289190791541">建议的密码</translation>
 <translation id="6032091552407840792">这项试用版功能仅在<ph name="BEGIN_LINK" />部分区域<ph name="END_LINK" />有效。</translation>
 <translation id="6033245666633565791">Chrome 正在通过 <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> 开发新技术,以便既能保护开放网络又能使您免受跨网站跟踪。
@@ -853,6 +850,7 @@
 <translation id="6441734959916820584">名称太长</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# 张图片}other{# 张图片}}</translation>
 <translation id="6447558397796644647">找不到该书签。请检查您的拼写或添加新书签。</translation>
+<translation id="6459045781120991510">调查问卷</translation>
 <translation id="6461962085415701688">无法打开文件</translation>
 <translation id="6464977750820128603">您可以查看自己在 Chrome 中访问的网站并为这些网站设置计时器。\n\nGoogle 会获取这些设有计时器的网站的相关信息以及您对这些网站的访问时长。这些信息会被用于改进“数字健康”应用。</translation>
 <translation id="6475951671322991020">下载视频</translation>
@@ -885,7 +883,6 @@
 <translation id="661266467055912436">为您以及网络上的所有人提供更好的安全保障。</translation>
 <translation id="6618554661997243500">若要查看为您推荐的热门网站和报道,请点按“主屏幕”按钮</translation>
 <translation id="6627583120233659107">修改文件夹</translation>
-<translation id="6635718764393004944">您所用的搜索引擎是<ph name="DSE" />。如果适用的话,请查看它的相关说明以了解如何删除您的搜索记录。</translation>
 <translation id="663674369910034433">如需了解更多与隐私、安全和数据收集相关的设置,请前往<ph name="BEGIN_LINK1" />同步功能<ph name="END_LINK1" />和 <ph name="BEGIN_LINK2" />Google 服务<ph name="END_LINK2" />部分</translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6643649862576733715">按已节省的数据流量排序</translation>
@@ -969,6 +966,7 @@
 <translation id="7242755609445462077">已为突出显示的内容添加样式,日期为:<ph name="CURRENT_DATE" /></translation>
 <translation id="7248069434667874558">请确保<ph name="TARGET_DEVICE_NAME" />已在 Chrome 中开启同步功能</translation>
 <translation id="7252076891734325316">将手机靠近计算机</translation>
+<translation id="727288900855680735">将 <ph name="ONE_TIME_CODE" /> 提交至 <ph name="ORIGIN" />?</translation>
 <translation id="7274013316676448362">禁止访问的网站</translation>
 <translation id="7286572596625053347">更改<ph name="LANGUAGE" />?</translation>
 <translation id="7290209999329137901">不可重命名</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
index a71eb148..ecddfa90 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">正在運算…</translation>
 <translation id="1383876407941801731">搜尋</translation>
 <translation id="1384704387250346179">使用「Google 智能鏡頭」翻譯圖片 <ph name="BEGIN_NEW" />新功能<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">風格化焦點內容</translation>
 <translation id="1386674309198842382">曾於 <ph name="LAST_UPDATED" /> 天前在線</translation>
 <translation id="1397811292916898096">使用 <ph name="PRODUCT_NAME" /> 搜尋內容</translation>
 <translation id="1406000523432664303">「不追蹤」</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" />,<ph name="LINK_NAME" />按鈕</translation>
 <translation id="2000419248597011803">將部分 Cookie,以及網址列和搜尋框中的搜尋內容傳送至預設搜尋引擎</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# 個檔案}other{# 個檔案}}</translation>
-<translation id="2017836877785168846">清除網址列中的記錄和自動完成資料。</translation>
 <translation id="2021896219286479412">全螢幕網站控制</translation>
 <translation id="2038563949887743358">開啟「切換為電腦版網站」</translation>
 <translation id="2039379262107991683">將網頁新增至閱讀清單,即可在之後收到閱讀提醒</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">使用「Google 智能鏡頭」的搜尋功能<ph name="BEGIN_NEW" />新功能<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">在新分頁中開啟</translation>
 <translation id="4198423547019359126">沒有可用的下載位置</translation>
-<translation id="4206707945726604465">如要清除其他形式的記錄,請前往「<ph name="BEGIN_LINK1" />我的 Google 活動<ph name="END_LINK1" />」</translation>
 <translation id="4209895695669353772">如要接收 Google 建議的個人化內容,請開啟同步處理功能</translation>
 <translation id="4225895483398857530">工具列捷徑</translation>
 <translation id="4242533952199664413">開啟設定</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - 下載中…</translation>
 <translation id="4404568932422911380">沒有書籤</translation>
 <translation id="4405224443901389797">移至…</translation>
+<translation id="4409271659088619928">您的搜尋引擎是「<ph name="DSE" />」。建議您查看搜尋引擎的搜尋記錄刪除指示 (如有)。</translation>
 <translation id="4411535500181276704">精簡模式</translation>
 <translation id="4415276339145661267">管理您的 Google 帳戶</translation>
 <translation id="4427306783828095590">強化保護功能可進一步封鎖仿冒詐騙和惡意軟件</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">檢查密碼</translation>
 <translation id="6000066717592683814">繼續使用 Google</translation>
 <translation id="6000203700195075278">重新追蹤</translation>
-<translation id="6002623704405939939">如要清除<ph name="BEGIN_LINK1" />搜尋<ph name="END_LINK1" />或其他類型的記錄,請前往<ph name="BEGIN_LINK2" />我的 Google 活動<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">建議的密碼</translation>
 <translation id="6032091552407840792">此試用功能只會在<ph name="BEGIN_LINK" />部分地區<ph name="END_LINK" />啟用。</translation>
 <translation id="6033245666633565791">Chrome 透過「<ph name="BEGIN_LINK" />私隱沙箱<ph name="END_LINK" />」開發新的技術,防止有心人士透過跨網站追蹤機制取得您的資料,同時保護開放網絡。
@@ -853,7 +850,7 @@
 <translation id="6441734959916820584">此名稱過長</translation>
 <translation id="6444421004082850253">{FILE_COUNT,plural, =1{# 張圖片}other{# 張圖片}}</translation>
 <translation id="6447558397796644647">找不到該書籤。請檢查拼字或新增書籤。</translation>
-<translation id="6459045781120991510">問卷調查</translation>
+<translation id="6459045781120991510">問卷</translation>
 <translation id="6461962085415701688">無法開啟檔案</translation>
 <translation id="6464977750820128603">您可查看在 Chrome 上瀏覽的網站,並為這些網站設定計時器。\n\nGoogle 會收到這些設有計時器的網站相關資料,以及您的瀏覽時間長度。這些資料可協助我們改善「健康數碼生活」。</translation>
 <translation id="6475951671322991020">下載影片</translation>
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">為您和網絡上的所有使用者提高安全性。</translation>
 <translation id="6618554661997243500">㩒「主按鈕」就可以睇下熱門網站同報導</translation>
 <translation id="6627583120233659107">編輯資料夾</translation>
-<translation id="6635718764393004944">您的搜尋引擎是 <ph name="DSE" />。請查看搜尋引擎的指示 (如有) 以便刪除搜尋記錄。</translation>
 <translation id="663674369910034433">如需更多與私隱權、安全性和資料收集相關的設定,請參閱<ph name="BEGIN_LINK1" />同步處理<ph name="END_LINK1" />和 <ph name="BEGIN_LINK2" />Google 服務<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6643649862576733715">依節省數據量排序</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
index d222f4c..323566d 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">計算中…</translation>
 <translation id="1383876407941801731">搜尋</translation>
 <translation id="1384704387250346179">使用 Google 智慧鏡頭翻譯圖片內容 <ph name="BEGIN_NEW" />新功能<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">風格化醒目顯示</translation>
 <translation id="1386674309198842382">上次使用時間:<ph name="LAST_UPDATED" /> 天前</translation>
 <translation id="1397811292916898096">使用 <ph name="PRODUCT_NAME" /> 搜尋</translation>
 <translation id="1406000523432664303">「不追蹤」</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" />按鈕</translation>
 <translation id="2000419248597011803">將網址列和搜尋框中的部分 Cookie 和搜尋字詞傳送給你的預設搜尋引擎</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# 個檔案}other{# 個檔案}}</translation>
-<translation id="2017836877785168846">將歷史記錄和自動即時查詢從網址列中清除。</translation>
 <translation id="2021896219286479412">全螢幕網站控制</translation>
 <translation id="2038563949887743358">開啟「要求電腦版網站」</translation>
 <translation id="2039379262107991683">將網頁新增至閱讀清單,即可在之後收到閱讀提醒</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">使用 Google 智慧鏡頭的搜尋功能 <ph name="BEGIN_NEW" />新功能<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">在新分頁中開啟</translation>
 <translation id="4198423547019359126">沒有可用的下載位置</translation>
-<translation id="4206707945726604465">如要清除其他類型的歷史記錄,請前往<ph name="BEGIN_LINK1" />我的 Google 活動<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">如要取得個人化的 Google 推薦內容,請開啟同步處理功能</translation>
 <translation id="4225895483398857530">工具列捷徑</translation>
 <translation id="4242533952199664413">開啟設定</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - 下載中…</translation>
 <translation id="4404568932422911380">沒有書籤</translation>
 <translation id="4405224443901389797">移至…</translation>
+<translation id="4409271659088619928">你的搜尋引擎是 <ph name="DSE" />。如要瞭解如何刪除搜尋記錄,請查看搜尋引擎的操作說明 (如果有的話)。</translation>
 <translation id="4411535500181276704">精簡模式</translation>
 <translation id="4415276339145661267">管理你的 Google 帳戶</translation>
 <translation id="4427306783828095590">強化防護功能可進一步封鎖網路詐騙和惡意軟體</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">檢查密碼</translation>
 <translation id="6000066717592683814">繼續使用 Google</translation>
 <translation id="6000203700195075278">重新追蹤</translation>
-<translation id="6002623704405939939">如要清除<ph name="BEGIN_LINK1" />搜尋<ph name="END_LINK1" />記錄或其他類型的歷史記錄,請前往<ph name="BEGIN_LINK2" />我的 Google 活動<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">建議的密碼</translation>
 <translation id="6032091552407840792">這項功能目前僅開放<ph name="BEGIN_LINK" />部分地區<ph name="END_LINK" />試用。</translation>
 <translation id="6033245666633565791">Chrome 透過 <ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" /> 開發新的技術,防止有心人士透過跨網站追蹤機制取得你的資料,同時保護開放網路。
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">可為你和所有網路使用者提供更完善的安全防護。</translation>
 <translation id="6618554661997243500">如要查看你常用的網站和精選報導,請輕觸「首頁」按鈕</translation>
 <translation id="6627583120233659107">編輯資料夾</translation>
-<translation id="6635718764393004944">你的搜尋引擎是 <ph name="DSE" />。請參閱相關操作說明,瞭解如何刪除搜尋記錄 (如果有的話)。</translation>
 <translation id="663674369910034433">如需更多有關隱私權、安全性和資料收集的設定,請參閱<ph name="BEGIN_LINK1" />同步處理<ph name="END_LINK1" />和 <ph name="BEGIN_LINK2" />Google 服務<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">清除</translation>
 <translation id="6643649862576733715">依儲存資料量排序</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
index 79ca131..c04a712 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
@@ -68,7 +68,6 @@
 <translation id="1376578503827013741">Ifaka kukhompuyutha...</translation>
 <translation id="1383876407941801731">Sesha</translation>
 <translation id="1384704387250346179">Humusha isithombe ngokuthi Ilensi ye-Google <ph name="BEGIN_NEW" />Okusha<ph name="END_NEW" /></translation>
-<translation id="1385855801883526502">Gqamisa ukwenza isitayela</translation>
 <translation id="1386674309198842382">Isebenze ezinsukwini ezingu-<ph name="LAST_UPDATED" /> ezedlule</translation>
 <translation id="1397811292916898096">Sesha nge-<ph name="PRODUCT_NAME" /></translation>
 <translation id="1406000523432664303">'Ungalandeleli'</translation>
@@ -147,7 +146,6 @@
 <translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> inkinobho</translation>
 <translation id="2000419248597011803">Ithumela amakhukhi nosesho kusukela kubha yekheli nebhokisi losesho kunjini yakho yosesho ezenzakalelayo</translation>
 <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# Ifayela}one{# Amafayela}other{# Amafayela}}</translation>
-<translation id="2017836877785168846">Sula umlando nokuqedela ngokuzenzakalela kwibha lekheli.</translation>
 <translation id="2021896219286479412">Izilawuli zesayithi zesikrini esiphelele</translation>
 <translation id="2038563949887743358">Vula ukucela isayithi yedeskithophu</translation>
 <translation id="2039379262107991683">Engeza amakhasi Ohlwini lwakho Lokufunda ukuze uthole isikhumbuzo</translation>
@@ -491,7 +489,6 @@
 <translation id="4183868528246477015">Sesha ngelensi yeGoogle<ph name="BEGIN_NEW" />Okusha<ph name="END_NEW" /></translation>
 <translation id="4195643157523330669">Vula kuthebhu entsha</translation>
 <translation id="4198423547019359126">Azikho izindawo ezitholakalayo zokulanda</translation>
-<translation id="4206707945726604465">Ukuze usule amanye amafomu omlando, vakashela <ph name="BEGIN_LINK1" />Umsebenzi Wami we-Google<ph name="END_LINK1" /></translation>
 <translation id="4209895695669353772">Ukuze uthole okuqukethwe okwenziwe kwaba ngokwakho i-Google, vula ukuvumelanisa</translation>
 <translation id="4225895483398857530">Isinqamuleli sebha yamathuluzi</translation>
 <translation id="4242533952199664413">Vula izilungiselelo</translation>
@@ -515,6 +512,7 @@
 <translation id="4402611456429872546"><ph name="LANG" /> - Iyadawuniloda…</translation>
 <translation id="4404568932422911380">Awekho amabhukimakhi</translation>
 <translation id="4405224443901389797">Hambisa ku…</translation>
+<translation id="4409271659088619928">Injini yakho yokusesha iyi-<ph name="DSE" />. Bona imiyalelo yabo yokusula umlando wakho wosesho, uma kusebenza.</translation>
 <translation id="4411535500181276704">Imodi elula</translation>
 <translation id="4415276339145661267">Lawula i-akhawunti yakho ye-Google</translation>
 <translation id="4427306783828095590">Isivikelo esithuthukisiwe senza okuningi ukuvimba ubugebengu bokweba imininingwane ebucayi kanye uhlelo olungayilungele ikhompyutha</translation>
@@ -774,7 +772,6 @@
 <translation id="5979084224081478209">Hlola amaphasiwedi</translation>
 <translation id="6000066717592683814">Gcina i-Google</translation>
 <translation id="6000203700195075278">Phinda ulandele</translation>
-<translation id="6002623704405939939">Ukuze usule <ph name="BEGIN_LINK1" />usesho<ph name="END_LINK1" /> noma ezinye izinhlobo zomlando, vakashela <ph name="BEGIN_LINK2" />Umsebenzi Wami we-Google<ph name="END_LINK2" /></translation>
 <translation id="6005538289190791541">Iphasiwedi ephakanyisiwe</translation>
 <translation id="6032091552407840792">Lo mzamo usebenza <ph name="BEGIN_LINK" />ezifundeni ezithile<ph name="END_LINK" /> kuphela.</translation>
 <translation id="6033245666633565791">Nge-<ph name="BEGIN_LINK" />Privacy Sandbox<ph name="END_LINK" />, i-Chrome ithuthukisa ubuchwepheshe obusha bokukuvikela ekulandeleni kwendawo ephambene lapho ugcina khona iwebhu evulekile.
@@ -886,7 +883,6 @@
 <translation id="661266467055912436">Kuthuthukisa ukuvikeleka kwakho nawo wonke umuntu okuwebhu.</translation>
 <translation id="6618554661997243500">Ukuze ubone amasayithi aphezulu nezindaba zakho, thepha inkinobho Yasekhaya</translation>
 <translation id="6627583120233659107">Hlela ifolda</translation>
-<translation id="6635718764393004944">Injini yakho yokusesha iyi-<ph name="DSE" />. Uma kufaneleka, bona imiyalelo yayo ukuze usule umlando wakho wosesho.</translation>
 <translation id="663674369910034433">Ukuze uthole amanye amasethingi ahambisana nobumfihlo, ukuvikeleka, nokuqoqwa kwedatha, bona okuthi <ph name="BEGIN_LINK1" />Ukuvumelanisa<ph name="END_LINK1" /> nokuthi <ph name="BEGIN_LINK2" />Amasevisi we-Google<ph name="END_LINK2" /></translation>
 <translation id="6643016212128521049">Sula</translation>
 <translation id="6643649862576733715">Hlunga ngenani ledatha elondoloziwe</translation>
diff --git a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc
index 642d96bb..535e9fa 100644
--- a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc
+++ b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc
@@ -302,6 +302,7 @@
       /*title=*/u"Fix connection problems",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"verycomplicatedsearchquery"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help/id/test",
       /*locale=*/"");
   search_concepts.push_back(std::move(concept));
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc
index 4ad2d8ea..0f7b817 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -42,6 +42,7 @@
 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h"
 #include "chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/services/multidevice_setup/multidevice_setup_service.h"
@@ -193,6 +194,11 @@
   return tab_strip_ui::IsDraggedTab(drop_data);
 }
 
+int ChromeShellDelegate::GetBrowserWebUITabStripHeight() {
+  DCHECK(ash::features::IsWebUITabStripTabDragIntegrationEnabled());
+  return TabStripUILayout::GetContainerHeight();
+}
+
 aura::Window* ChromeShellDelegate::CreateBrowserForTabDrop(
     aura::Window* source_window,
     const ui::OSExchangeData& drop_data) {
@@ -219,8 +225,19 @@
   // failures can happen in valid states, and if so whether we need to
   // reflect failure in UX.
 
+  // TODO(crbug.com/1225667): Loosen restriction for SplitViewController to be
+  // able to snap a window without calling Show(). It will simplify the logic
+  // without having to set and clear ash::kIsDraggingTabsKey by calling Show()
+  // after snapping the window to the right place.
+
+  // We need to mark the newly created window with |ash::kIsDraggingTabsKey|
+  // and clear it afterwards in order to prevent
+  // SplitViewController::AutoSnapController from snapping it on Show().
+  aura::Window* window = browser->window()->GetNativeWindow();
+  window->SetProperty(ash::kIsDraggingTabsKey, true);
   browser->window()->Show();
-  return browser->window()->GetNativeWindow();
+  window->ClearProperty(ash::kIsDraggingTabsKey);
+  return window;
 }
 
 void ChromeShellDelegate::BindBluetoothSystemFactory(
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h
index 936a9c8..b7cd953 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.h
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -30,6 +30,7 @@
   bool AllowDefaultTouchActions(gfx::NativeWindow window) override;
   bool ShouldWaitForTouchPressAck(gfx::NativeWindow window) override;
   bool IsTabDrag(const ui::OSExchangeData& drop_data) override;
+  int GetBrowserWebUITabStripHeight() override;
   aura::Window* CreateBrowserForTabDrop(
       aura::Window* source_window,
       const ui::OSExchangeData& drop_data) override;
diff --git a/chrome/browser/ui/ash/login_screen_client_impl.cc b/chrome/browser/ui/ash/login_screen_client_impl.cc
index d80ca09..92cef5f 100644
--- a/chrome/browser/ui/ash/login_screen_client_impl.cc
+++ b/chrome/browser/ui/ash/login_screen_client_impl.cc
@@ -280,7 +280,7 @@
 }
 
 void LoginScreenClientImpl::SignOutUser() {
-  chromeos::ScreenLocker::default_screen_locker()->Signout();
+  ash::ScreenLocker::default_screen_locker()->Signout();
 }
 
 void LoginScreenClientImpl::CancelAddUser() {
@@ -288,7 +288,7 @@
 }
 
 void LoginScreenClientImpl::LoginAsGuest() {
-  DCHECK(!chromeos::ScreenLocker::default_screen_locker());
+  DCHECK(!ash::ScreenLocker::default_screen_locker());
   if (ash::LoginDisplayHost::default_host()) {
     ash::LoginDisplayHost::default_host()->GetExistingUserController()->Login(
         chromeos::UserContext(user_manager::USER_TYPE_GUEST,
diff --git a/chrome/browser/ui/ash/network/network_connect_delegate_chromeos.cc b/chrome/browser/ui/ash/network/network_connect_delegate_chromeos.cc
index 8b7bbc3..748a3daa 100644
--- a/chrome/browser/ui/ash/network/network_connect_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/network/network_connect_delegate_chromeos.cc
@@ -15,8 +15,8 @@
 
 bool IsUIAvailable() {
   // UI is available when screen is unlocked.
-  return !chromeos::ScreenLocker::default_screen_locker() ||
-         !chromeos::ScreenLocker::default_screen_locker()->locked();
+  return !ash::ScreenLocker::default_screen_locker() ||
+         !ash::ScreenLocker::default_screen_locker()->locked();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
index ae04232..da88f024 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
@@ -167,9 +167,11 @@
 void SharesheetBubbleView::ShowBubble(
     std::vector<TargetInfo> targets,
     apps::mojom::IntentPtr intent,
-    ::sharesheet::DeliveredCallback delivered_callback) {
+    ::sharesheet::DeliveredCallback delivered_callback,
+    ::sharesheet::CloseCallback close_callback) {
   intent_ = std::move(intent);
   delivered_callback_ = std::move(delivered_callback);
+  close_callback_ = std::move(close_callback);
 
   main_view_->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical));
@@ -250,9 +252,9 @@
     apps::mojom::IntentPtr intent,
     ::sharesheet::DeliveredCallback delivered_callback,
     ::sharesheet::CloseCallback close_callback) {
-  close_callback_ = std::move(close_callback);
   user_selection_made_ = true;  // Disable close when clicking outside bubble.
-  ShowBubble({}, std::move(intent), std::move(delivered_callback));
+  ShowBubble({}, std::move(intent), std::move(delivered_callback),
+             std::move(close_callback));
   if (delivered_callback_) {
     std::move(delivered_callback_)
         .Run(::sharesheet::SharesheetResult::kSuccess);
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.h b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.h
index 30b133c..82473e8 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.h
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.h
@@ -43,7 +43,8 @@
   // |close_callback| is run to inform the caller when the bubble is closed.
   void ShowBubble(std::vector<TargetInfo> targets,
                   apps::mojom::IntentPtr intent,
-                  ::sharesheet::DeliveredCallback delivered_callback);
+                  ::sharesheet::DeliveredCallback delivered_callback,
+                  ::sharesheet::CloseCallback close_callback);
   void ShowNearbyShareBubble(apps::mojom::IntentPtr intent,
                              ::sharesheet::DeliveredCallback delivered_callback,
                              ::sharesheet::CloseCallback close_callback);
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
index ae4bc42..8b27d88 100644
--- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_browsertest.cc
@@ -55,7 +55,7 @@
     sharesheet_service->ShowBubble(
         browser()->tab_strip_model()->GetActiveWebContents(), std::move(intent),
         ::sharesheet::SharesheetMetrics::LaunchSource::kUnknown,
-        base::DoNothing());
+        base::DoNothing(), base::DoNothing());
 
     views::Widget::Widgets new_widgets;
     for (aura::Window* root_window : Shell::GetAllRootWindows())
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
index 1b6d314..4d12a79 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/ash/shelf/app_service/app_service_app_window_arc_tracker.h"
 
 #include "ash/constants/app_types.h"
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/multi_user_window_manager.h"
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/public/cpp/shelf_model.h"
@@ -130,6 +129,7 @@
 
   auto session_id = arc::GetWindowSessionId(window);
   if (session_id.has_value()) {
+    OnSessionDestroyed(*session_id);
     session_id_to_arc_app_window_info_.erase(*session_id);
     if (session_id == active_session_id_)
       active_session_id_ = arc::kNoTaskId;
@@ -177,6 +177,12 @@
   auto it = session_id_to_arc_app_window_info_.find(session_id);
   if (it != session_id_to_arc_app_window_info_.end()) {
     task_id_to_arc_app_window_info_[task_id]->set_window(it->second->window());
+
+    const auto app_shelf_id = it->second->app_shelf_id();
+    auto it_controller = app_shelf_group_to_controller_map_.find(app_shelf_id);
+    if (it_controller != app_shelf_group_to_controller_map_.end())
+      it_controller->second->RemoveSessionId(it->first);
+
     session_id_to_arc_app_window_info_.erase(it);
     if (session_id == active_session_id_)
       active_session_id_ = arc::kNoTaskId;
@@ -387,10 +393,7 @@
   window->SetProperty(ash::kArcPackageNameKey,
                       new std::string(info->package_name()));
   window->SetProperty(ash::kAppIDKey, new std::string(shelf_id.app_id));
-  if (base::FeatureList::IsEnabled(
-          chromeos::features::kArcPreImeKeyEventSupport)) {
-    window->SetProperty(aura::client::kSkipImeProcessing, true);
-  }
+  window->SetProperty(aura::client::kSkipImeProcessing, true);
 
   if (info->app_shelf_id().app_id() == arc::kPlayStoreAppId)
     HandlePlayStoreLaunch(info);
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_instance_registry_helper.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_instance_registry_helper.cc
index 6c82e4ec..be8ef80e 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_instance_registry_helper.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_instance_registry_helper.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
+#include "chrome/browser/lifetime/browser_shutdown.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.h"
@@ -202,6 +203,12 @@
 
 void AppServiceInstanceRegistryHelper::OnSetShelfIDForBrowserWindowContents(
     content::WebContents* contents) {
+  // Do not try to update window status on shutdown, because during the shutdown
+  // phase, we can't guaranteen the window destroy sequence, and it might cause
+  // crash.
+  if (browser_shutdown::HasShutdownStarted())
+    return;
+
   aura::Window* window = GetWindow(contents);
   if (!window || !window->GetToplevelWindow())
     return;
diff --git a/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc b/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc
index 4cd46540..0fe81ccb 100644
--- a/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc
+++ b/chrome/browser/ui/ash/system_tray_client_impl_browsertest.cc
@@ -140,7 +140,7 @@
   EXPECT_FALSE(tray_test_api->Is24HourClock());
 
   // Test lock screen.
-  chromeos::ScreenLockerTester locker;
+  ash::ScreenLockerTester locker;
   locker.Lock();
 
   EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(account_id1_));
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index 29890d8..df2bdd2 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -787,7 +787,8 @@
          host != chrome::kChromeUIThumbnailHost2 &&
          host != chrome::kChromeUISuggestionsHost &&
          host != chrome::kChromeUIDevicesHost &&
-         host != chrome::kChromeUINewTabPageHost;
+         host != chrome::kChromeUINewTabPageHost &&
+         host != chrome::kChromeUINewTabPageThirdPartyHost;
 }
 
 bool IsURLAllowedInIncognito(const GURL& url,
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc
index 434c9f2..d9952592 100644
--- a/chrome/browser/ui/browser_navigator_browsertest.cc
+++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -76,6 +76,10 @@
   return GURL(chrome::kChromeUINewTabPageURL);
 }
 
+GURL GetWebUINewTabPageThirdParty() {
+  return GURL(chrome::kChromeUINewTabPageThirdPartyURL);
+}
+
 GURL GetContentSettingsURL() {
   return GetSettingsURL().Resolve(chrome::kContentSettingsSubPage);
 }
@@ -1283,6 +1287,16 @@
       GetWebUINewTabPage(), ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
 }
 
+// This test verifies that chrome://new-tab-page-third-party isn't opened in the
+// incognito window.
+IN_PROC_BROWSER_TEST_F(
+    BrowserNavigatorTest,
+    Disposition_WebUINewTabPageThirdParty_UseNonIncognitoWindow) {
+  RunUseNonIncognitoWindowTest(
+      GetWebUINewTabPageThirdParty(),
+      ui::PageTransition::PAGE_TRANSITION_AUTO_BOOKMARK);
+}
+
 // This test verifies that the view-source settings page isn't opened in the
 // incognito window.
 IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index f0c0a670..0f32db1 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -83,6 +83,10 @@
 class NativeTheme;
 }
 
+namespace views {
+class Button;
+}  // namespace views
+
 namespace web_modal {
 class WebContentsModalDialogHost;
 }
@@ -396,11 +400,16 @@
       send_tab_to_self::SendTabToSelfBubbleController* controller,
       bool is_user_gesture) = 0;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Returns the PageActionIconView for the Sharing Hub.
+  virtual views::Button* GetSharingHubIconButton() = 0;
+#else
   // Shows the Sharing Hub bubble.
   virtual sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents,
       sharing_hub::SharingHubBubbleController* controller,
       bool is_user_gesture) = 0;
+#endif
 
   // Shows the translate bubble.
   //
diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa.mm b/chrome/browser/ui/cocoa/accelerators_cocoa.mm
index fcf236f6..2bcdaecf 100644
--- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm
+++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm
@@ -9,9 +9,9 @@
 
 #include <utility>
 
+#include "base/cxx17_backports.h"
 #include "base/macros.h"
 #include "base/memory/singleton.h"
-#include "base/stl_util.h"
 #include "build/branding_buildflags.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/ui/commander/commander.h"
diff --git a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
index b995f41..dae3e78 100644
--- a/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
+++ b/chrome/browser/ui/cocoa/applescript/apple_event_util.mm
@@ -28,22 +28,18 @@
       break;
 
     case base::Value::Type::BOOLEAN: {
-      bool bool_value;
-      value->GetAsBoolean(&bool_value);
-      descriptor = [NSAppleEventDescriptor descriptorWithBoolean:bool_value];
+      descriptor =
+          [NSAppleEventDescriptor descriptorWithBoolean:value->GetBool()];
       break;
     }
 
     case base::Value::Type::INTEGER: {
-      int int_value;
-      value->GetAsInteger(&int_value);
-      descriptor = [NSAppleEventDescriptor descriptorWithInt32:int_value];
+      descriptor = [NSAppleEventDescriptor descriptorWithInt32:value->GetInt()];
       break;
     }
 
     case base::Value::Type::DOUBLE: {
-      double double_value;
-      value->GetAsDouble(&double_value);
+      double double_value = value->GetDouble();
       descriptor = [NSAppleEventDescriptor
           descriptorWithDescriptorType:typeIEEE64BitFloatingPoint
                                  bytes:&double_value
@@ -52,10 +48,8 @@
     }
 
     case base::Value::Type::STRING: {
-      std::string string_value;
-      value->GetAsString(&string_value);
-      descriptor = [NSAppleEventDescriptor descriptorWithString:
-          base::SysUTF8ToNSString(string_value)];
+      descriptor = [NSAppleEventDescriptor
+          descriptorWithString:base::SysUTF8ToNSString(value->GetString())];
       break;
     }
 
diff --git a/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm b/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm
index 8dbaeb3..becf43e 100644
--- a/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm
@@ -10,10 +10,10 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/mac/scoped_aedesc.h"
 #include "base/notreached.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
diff --git a/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
index b57c80f..cd63e6e 100644
--- a/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
+++ b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
@@ -7,8 +7,8 @@
 #include <Carbon/Carbon.h>
 #include <QuartzCore/QuartzCore.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/mac_util.h"
-#include "base/stl_util.h"
 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_controller.h"
 #include "ui/base/cocoa/appkit_utils.h"
 
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 82ce975..2fa4777 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -22,9 +22,11 @@
 #include "chrome/browser/permissions/quiet_notification_permission_ui_state.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h"
+#include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/content_settings/content_setting_image_model_states.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
@@ -35,6 +37,7 @@
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/content_settings/core/common/features.h"
 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
+#include "components/permissions/features.h"
 #include "components/permissions/permission_request_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
@@ -977,8 +980,21 @@
   auto* profile =
       Profile::FromBrowserContext(web_contents->GetBrowserContext());
 
-  if (!manager || !manager->ShouldCurrentRequestUseQuietUI())
+  // If `kPermissionQuietUIChip` is enabled, we shouldn't show the icon unless
+  // we're a PWA.
+  // TODO(crbug.com/1221189): Allow PermissionRequestManager to identify the
+  // correct UI style of a permission prompt.
+  const bool quiet_icon_allowed =
+      web_app::AppBrowserController::IsWebApp(
+          chrome::FindBrowserWithWebContents(web_contents)) ||
+      !base::FeatureList::IsEnabled(
+          permissions::features::kPermissionQuietChip);
+
+  if (!quiet_icon_allowed || !manager ||
+      !manager->ShouldCurrentRequestUseQuietUI()) {
     return false;
+  }
+
   // |manager| may be null in tests.
   // Show promo the first time a quiet prompt is shown to the user.
   set_should_show_promo(
diff --git a/chrome/browser/ui/hats/DEPS b/chrome/browser/ui/hats/DEPS
index 9e7e3fa..f207e6f 100644
--- a/chrome/browser/ui/hats/DEPS
+++ b/chrome/browser/ui/hats/DEPS
@@ -2,5 +2,9 @@
   # Allow access from test file.
   "hats_service_browsertest\.cc": [
     "+chrome/browser/ui/views/hats",
+  ],
+
+  "trust_safety_sentiment_service_browsertest\.cc": [
+    "+chrome/browser/ui/views/page_info",
   ]
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h b/chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h
index c09f49e6d..855bc3b 100644
--- a/chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h
+++ b/chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h
@@ -28,6 +28,10 @@
               (content::WebContents * web_contents),
               (override));
   MOCK_METHOD(void, RanSafetyCheck, (), (override));
+  MOCK_METHOD(void, PageInfoOpened, (), (override));
+  MOCK_METHOD(void, InteractedWithPageInfo, (), (override));
+  MOCK_METHOD(void, PageInfoClosed, (), (override));
+  MOCK_METHOD(void, SavedPassword, (), (override));
 };
 
 std::unique_ptr<KeyedService> BuildMockTrustSafetySentimentService(
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc
index 976da1f..d1902d7 100644
--- a/chrome/browser/ui/hats/trust_safety_sentiment_service.cc
+++ b/chrome/browser/ui/hats/trust_safety_sentiment_service.cc
@@ -237,6 +237,37 @@
                       profile_, /*ran_safety_check=*/true));
 }
 
+void TrustSafetySentimentService::PageInfoOpened() {
+  // Only one Page Info should ever be open.
+  DCHECK(!page_info_state_);
+  page_info_state_ = std::make_unique<PageInfoState>();
+}
+
+void TrustSafetySentimentService::InteractedWithPageInfo() {
+  DCHECK(page_info_state_);
+  page_info_state_->interacted = true;
+}
+
+void TrustSafetySentimentService::PageInfoClosed() {
+  DCHECK(page_info_state_);
+
+  // Record a trigger if either the user had page info open for the required
+  // time, or if they interacted with it.
+  if (base::Time::Now() - page_info_state_->opened_time >=
+          features::kTrustSafetySentimentSurveyTrustedSurfaceTime.Get() ||
+      page_info_state_->interacted) {
+    TriggerOccurred(
+        FeatureArea::kTrustedSurface,
+        {{"Interacted with Page Info", page_info_state_->interacted}});
+  }
+
+  page_info_state_.reset();
+}
+
+void TrustSafetySentimentService::SavedPassword() {
+  TriggerOccurred(FeatureArea::kTransactions, {{"Saved password", true}});
+}
+
 void TrustSafetySentimentService::OnOffTheRecordProfileCreated(
     Profile* off_the_record) {
   // Only interested in the primary OTR profile i.e. the one used for incognito
@@ -303,6 +334,9 @@
   std::move(complete_callback_).Run(stayed_on_settings);
 }
 
+TrustSafetySentimentService::PageInfoState::PageInfoState()
+    : opened_time(base::Time::Now()) {}
+
 void TrustSafetySentimentService::SettingsWatcherComplete(
     bool stayed_on_settings) {
   settings_watcher_.reset();
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service.h b/chrome/browser/ui/hats/trust_safety_sentiment_service.h
index cc45489..62b0072e 100644
--- a/chrome/browser/ui/hats/trust_safety_sentiment_service.h
+++ b/chrome/browser/ui/hats/trust_safety_sentiment_service.h
@@ -21,25 +21,39 @@
   explicit TrustSafetySentimentService(Profile* profile);
   ~TrustSafetySentimentService() override;
 
-  // Called to indicate to the service that the user opened an NTP. This allows
-  // the service to update its eligibility logic, and potentially show a
-  // survey. Virtual to allow mocking in tests.
+  // Called when the user opens an NTP. This allows the service to update its
+  // eligibility logic, and potentially show a survey. Virtual to allow mocking
+  // in tests.
   virtual void OpenedNewTabPage();
 
-  // Called to indicate to the service that the user has interacted with the
-  // privacy settings on chrome://settings in |web_contents|. Interaction in
-  // this context could be using a link row on the privacy settings card.
-  // Calling this allows the service to monitor |web_contents| to determine
-  // if the user stays on settings for the required time. Virtual to allow
-  // mocking in tests.
+  // Called when the user interacts with the privacy settings on
+  // chrome://settings in |web_contents|. Interaction in this context could be
+  // using a link row on the privacy settings card. Calling this allows the
+  // service to monitor |web_contents| to determine if the user stays on
+  // settings for the required time. Virtual to allow mocking in tests.
   virtual void InteractedWithPrivacySettings(
       content::WebContents* web_contents);
 
-  // Called to indicate to the service that the user has run safety check. This
-  // is immediately considered as a trigger action. Virtual to allow mocking in
-  // tests.
+  // Called when the user runs safety check. This is immediately considered as a
+  // trigger action. Virtual to allow mocking in tests.
   virtual void RanSafetyCheck();
 
+  // Called when the user opens Page Info.
+  virtual void PageInfoOpened();
+
+  // Called when the user interacts in some way with Page Info.
+  virtual void InteractedWithPageInfo();
+
+  // Called when the user saves a password via the manage passwords UI. This is
+  // the native UI shown when Chrome detects a password has been entered into
+  // the web page.
+  virtual void SavedPassword();
+
+  // Called when the user closes Page Info. If Page Info was opened for the
+  // target time, or the user interacted with it while it was open, a trigger
+  // action is recorded.
+  virtual void PageInfoClosed();
+
   // Profile Observer:
   void OnOffTheRecordProfileCreated(Profile* off_the_record) override;
   void OnProfileWillBeDestroyed(Profile* profile) override;
@@ -107,6 +121,13 @@
     base::WeakPtrFactory<SettingsWatcher> weak_ptr_factory_{this};
   };
 
+  // Struct which represents the PageInfo state of interest to the service.
+  struct PageInfoState {
+    PageInfoState();
+    base::Time opened_time;
+    bool interacted = false;
+  };
+
   void SettingsWatcherComplete(bool stayed_on_settings);
 
   // Record that a trigger occurred, placing it in the set of pending triggers.
@@ -127,6 +148,7 @@
   Profile* const profile_;
   std::map<FeatureArea, PendingTrigger> pending_triggers_;
   std::unique_ptr<SettingsWatcher> settings_watcher_;
+  std::unique_ptr<PageInfoState> page_info_state_;
   base::ScopedMultiSourceObservation<Profile, ProfileObserver>
       observed_profiles_{this};
   base::WeakPtrFactory<TrustSafetySentimentService> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service_browsertest.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service_browsertest.cc
new file mode 100644
index 0000000..b9c33c6
--- /dev/null
+++ b/chrome/browser/ui/hats/trust_safety_sentiment_service_browsertest.cc
@@ -0,0 +1,152 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service.h"
+
+#include "base/time/time_override.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
+#include "chrome/browser/ui/hats/mock_hats_service.h"
+#include "chrome/browser/ui/page_info/page_info_dialog.h"
+#include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/browser_test.h"
+
+class TrustSafetySentimentServiceBrowserTest : public InProcessBrowserTest {
+ public:
+  TrustSafetySentimentServiceBrowserTest() {
+    feature_list_.InitAndEnableFeatureWithParameters(
+        features::kTrustSafetySentimentSurvey,
+        {{"trusted-surface-probability", "1.0"}});
+  }
+
+  void SetUpOnMainThread() override {
+    mock_hats_service_ = static_cast<MockHatsService*>(
+        HatsServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+            browser()->profile(), base::BindRepeating(&BuildMockHatsService)));
+    EXPECT_CALL(*mock_hats_service_, CanShowAnySurvey(testing::_))
+        .WillRepeatedly(testing::Return(true));
+  }
+
+  void OpenPageInfo() {
+    ShowPageInfoDialog(browser()->tab_strip_model()->GetActiveWebContents(),
+                       base::DoNothing());
+  }
+
+  void ClosePageInfo() {
+    PageInfoBubbleView::GetPageInfoBubbleForTesting()
+        ->GetWidget()
+        ->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
+    base::RunLoop().RunUntilIdle();
+  }
+
+  void ChangePermission() {
+    PageInfo::PermissionInfo permission;
+    permission.type = ContentSettingsType::NOTIFICATIONS;
+    permission.setting = ContentSetting::CONTENT_SETTING_BLOCK;
+    permission.default_setting = ContentSetting::CONTENT_SETTING_ASK;
+    permission.source = content_settings::SettingSource::SETTING_SOURCE_USER;
+
+    static_cast<PageInfoBubbleView*>(
+        PageInfoBubbleView::GetPageInfoBubbleForTesting())
+        ->OnPermissionChanged(permission);
+  }
+
+  void OpenEnoughNewTabs() {
+    for (int i = 0;
+         i < features::kTrustSafetySentimentSurveyNtpVisitsMaxRange.Get();
+         i++) {
+      ui_test_utils::NavigateToURLWithDisposition(
+          browser(), GURL(chrome::kChromeUINewTabURL),
+          WindowOpenDisposition::NEW_FOREGROUND_TAB,
+          ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+    }
+  }
+
+ protected:
+  base::test::ScopedFeatureList feature_list_;
+  MockHatsService* mock_hats_service_;
+};
+
+IN_PROC_BROWSER_TEST_F(TrustSafetySentimentServiceBrowserTest,
+                       PageInfoTriggersSurvey_NoInteraction) {
+  // Check that after opening Page Info for the required time, then performing
+  // the required eligibility actions, a survey is requested from the HaTS
+  // service.
+  std::map<std::string, bool> expected_product_specific_data = {
+      {"Interacted with Page Info", false}};
+  EXPECT_CALL(
+      *mock_hats_service_,
+      LaunchSurvey(kHatsSurveyTriggerTrustSafetyTrustedSurface, testing::_,
+                   testing::_, expected_product_specific_data));
+  {
+    base::subtle::ScopedTimeClockOverrides override(
+        []() {
+          return base::subtle::TimeNowIgnoringOverride().LocalMidnight();
+        },
+        nullptr, nullptr);
+    OpenPageInfo();
+  }
+
+  // Wait for the required time before closing.
+  {
+    base::subtle::ScopedTimeClockOverrides override(
+        []() {
+          return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
+                 features::kTrustSafetySentimentSurveyTrustedSurfaceTime.Get();
+        },
+        nullptr, nullptr);
+    ClosePageInfo();
+  }
+
+  // Open the maximum number of required tabs, after waiting for the minimum
+  // prompt time.
+  {
+    base::subtle::ScopedTimeClockOverrides override(
+        []() {
+          return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
+                 features::kTrustSafetySentimentSurveyTrustedSurfaceTime.Get() +
+                 features::kTrustSafetySentimentSurveyMinTimeToPrompt.Get();
+        },
+        nullptr, nullptr);
+    OpenEnoughNewTabs();
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(TrustSafetySentimentServiceBrowserTest,
+                       PageInfoTriggersSurvey_Interaction) {
+  // Check that interacting with page info (through a reported change to
+  // permissions in this instance) removes the time requirement, and also
+  // changes the product specific data accordingly.
+  std::map<std::string, bool> expected_product_specific_data = {
+      {"Interacted with Page Info", true}};
+  EXPECT_CALL(
+      *mock_hats_service_,
+      LaunchSurvey(kHatsSurveyTriggerTrustSafetyTrustedSurface, testing::_,
+                   testing::_, expected_product_specific_data));
+
+  {
+    base::subtle::ScopedTimeClockOverrides override(
+        []() {
+          return base::subtle::TimeNowIgnoringOverride().LocalMidnight();
+        },
+        nullptr, nullptr);
+    OpenPageInfo();
+    ChangePermission();
+    ClosePageInfo();
+  }
+
+  {
+    base::subtle::ScopedTimeClockOverrides override(
+        []() {
+          return base::subtle::TimeNowIgnoringOverride().LocalMidnight() +
+                 features::kTrustSafetySentimentSurveyMinTimeToPrompt.Get();
+        },
+        nullptr, nullptr);
+    OpenEnoughNewTabs();
+  }
+}
diff --git a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc
index 1333d8c..c243454 100644
--- a/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc
+++ b/chrome/browser/ui/hats/trust_safety_sentiment_service_unittest.cc
@@ -273,6 +273,25 @@
   service()->OpenedNewTabPage();
 }
 
+TEST_F(TrustSafetySentimentServiceTest, SavedPassword) {
+  // Saving a password is considered a trigger, and should make a user eligible
+  // to receive a survey.
+  FeatureParams params;
+  params.transactions_probability = "1.0";
+  params.min_time_to_prompt = "0s";
+  params.ntp_visits_min_range = "0";
+  params.ntp_visits_max_range = "0";
+  SetupFeatureParameters(params);
+
+  std::map<std::string, bool> expected_psd = {{"Saved password", true}};
+
+  EXPECT_CALL(*mock_hats_service(),
+              LaunchSurvey(kHatsSurveyTriggerTrustSafetyTransactions,
+                           testing::_, testing::_, expected_psd));
+  service()->SavedPassword();
+  service()->OpenedNewTabPage();
+}
+
 TEST_F(TrustSafetySentimentServiceTest, PrivacySettingsProductSpecificData) {
   // Check the product specific data accompanying surveys for the Privacy
   // Settings feature area correctly records whether the user has a non default
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
index edd788e..357be14 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.cc
@@ -16,6 +16,12 @@
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "url/gurl.h"
 
+#if !defined(OS_ANDROID)
+#include "chrome/browser/extensions/window_controller_list.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#endif
+
 ChromePageInfoUiDelegate::ChromePageInfoUiDelegate(Profile* profile,
                                                    const GURL& site_url)
     : profile_(profile), site_url_(site_url) {}
@@ -46,18 +52,37 @@
   }
 }
 
-bool ChromePageInfoUiDelegate::ShouldShowAsk(ContentSettingsType type) {
+std::u16string ChromePageInfoUiDelegate::GetAutomaticallyBlockedReason(
+    ContentSettingsType type) {
   switch (type) {
-    case ContentSettingsType::USB_GUARD:
-    case ContentSettingsType::SERIAL_GUARD:
-    case ContentSettingsType::BLUETOOTH_GUARD:
-    case ContentSettingsType::BLUETOOTH_SCANNING:
-    case ContentSettingsType::FILE_SYSTEM_WRITE_GUARD:
-    case ContentSettingsType::HID_GUARD:
-      return true;
+    // Notifications and idle detection do not support CONTENT_SETTING_ALLOW in
+    // incognito.
+    case ContentSettingsType::NOTIFICATIONS:
+    case ContentSettingsType::IDLE_DETECTION: {
+      if (profile_->IsOffTheRecord()) {
+        // TODO(crbug.com/1225563): Replace with actual strings.
+        return u"Not allowed in Incognito";
+      }
+      break;
+    }
+    // Media only supports CONTENT_SETTING_ALLOW for secure origins.
+    case ContentSettingsType::MEDIASTREAM_MIC:
+    case ContentSettingsType::MEDIASTREAM_CAMERA: {
+      if (!network::IsUrlPotentiallyTrustworthy(site_url_)) {
+        // TODO(crbug.com/1225563): Replace with actual strings.
+        return u"Not allowed on non-secure connections";
+      }
+      break;
+    }
     default:
-      return false;
+      break;
   }
+
+  return std::u16string();
+}
+
+bool ChromePageInfoUiDelegate::ShouldShowAsk(ContentSettingsType type) {
+  return permissions::PermissionUtil::IsGuardContentSetting(type);
 }
 
 #if !defined(OS_ANDROID)
@@ -65,6 +90,28 @@
   return !profile_->IsGuestSession();
 }
 
+// TODO(crbug.com/1227074): Reconcile with LastTabStandingTracker.
+bool ChromePageInfoUiDelegate::IsMultipleTabsOpen() {
+  const extensions::WindowControllerList::ControllerList& windows =
+      extensions::WindowControllerList::GetInstance()->windows();
+  int count = 0;
+  auto site_origin = site_url_.GetOrigin();
+  for (auto* window : windows) {
+    const Browser* const browser = window->GetBrowser();
+    if (!browser)
+      continue;
+    const TabStripModel* const tabs = browser->tab_strip_model();
+    DCHECK(tabs);
+    for (int i = 0; i < tabs->count(); ++i) {
+      content::WebContents* const web_contents = tabs->GetWebContentsAt(i);
+      if (web_contents->GetURL().GetOrigin() == site_origin) {
+        count++;
+      }
+    }
+  }
+  return count > 1;
+}
+
 std::u16string ChromePageInfoUiDelegate::GetPermissionDetail(
     ContentSettingsType type) {
   return content_settings::GetPermissionDetailString(profile_, type, site_url_);
diff --git a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
index c0f9bea..2213efe 100644
--- a/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
+++ b/chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h
@@ -25,6 +25,9 @@
   // Whether the combobox option to ask a permission should be shown for `type`.
   bool ShouldShowAsk(ContentSettingsType type);
 
+  // If "allow" option is not available, return the reason why.
+  std::u16string GetAutomaticallyBlockedReason(ContentSettingsType type);
+
 #if !defined(OS_ANDROID)
   // Whether to show a link that takes the user to the chrome://settings subpage
   // for `site_url_`.
@@ -36,6 +39,7 @@
 
   // PageInfoUiDelegate implementation
   bool IsBlockAutoPlayEnabled() override;
+  bool IsMultipleTabsOpen() override;
 #endif  // !defined(OS_ANDROID)
   permissions::PermissionResult GetPermissionStatus(
       ContentSettingsType type) override;
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 0c5547e..18c179b 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -38,6 +38,7 @@
 #include "components/infobars/core/infobar.h"
 #include "components/page_info/features.h"
 #include "components/page_info/page_info_ui.h"
+#include "components/permissions/features.h"
 #include "components/safe_browsing/buildflags.h"
 #include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
 #include "components/security_state/core/features.h"
@@ -1500,3 +1501,282 @@
 }
 
 #endif  // !defined(OS_ANDROID)
+
+// Unit tests for logic in the PageInfoUI that toggles permission between
+// allow/block and remember/forget.
+class PageInfoToggleStatesUnitTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        permissions::features::kOneTimeGeolocationPermission);
+    ::testing::Test::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// Testing all possible state transitions for a permission that doesn't
+// support allow once.
+TEST_F(PageInfoToggleStatesUnitTest,
+       TogglePermissionWithoutAllowOnceDefaultAskTest) {
+  PageInfo::PermissionInfo camera_permission;
+  camera_permission.type = ContentSettingsType::MEDIASTREAM_CAMERA;
+  camera_permission.setting = CONTENT_SETTING_ALLOW;
+  camera_permission.default_setting = CONTENT_SETTING_ASK;
+  camera_permission.source = content_settings::SETTING_SOURCE_USER;
+  camera_permission.is_one_time = false;
+
+  // Allow -> Block
+  PageInfoUI::ToggleBetweenAllowAndBlock(camera_permission);
+  EXPECT_EQ(camera_permission.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Allow
+  PageInfoUI::ToggleBetweenAllowAndBlock(camera_permission);
+  EXPECT_EQ(camera_permission.setting, CONTENT_SETTING_ALLOW);
+}
+
+TEST_F(PageInfoToggleStatesUnitTest,
+       TogglePermissionWithoutAllowOnceDefaultBlockTest) {
+  PageInfo::PermissionInfo camera_permission;
+  camera_permission.type = ContentSettingsType::MEDIASTREAM_CAMERA;
+  camera_permission.setting = CONTENT_SETTING_ALLOW;
+  camera_permission.default_setting = CONTENT_SETTING_BLOCK;
+  camera_permission.source = content_settings::SETTING_SOURCE_USER;
+  camera_permission.is_one_time = false;
+
+  // Allow -> Block (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(camera_permission);
+  EXPECT_EQ(camera_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Block (default) -> Allow
+  PageInfoUI::ToggleBetweenAllowAndBlock(camera_permission);
+  EXPECT_EQ(camera_permission.setting, CONTENT_SETTING_ALLOW);
+
+  // Block -> Allow
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  camera_permission.setting = CONTENT_SETTING_BLOCK;
+  PageInfoUI::ToggleBetweenAllowAndBlock(camera_permission);
+  EXPECT_EQ(camera_permission.setting, CONTENT_SETTING_ALLOW);
+}
+
+// Testing all possible state transitions for a permission that supports
+// allow once and default setting ask.
+TEST_F(PageInfoToggleStatesUnitTest,
+       TogglePermissionWithAllowOnceDefaultAskTest) {
+  PageInfo::PermissionInfo location_permission;
+  location_permission.type = ContentSettingsType::GEOLOCATION;
+  location_permission.setting = CONTENT_SETTING_ALLOW;
+  location_permission.default_setting = CONTENT_SETTING_ASK;
+  location_permission.source = content_settings::SETTING_SOURCE_USER;
+  location_permission.is_one_time = false;
+
+  // Allow -> Block
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Allow
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+
+  // Allow -> Allow once
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, true);
+
+  // Allow once -> Allow
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, false);
+
+  // Allow -> Block
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Default
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Default -> Block
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Default
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Default -> Allow once
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, true);
+
+  // Allow once -> Default
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+  EXPECT_EQ(location_permission.is_one_time, false);
+}
+
+// Testing all possible state transitions for a permission that supports
+// allow once and default setting block.
+TEST_F(PageInfoToggleStatesUnitTest,
+       TogglePermissionWithAllowOnceDefaultBlockTest) {
+  PageInfo::PermissionInfo location_permission;
+  location_permission.type = ContentSettingsType::GEOLOCATION;
+  location_permission.setting = CONTENT_SETTING_ALLOW;
+  location_permission.default_setting = CONTENT_SETTING_BLOCK;
+  location_permission.source = content_settings::SETTING_SOURCE_USER;
+  location_permission.is_one_time = false;
+
+  // If the default setting matches target setting, no site exception will be
+  // created and permission will be in the default state.
+  // Allow -> Block (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Block (default) -> Allow once
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, true);
+
+  // Allow once -> Allow
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, false);
+
+  // Allow -> Allow once
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(location_permission.is_one_time, true);
+
+  // Allow once -> Block (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+  EXPECT_EQ(location_permission.is_one_time, false);
+
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  // Block -> Allow
+  location_permission.setting = CONTENT_SETTING_BLOCK;
+  PageInfoUI::ToggleBetweenAllowAndBlock(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_ALLOW);
+  // Block -> Block (default)
+  location_permission.setting = CONTENT_SETTING_BLOCK;
+  PageInfoUI::ToggleBetweenRememberAndForget(location_permission);
+  EXPECT_EQ(location_permission.setting, CONTENT_SETTING_DEFAULT);
+}
+
+// Testing all possible state transitions for a content settings with a default
+// setting allow.
+TEST_F(PageInfoToggleStatesUnitTest, TogglePermissionDefaultAllowTest) {
+  PageInfo::PermissionInfo images_permission;
+  images_permission.type = ContentSettingsType::IMAGES;
+  images_permission.setting = CONTENT_SETTING_DEFAULT;
+  images_permission.default_setting = CONTENT_SETTING_ALLOW;
+  images_permission.source = content_settings::SETTING_SOURCE_USER;
+  images_permission.is_one_time = false;
+
+  // Allow (default) -> Block
+  PageInfoUI::ToggleBetweenAllowAndBlock(images_permission);
+  EXPECT_EQ(images_permission.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Allow (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(images_permission);
+  EXPECT_EQ(images_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Allow -> Block
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  images_permission.setting = CONTENT_SETTING_ALLOW;
+  PageInfoUI::ToggleBetweenAllowAndBlock(images_permission);
+  EXPECT_EQ(images_permission.setting, CONTENT_SETTING_BLOCK);
+}
+
+// Testing all possible state transitions for a content settings with a default
+// setting block.
+TEST_F(PageInfoToggleStatesUnitTest, TogglePermissionDefaultBlockTest) {
+  PageInfo::PermissionInfo popups_permission;
+  popups_permission.type = ContentSettingsType::POPUPS;
+  popups_permission.setting = CONTENT_SETTING_DEFAULT;
+  popups_permission.default_setting = CONTENT_SETTING_BLOCK;
+  popups_permission.source = content_settings::SETTING_SOURCE_USER;
+  popups_permission.is_one_time = false;
+
+  // Block (default) -> Allow
+  PageInfoUI::ToggleBetweenAllowAndBlock(popups_permission);
+  EXPECT_EQ(popups_permission.setting, CONTENT_SETTING_ALLOW);
+
+  // Allow -> Block (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(popups_permission);
+  EXPECT_EQ(popups_permission.setting, CONTENT_SETTING_DEFAULT);
+
+  // Block -> Allow
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  popups_permission.setting = CONTENT_SETTING_BLOCK;
+  PageInfoUI::ToggleBetweenAllowAndBlock(popups_permission);
+  EXPECT_EQ(popups_permission.setting, CONTENT_SETTING_ALLOW);
+}
+
+// TODO(olesiamarukhno): Add test for guard content setting for
+// chooser-based permissions (ex. ContentSettingsType::USB_GUARD for
+// ContentSettingsType::USB_CHOOSER_DATA). Guard content settings support only
+// ask and block state, don't support allow.
+
+// Testing all possible state transitions for a guard content settings with a
+// default setting ask.
+TEST_F(PageInfoToggleStatesUnitTest, ToggleGuardPermissionDefaultAskTest) {
+  PageInfo::PermissionInfo usb_guard;
+  usb_guard.type = ContentSettingsType::USB_GUARD;
+  usb_guard.setting = CONTENT_SETTING_DEFAULT;
+  usb_guard.default_setting = CONTENT_SETTING_ASK;
+  usb_guard.source = content_settings::SETTING_SOURCE_USER;
+  usb_guard.is_one_time = false;
+
+  // Ask (default) -> Block
+  PageInfoUI::ToggleBetweenAllowAndBlock(usb_guard);
+  EXPECT_EQ(usb_guard.setting, CONTENT_SETTING_BLOCK);
+
+  // Block -> Ask (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(usb_guard);
+  EXPECT_EQ(usb_guard.setting, CONTENT_SETTING_DEFAULT);
+
+  // Ask -> Block
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  usb_guard.setting = CONTENT_SETTING_ASK;
+  PageInfoUI::ToggleBetweenAllowAndBlock(usb_guard);
+  EXPECT_EQ(usb_guard.setting, CONTENT_SETTING_BLOCK);
+}
+
+// Testing all possible state transitions for a guard content settings with a
+// default setting block.
+TEST_F(PageInfoToggleStatesUnitTest, ToggleGuardPermissionDefaultBlockTest) {
+  PageInfo::PermissionInfo hid_guard;
+  hid_guard.type = ContentSettingsType::HID_GUARD;
+  hid_guard.setting = CONTENT_SETTING_DEFAULT;
+  hid_guard.default_setting = CONTENT_SETTING_BLOCK;
+  hid_guard.source = content_settings::SETTING_SOURCE_USER;
+  hid_guard.is_one_time = false;
+
+  // Block (default) -> Ask
+  PageInfoUI::ToggleBetweenAllowAndBlock(hid_guard);
+  EXPECT_EQ(hid_guard.setting, CONTENT_SETTING_ASK);
+
+  // Ask -> Block (default)
+  PageInfoUI::ToggleBetweenAllowAndBlock(hid_guard);
+  EXPECT_EQ(hid_guard.setting, CONTENT_SETTING_DEFAULT);
+
+  // Block -> Ask
+  // If there is a site exception created, that matches the default setting,
+  // permission setting still will be toggled to the opposite but there won't
+  // be an option to recreate the site setting.
+  hid_guard.setting = CONTENT_SETTING_BLOCK;
+  PageInfoUI::ToggleBetweenAllowAndBlock(hid_guard);
+  EXPECT_EQ(hid_guard.setting, CONTENT_SETTING_ASK);
+}
diff --git a/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller_unittest.cc b/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller_unittest.cc
index 03e6f14..127bddb 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/save_update_bubble_controller_unittest.cc
@@ -19,6 +19,8 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/test_signin_client_builder.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h"
 #include "chrome/test/base/testing_profile.h"
@@ -77,14 +79,20 @@
   ~SaveUpdateBubbleControllerTest() override = default;
 
   void SetUp() override {
-    test_web_contents_ =
-        content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
+    TestingProfile::Builder profile_builder;
+    profile_builder.AddTestingFactory(
+        ChromeSigninClientFactory::GetInstance(),
+        base::BindRepeating(&signin::BuildTestSigninClient));
+    profile_builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
+                                      SyncServiceFactory::GetDefaultFactory());
+    profile_ = profile_builder.Build();
+
+    test_web_contents_ = content::WebContentsTester::CreateTestWebContents(
+        profile_.get(), nullptr);
     mock_delegate_ =
         std::make_unique<testing::NiceMock<PasswordsModelDelegateMock>>();
     ON_CALL(*mock_delegate_, GetPasswordFormMetricsRecorder())
         .WillByDefault(Return(nullptr));
-    SyncServiceFactory::GetInstance()->SetTestingFactory(
-        profile(), SyncServiceFactory::GetDefaultFactory());
     PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
         profile(),
         base::BindRepeating(
@@ -103,9 +111,9 @@
     controller_.reset();
   }
 
-  PrefService* prefs() { return profile_.GetPrefs(); }
+  PrefService* prefs() { return profile_->GetPrefs(); }
 
-  TestingProfile* profile() { return &profile_; }
+  TestingProfile* profile() { return profile_.get(); }
 
   password_manager::MockPasswordStore* GetStore() {
     return static_cast<password_manager::MockPasswordStore*>(
@@ -144,7 +152,7 @@
   base::test::ScopedFeatureList feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   content::RenderViewHostTestEnabler rvh_enabler_;
-  TestingProfile profile_;
+  std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<content::WebContents> test_web_contents_;
   std::unique_ptr<SaveUpdateBubbleController> controller_;
   std::unique_ptr<PasswordsModelDelegateMock> mock_delegate_;
diff --git a/chrome/browser/ui/passwords/manage_passwords_test.cc b/chrome/browser/ui/passwords/manage_passwords_test.cc
index 9a9b3fb2..220af78d 100644
--- a/chrome/browser/ui/passwords/manage_passwords_test.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_test.cc
@@ -52,6 +52,9 @@
   password_form_.url = GURL(kTestOrigin);
   password_form_.username_value = kTestUsername;
   password_form_.password_value = u"test_password";
+  password_form_.password_issues =
+      base::flat_map<password_manager::InsecureType,
+                     password_manager::InsecurityMetadata>();
 
   federated_form_.signon_realm =
       "federation://example.com/somelongeroriginurl.com";
@@ -137,6 +140,10 @@
       password_manager::prefs::kLastTimePasswordCheckCompleted,
       (base::Time::Now() - base::TimeDelta::FromMinutes(1)).ToDoubleT());
   SetupPendingPassword();
+  scoped_refptr<password_manager::PasswordStore> password_store =
+      PasswordStoreFactory::GetForProfile(browser()->profile(),
+                                          ServiceAccessType::IMPLICIT_ACCESS);
+  password_store->AddLogin(password_form_);
   GetController()->SavePassword(password_form_.username_value,
                                 password_form_.password_value);
   GetController()->OnBubbleHidden();
@@ -154,11 +161,12 @@
       PasswordStoreFactory::GetForProfile(browser()->profile(),
                                           ServiceAccessType::IMPLICIT_ACCESS);
   // This is an unrelated insecure credential that should still be fixed.
-  password_manager::InsecureCredential credential(
-      "https://somesite.com/", kTestUsername, base::Time(),
-      password_manager::InsecureType::kLeaked,
-      password_manager::IsMuted(false));
-  password_store->AddInsecureCredential(credential);
+  password_manager::PasswordForm to_be_fixed = password_form_;
+  to_be_fixed.signon_realm = "https://somesite.com/";
+  to_be_fixed.password_issues->insert({password_manager::InsecureType::kLeaked,
+                                       password_manager::InsecurityMetadata()});
+  password_store->AddLogin(to_be_fixed);
+  password_store->AddLogin(password_form_);
   SetupPendingPassword();
   GetController()->SavePassword(password_form_.username_value,
                                 password_form_.password_value);
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index ec2ae1a..0aba6d6 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -25,6 +25,8 @@
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
 #include "chrome/browser/ui/location_bar/location_bar.h"
 #include "chrome/browser/ui/page_action/page_action_icon_type.h"
 #include "chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.h"
@@ -66,7 +68,7 @@
 
 namespace {
 
-password_manager::PasswordStore* GetProfilePasswordStore(
+password_manager::PasswordStoreInterface* GetProfilePasswordStore(
     content::WebContents* web_contents) {
   return PasswordStoreFactory::GetForProfile(
              Profile::FromBrowserContext(web_contents->GetBrowserContext()),
@@ -74,7 +76,7 @@
       .get();
 }
 
-password_manager::PasswordStore* GetAccountPasswordStore(
+password_manager::PasswordStoreInterface* GetAccountPasswordStore(
     content::WebContents* web_contents) {
   return AccountPasswordStoreFactory::GetForProfile(
              Profile::FromBrowserContext(web_contents->GetBrowserContext()),
@@ -109,11 +111,11 @@
       are_passwords_revealed_when_next_bubble_is_opened_(false) {
   passwords_data_.set_client(
       ChromePasswordManagerClient::FromWebContents(web_contents));
-  password_manager::PasswordStore* profile_password_store =
+  password_manager::PasswordStoreInterface* profile_password_store =
       GetProfilePasswordStore(web_contents);
   if (profile_password_store)
     profile_password_store->AddObserver(this);
-  password_manager::PasswordStore* account_password_store =
+  password_manager::PasswordStoreInterface* account_password_store =
       GetAccountPasswordStore(web_contents);
   if (account_password_store)
     account_password_store->AddObserver(this);
@@ -503,6 +505,13 @@
   UpdatePasswordFormUsernameAndPassword(username, password,
                                         passwords_data_.form_manager());
 
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(
+              Profile::FromBrowserContext(
+                  web_contents()->GetBrowserContext()))) {
+    sentiment_service->SavedPassword();
+  }
+
   if (GetPasswordFormMetricsRecorder() && BubbleIsManualFallbackForSaving()) {
     GetPasswordFormMetricsRecorder()->RecordDetailedUserAction(
         password_manager::PasswordFormMetricsRecorder::DetailedUserAction::
@@ -790,11 +799,11 @@
 }
 
 void ManagePasswordsUIController::WebContentsDestroyed() {
-  password_manager::PasswordStore* profile_password_store =
+  password_manager::PasswordStoreInterface* profile_password_store =
       GetProfilePasswordStore(web_contents());
   if (profile_password_store)
     profile_password_store->RemoveObserver(this);
-  password_manager::PasswordStore* account_password_store =
+  password_manager::PasswordStoreInterface* account_password_store =
       GetAccountPasswordStore(web_contents());
   if (account_password_store)
     account_password_store->RemoveObserver(this);
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
index 5fa84ce6..ecc266a 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
 #include "chrome/common/buildflags.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
-#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/password_store_interface.h"
 #include "components/password_manager/core/browser/ui/post_save_compromised_helper.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 71b50e8..bce78b6a 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -17,6 +17,8 @@
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
+#include "chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
 #include "chrome/browser/ui/passwords/credential_leak_dialog_controller.h"
 #include "chrome/browser/ui/passwords/credential_manager_dialog_controller.h"
 #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h"
@@ -53,6 +55,9 @@
 using password_manager::PasswordForm;
 using ReauthSucceeded =
     password_manager::PasswordManagerClient::ReauthSucceeded;
+using InsecureType = password_manager::InsecureType;
+using password_manager::InsecurityMetadata;
+using password_manager::PasswordForm;
 using ::testing::_;
 using ::testing::AtLeast;
 using ::testing::AtMost;
@@ -272,6 +277,8 @@
   test_local_form_.username_element = u"username_element";
   test_local_form_.password_value = u"12345";
   test_local_form_.password_element = u"password_element";
+  test_local_form_.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
 
   test_federated_form_.url = GURL("http://example.com/login");
   test_federated_form_.signon_realm =
@@ -279,6 +286,11 @@
   test_federated_form_.username_value = u"username";
   test_federated_form_.federation_origin =
       url::Origin::Create(GURL("https://federation.test/"));
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  test_federated_form_.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
 
   submitted_form_ = test_local_form_;
   submitted_form_.username_value = u"submitted_username";
@@ -476,6 +488,13 @@
 }
 
 TEST_F(ManagePasswordsUIControllerTest, PasswordSaved) {
+  auto* mock_sentiment_service_ = static_cast<MockTrustSafetySentimentService*>(
+      TrustSafetySentimentServiceFactory::GetInstance()
+          ->SetTestingFactoryAndUse(
+              profile(),
+              base::BindRepeating(&BuildMockTrustSafetySentimentService)));
+  EXPECT_CALL(*mock_sentiment_service_, SavedPassword());
+
   std::vector<const PasswordForm*> best_matches;
   auto test_form_manager = CreateFormManagerWithBestMatches(&best_matches);
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
@@ -1532,16 +1551,22 @@
   // password not anymore.
   EXPECT_CALL(*test_form_manager_raw, GetInsecureCredentials())
       .WillOnce(Return(saved));
+  password_manager::PasswordStoreConsumer* post_save_helper = nullptr;
+
+  EXPECT_CALL(*client().GetProfilePasswordStore(), GetAutofillableLogins)
+      .WillOnce(testing::WithArg<0>([&post_save_helper](auto* consumer) {
+        post_save_helper = consumer;
+      }));
   controller()->SavePassword(submitted_form().username_value,
                              submitted_form().password_value);
   // The bubble gets hidden after the user clicks on save.
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnBubbleHidden();
-  saved = {};
-  EXPECT_CALL(*client().GetProfilePasswordStore(),
-              GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+
+  std::vector<std::unique_ptr<PasswordForm>> results;
+  results.push_back(std::make_unique<PasswordForm>(submitted_form()));
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
+  post_save_helper->OnGetPasswordStoreResults(std::move(results));
   WaitForPasswordStore();
 
   EXPECT_TRUE(controller()->opened_automatic_bubble());
@@ -1563,22 +1588,36 @@
   controller()->OnPasswordSubmitted(std::move(test_form_manager));
 
   EXPECT_CALL(*test_form_manager_raw, Save());
+  // Pretend that the current credential was insecure.
   std::vector<InsecureCredential> saved = {
       CreateInsecureCredential(test_local_form())};
-  // Pretend that the current credential was insecure.
   EXPECT_CALL(*test_form_manager_raw, GetInsecureCredentials())
       .WillOnce(Return(saved));
+
+  password_manager::PasswordStoreConsumer* post_save_helper = nullptr;
+
+  EXPECT_CALL(*client().GetProfilePasswordStore(), GetAutofillableLogins)
+      .WillOnce(testing::WithArg<0>([&post_save_helper](auto* consumer) {
+        post_save_helper = consumer;
+      }));
   controller()->SavePassword(submitted_form().username_value,
                              submitted_form().password_value);
+  // There are more insecure credentials to fix.
+  std::vector<PasswordForm> expected_forms = {test_local_form(),
+                                              submitted_form()};
+  expected_forms.at(0).username_value = u"another username";
+  expected_forms.at(0).password_issues->insert(
+      {InsecureType::kLeaked, InsecurityMetadata()});
+  expected_forms.at(1).password_issues->clear();
+  std::vector<std::unique_ptr<PasswordForm>> results;
+  for (const auto& form : expected_forms) {
+    results.push_back(std::make_unique<PasswordForm>(form));
+  }
   // The bubble gets hidden after the user clicks on save.
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
   controller()->OnBubbleHidden();
-  // There are more insecure credentials to fix.
-  saved[0].username = u"another username";
-  EXPECT_CALL(*client().GetProfilePasswordStore(),
-              GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
   EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
+  post_save_helper->OnGetPasswordStoreResults(std::move(results));
   WaitForPasswordStore();
 
   EXPECT_TRUE(controller()->opened_automatic_bubble());
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
index be1a749..120fc9c 100644
--- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
+++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.cc
@@ -6,7 +6,6 @@
 
 #include "base/logging.h"
 #include "chrome/browser/password_manager/affiliation_service_factory.h"
-#include "chrome/browser/password_manager/change_password_url_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/webui_url_constants.h"
@@ -111,20 +110,12 @@
   if (!handle->IsInPrimaryMainFrame())
     return;
 
-  if (base::FeatureList::IsEnabled(
-          password_manager::features::kChangePasswordAffiliationInfo)) {
-    affiliation_service_ =
-        AffiliationServiceFactory::GetForProfile(Profile::FromBrowserContext(
-            handle->GetWebContents()->GetBrowserContext()));
-    if (affiliation_service_->GetChangePasswordURL(request_url_).is_empty()) {
-      well_known_change_password_state_.PrefetchChangePasswordURLs(
-          affiliation_service_, {request_url_});
-    }
-  } else {
-    change_password_url_service_ =
-        ChangePasswordUrlServiceFactory::GetForBrowserContext(
-            handle->GetWebContents()->GetBrowserContext());
-    change_password_url_service_->PrefetchURLs();
+  affiliation_service_ =
+      AffiliationServiceFactory::GetForProfile(Profile::FromBrowserContext(
+          handle->GetWebContents()->GetBrowserContext()));
+  if (affiliation_service_->GetChangePasswordURL(request_url_).is_empty()) {
+    well_known_change_password_state_.PrefetchChangePasswordURLs(
+        affiliation_service_, {request_url_});
   }
 }
 
@@ -193,14 +184,8 @@
     Resume();
     return;
   }
-  GURL redirect_url;
-  if (base::FeatureList::IsEnabled(
-          password_manager::features::kChangePasswordAffiliationInfo)) {
-    redirect_url = affiliation_service_->GetChangePasswordURL(request_url_);
-  } else {
-    redirect_url =
-        change_password_url_service_->GetChangePasswordUrl(request_url_);
-  }
+  GURL redirect_url = affiliation_service_->GetChangePasswordURL(request_url_);
+
   if (redirect_url.is_valid()) {
     RecordMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
     Redirect(redirect_url);
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h
index 85c19cc..3cf4abb 100644
--- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h
+++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h
@@ -20,7 +20,6 @@
 
 namespace password_manager {
 class AffiliationService;
-class ChangePasswordUrlService;
 }  // namespace password_manager
 
 // This NavigationThrottle checks whether a site supports the
@@ -65,8 +64,6 @@
   password_manager::WellKnownChangePasswordState
       well_known_change_password_state_{this};
   ukm::SourceId source_id_ = ukm::kInvalidSourceId;
-  password_manager::ChangePasswordUrlService* change_password_url_service_ =
-      nullptr;
   password_manager::AffiliationService* affiliation_service_ = nullptr;
 };
 
diff --git a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc
index 894e7659..4e82097 100644
--- a/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc
+++ b/chrome/browser/ui/passwords/well_known_change_password_navigation_throttle_browsertest.cc
@@ -85,11 +85,14 @@
 
 }  // namespace
 
-class MockChangePasswordUrlService
-    : public password_manager::ChangePasswordUrlService {
+class MockAffiliationService : public password_manager::AffiliationService {
  public:
-  void PrefetchURLs() override {}
-  MOCK_METHOD(GURL, GetChangePasswordUrl, (const GURL&), (override));
+  MOCK_METHOD(void,
+              PrefetchChangePasswordURLs,
+              (const std::vector<GURL>& urls, base::OnceClosure callback),
+              (override));
+  MOCK_METHOD(void, Clear, (), (override));
+  MOCK_METHOD(GURL, GetChangePasswordURL, (const GURL&), (override, const));
 };
 
 class ChangePasswordNavigationThrottleBrowserTestBase
@@ -199,14 +202,12 @@
     : public ChangePasswordNavigationThrottleBrowserTestBase {
  public:
   WellKnownChangePasswordNavigationThrottleBrowserTest() {
-    feature_list_.InitAndDisableFeature(
-        password_manager::features::kChangePasswordAffiliationInfo);
   }
 
   void SetUpOnMainThread() override;
   void TestNavigationThrottleForLocalhost(const std::string& expected_path);
 
-  MockChangePasswordUrlService* url_service_ = nullptr;
+  MockAffiliationService* url_service_ = nullptr;
 
  private:
 };
@@ -214,13 +215,12 @@
 void WellKnownChangePasswordNavigationThrottleBrowserTest::SetUpOnMainThread() {
   Initialize();
   url_service_ =
-      ChangePasswordUrlServiceFactory::GetInstance()
-          ->SetTestingSubclassFactoryAndUse(
-              browser()->profile(),
-              base::BindRepeating([](content::BrowserContext*) {
-                return std::make_unique<
-                    testing::StrictMock<MockChangePasswordUrlService>>();
-              }));
+      AffiliationServiceFactory::GetInstance()->SetTestingSubclassFactoryAndUse(
+          browser()->profile(),
+          base::BindRepeating([](content::BrowserContext*) {
+            return std::make_unique<
+                testing::NiceMock<MockAffiliationService>>();
+          }));
 }
 
 void WellKnownChangePasswordNavigationThrottleBrowserTest::
@@ -366,9 +366,9 @@
       net::HTTP_NOT_FOUND, {}, response_delays().not_exist_delay};
 
   if (page_transition() & ui::PAGE_TRANSITION_FROM_API) {
-    EXPECT_CALL(*url_service_, GetChangePasswordUrl(test_server_->GetURL(
+    EXPECT_CALL(*url_service_, GetChangePasswordURL(test_server_->GetURL(
                                    kWellKnownChangePasswordPath)))
-        .WillOnce(Return(GURL()));
+        .WillRepeatedly(Return(GURL()));
     TestNavigationThrottleForLocalhost(/*expected_path=*/"/");
     ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
   } else {
@@ -387,9 +387,9 @@
       net::HTTP_NOT_FOUND, {}, response_delays().not_exist_delay};
 
   if (page_transition() & ui::PAGE_TRANSITION_FROM_API) {
-    EXPECT_CALL(*url_service_, GetChangePasswordUrl(test_server_->GetURL(
+    EXPECT_CALL(*url_service_, GetChangePasswordURL(test_server_->GetURL(
                                    kWellKnownChangePasswordPath)))
-        .WillOnce(Return(test_server_->GetURL(kMockChangePasswordPath)));
+        .WillRepeatedly(Return(test_server_->GetURL(kMockChangePasswordPath)));
     TestNavigationThrottleForLocalhost(
         /*expected_path=*/kMockChangePasswordPath);
     ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
@@ -410,9 +410,9 @@
       net::HTTP_OK, {}, response_delays().not_exist_delay};
 
   if (page_transition() & ui::PAGE_TRANSITION_FROM_API) {
-    EXPECT_CALL(*url_service_, GetChangePasswordUrl(test_server_->GetURL(
+    EXPECT_CALL(*url_service_, GetChangePasswordURL(test_server_->GetURL(
                                    kWellKnownChangePasswordPath)))
-        .WillOnce(Return(GURL()));
+        .WillRepeatedly(Return(GURL()));
     TestNavigationThrottleForLocalhost(/*expected_path=*/"/");
     ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
   } else {
@@ -440,9 +440,9 @@
   path_response_map_["/not-found"] = {net::HTTP_NOT_FOUND, {}, 0};
 
   if (page_transition() & ui::PAGE_TRANSITION_FROM_API) {
-    EXPECT_CALL(*url_service_, GetChangePasswordUrl(test_server_->GetURL(
+    EXPECT_CALL(*url_service_, GetChangePasswordURL(test_server_->GetURL(
                                    kWellKnownChangePasswordPath)))
-        .WillOnce(Return(GURL()));
+        .WillRepeatedly(Return(GURL()));
     TestNavigationThrottleForLocalhost(/*expected_path=*/"/");
     ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
   } else {
@@ -482,135 +482,9 @@
       test_recorder()->GetEntriesByName(UkmBuilder::kEntryName).empty());
 }
 
-constexpr char kExample1Hostname[] = "example1.com";
-constexpr char kExample1ChangePasswordRelativeUrl[] = "/settings/password";
-constexpr char kExample2Hostname[] = "example2.com";
-constexpr char kExample2ChangePasswordRelativeUrl[] = "/change-pwd";
-
-// Browser Test that checks redirection to change password URL returned by
-// Affiliation Service. Enables kChangePasswordAffiliationInfo feature.
-class AffiliationChangePasswordNavigationThrottleBrowserTest
-    : public ChangePasswordNavigationThrottleBrowserTestBase {
- public:
-  AffiliationChangePasswordNavigationThrottleBrowserTest() {
-    feature_list_.InitAndEnableFeature(
-        password_manager::features::kChangePasswordAffiliationInfo);
-    sync_service_.SetFirstSetupComplete(true);
-    sync_service_.SetIsUsingExplicitPassphrase(false);
-  }
-
-  void SetUpOnMainThread() override;
-  // The facet's |url| and corresponding |change_password_url| cannot be
-  // hardcoded in the method as the the ports are randomly generated and the
-  // response would no longer match requested or expected url.
-  std::string CreateResponse(const GURL& requested_url,
-                             const GURL& requested_change_password_url,
-                             const GURL& other_url,
-                             const GURL& other_change_password_url);
-
-  syncer::TestSyncService sync_service_;
-  network::TestURLLoaderFactory test_url_loader_factory_;
-};
-
-void AffiliationChangePasswordNavigationThrottleBrowserTest::
-    SetUpOnMainThread() {
-  Initialize();
-
-  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory =
-      base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-          &test_url_loader_factory_);
-
-  auto* affiliation_service =
-      static_cast<password_manager::AffiliationServiceImpl*>(
-          AffiliationServiceFactory::GetForProfile(browser()->profile()));
-  affiliation_service->SetSyncServiceForTesting(&sync_service_);
-  affiliation_service->SetURLLoaderFactoryForTesting(shared_url_loader_factory);
-}
-
-std::string
-AffiliationChangePasswordNavigationThrottleBrowserTest::CreateResponse(
-    const GURL& requested_url,
-    const GURL& requested_change_password_url,
-    const GURL& other_url,
-    const GURL& other_change_password_url) {
-  affiliation_pb::LookupAffiliationResponse response;
-  affiliation_pb::FacetGroup* facet_group = response.add_group();
-
-  affiliation_pb::Facet* requested_facet = facet_group->add_facet();
-  requested_facet->set_id(requested_url.spec());
-  requested_facet->mutable_change_password_info()->set_change_password_url(
-      requested_change_password_url.spec());
-
-  affiliation_pb::Facet* other_facet = facet_group->add_facet();
-  other_facet->set_id(other_url.spec());
-  other_facet->mutable_change_password_info()->set_change_password_url(
-      other_change_password_url.spec());
-
-  return response.SerializeAsString();
-}
-
-IN_PROC_BROWSER_TEST_P(AffiliationChangePasswordNavigationThrottleBrowserTest,
-                       NavigatesToChangePasswordURLOfRequestedURL) {
-  GURL requested_origin = test_server_->GetURL(kExample1Hostname, "/");
-  GURL requested_change_password_url = test_server_->GetURL(
-      kExample1Hostname, kExample1ChangePasswordRelativeUrl);
-
-  GURL other_origin = test_server_->GetURL(kExample2Hostname, "/");
-  GURL other_change_password_url = test_server_->GetURL(
-      kExample2Hostname, kExample2ChangePasswordRelativeUrl);
-
-  std::string fake_response =
-      CreateResponse(requested_origin, requested_change_password_url,
-                     other_origin, other_change_password_url);
-  std::string spec =
-      base::FeatureList::IsEnabled(
-          password_manager::features::kUseOfHashAffiliationFetcher)
-          ? password_manager::HashAffiliationFetcher::BuildQueryURL().spec()
-          : password_manager::AffiliationFetcher::BuildQueryURL().spec();
-  test_url_loader_factory_.AddResponse(spec, fake_response);
-
-  path_response_map_[kWellKnownChangePasswordPath] = {
-      net::HTTP_NOT_FOUND, {}, response_delays().change_password_delay};
-  path_response_map_[kWellKnownNotExistingResourcePath] = {
-      net::HTTP_NOT_FOUND, {}, response_delays().not_exist_delay};
-
-  TestNavigationThrottle(/*navigate_url=*/test_server_->GetURL(
-                             kExample1Hostname, kWellKnownChangePasswordPath),
-                         /*expected_url=*/requested_change_password_url);
-  ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
-}
-
-IN_PROC_BROWSER_TEST_P(AffiliationChangePasswordNavigationThrottleBrowserTest,
-                       NavigatesToChangePasswordURLOfOtherURLIfEmpty) {
-  GURL requested_origin = test_server_->GetURL(kExample1Hostname, "/");
-
-  GURL other_origin = test_server_->GetURL(kExample2Hostname, "/");
-  GURL other_change_password_url = test_server_->GetURL(
-      kExample2Hostname, kExample2ChangePasswordRelativeUrl);
-
-  std::string fake_response = CreateResponse(
-      requested_origin, GURL(), other_origin, other_change_password_url);
-  std::string spec =
-      base::FeatureList::IsEnabled(
-          password_manager::features::kUseOfHashAffiliationFetcher)
-          ? password_manager::HashAffiliationFetcher::BuildQueryURL().spec()
-          : password_manager::AffiliationFetcher::BuildQueryURL().spec();
-  test_url_loader_factory_.AddResponse(spec, fake_response);
-
-  path_response_map_[kWellKnownChangePasswordPath] = {
-      net::HTTP_NOT_FOUND, {}, response_delays().change_password_delay};
-  path_response_map_[kWellKnownNotExistingResourcePath] = {
-      net::HTTP_NOT_FOUND, {}, response_delays().not_exist_delay};
-
-  TestNavigationThrottle(/*navigate_url=*/test_server_->GetURL(
-                             kExample1Hostname, kWellKnownChangePasswordPath),
-                         /*expected_url=*/other_change_password_url);
-  ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
-}
-
 // Harness for testing the throttle with prerendering involved.
 class PrerenderingChangePasswordNavigationThrottleBrowserTest
-    : public AffiliationChangePasswordNavigationThrottleBrowserTest {
+    : public WellKnownChangePasswordNavigationThrottleBrowserTest {
  public:
   PrerenderingChangePasswordNavigationThrottleBrowserTest()
       : prerender_helper_(base::BindRepeating(
@@ -719,12 +593,6 @@
 
 INSTANTIATE_TEST_SUITE_P(
     All,
-    AffiliationChangePasswordNavigationThrottleBrowserTest,
-    ::testing::Combine(::testing::Values(ui::PAGE_TRANSITION_FROM_API),
-                       ::testing::ValuesIn(kDelayParams)));
-
-INSTANTIATE_TEST_SUITE_P(
-    All,
     PrerenderingChangePasswordNavigationThrottleBrowserTest,
     ::testing::Combine(::testing::Values(ui::PAGE_TRANSITION_FROM_API),
                        ::testing::ValuesIn(kDelayParams)));
diff --git a/chrome/browser/ui/profile_picker.cc b/chrome/browser/ui/profile_picker.cc
index 1b07bbd..1f6863e 100644
--- a/chrome/browser/ui/profile_picker.cc
+++ b/chrome/browser/ui/profile_picker.cc
@@ -72,8 +72,7 @@
     return false;
 
   std::vector<ProfileAttributesEntry*> profile_attributes =
-      profile_manager->GetProfileAttributesStorage().GetAllProfilesAttributes(
-          /*include_guest_profile=*/false);
+      profile_manager->GetProfileAttributesStorage().GetAllProfilesAttributes();
   int number_of_active_profiles =
       std::count_if(profile_attributes.begin(), profile_attributes.end(),
                     [](ProfileAttributesEntry* entry) {
diff --git a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
index 4e613e9..60b61aa 100644
--- a/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
+++ b/chrome/browser/ui/search/ntp_user_data_logger_unittest.cc
@@ -52,7 +52,6 @@
                                                    TileVisualType visual_type) {
   return ntp_tiles::NTPTileImpression(index, source, title_source, visual_type,
                                       favicon_base::IconType::kInvalid,
-                                      /*data_generation_time=*/base::Time(),
                                       /*url_for_rappor=*/GURL());
 }
 
@@ -538,23 +537,13 @@
   TestNTPUserDataLogger logger(GURL("chrome://newtab/"));
 
   constexpr base::TimeDelta delta = base::TimeDelta::FromMilliseconds(0);
-  constexpr base::TimeDelta kSuggestionAge = base::TimeDelta::FromMinutes(1);
-  constexpr base::TimeDelta kBucketTolerance = base::TimeDelta::FromSeconds(20);
 
   logger.LogMostVisitedImpression(ntp_tiles::NTPTileImpression(
       0, TileSource::TOP_SITES, TileTitleSource::UNKNOWN,
-      TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid,
-      base::Time::Now() - kSuggestionAge, GURL()));
+      TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid, GURL()));
 
   logger.LogMostVisitedLoaded(delta, /*using_most_visited=*/true,
                               /*is_visible=*/true);
-
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.SuggestionsImpressionAge.client"),
-              ElementsAre(IsBucketBetween(
-                  (kSuggestionAge - kBucketTolerance).InSeconds(),
-                  (kSuggestionAge + kBucketTolerance).InSeconds(),
-                  /*count=*/1)));
 }
 
 TEST_F(NTPUserDataLoggerTest,
diff --git a/chrome/browser/ui/search/search_ipc_router_unittest.cc b/chrome/browser/ui/search/search_ipc_router_unittest.cc
index f8f1428..837dc1e 100644
--- a/chrome/browser/ui/search/search_ipc_router_unittest.cc
+++ b/chrome/browser/ui/search/search_ipc_router_unittest.cc
@@ -349,7 +349,7 @@
   const ntp_tiles::NTPTileImpression impression(
       3, ntp_tiles::TileSource::TOP_SITES, ntp_tiles::TileTitleSource::UNKNOWN,
       ntp_tiles::TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid,
-      base::Time(), GURL());
+      GURL());
   NavigateAndCommitActiveTab(GURL("chrome-search://foo/baz"));
   SetupMockDelegateAndPolicy();
   MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy();
@@ -366,7 +366,7 @@
   const ntp_tiles::NTPTileImpression impression(
       3, ntp_tiles::TileSource::TOP_SITES, ntp_tiles::TileTitleSource::UNKNOWN,
       ntp_tiles::TileVisualType::ICON_REAL, favicon_base::IconType::kInvalid,
-      base::Time(), GURL());
+      GURL());
   NavigateAndCommitActiveTab(GURL("chrome-search://foo/baz"));
   SetupMockDelegateAndPolicy();
   MockSearchIPCRouterPolicy* policy = GetSearchIPCRouterPolicy();
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
index 8dd818e8..0ceb32c 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
@@ -24,6 +24,7 @@
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/button/button.h"
 
 namespace sharing_hub {
 
@@ -87,10 +88,11 @@
 }
 
 void SharingHubBubbleController::ShowBubble() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  ShowSharesheet();
-#else
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  ShowSharesheet(browser->window()->GetSharingHubIconButton());
+#else
   sharing_hub_bubble_view_ =
       browser->window()->ShowSharingHubBubble(web_contents_, this, true);
 #endif
@@ -175,12 +177,16 @@
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-void SharingHubBubbleController::ShowSharesheet() {
+void SharingHubBubbleController::ShowSharesheet(
+    views::Button* highlighted_button) {
   if (!base::FeatureList::IsEnabled(features::kSharesheet) ||
       !base::FeatureList::IsEnabled(features::kChromeOSSharingHub)) {
     return;
   }
 
+  DCHECK(highlighted_button);
+  highlighted_button_tracker_.SetView(highlighted_button);
+
   Profile* const profile =
       Profile::FromBrowserContext(web_contents_->GetBrowserContext());
   DCHECK(profile);
@@ -194,14 +200,24 @@
   sharesheet_service->ShowBubble(
       web_contents_, std::move(intent),
       sharesheet::SharesheetMetrics::LaunchSource::kOmniboxShare,
-      base::BindOnce(&SharingHubBubbleController::OnSharesheetShown,
+      base::BindOnce(&SharingHubBubbleController::OnShareDelivered,
+                     base::Unretained(this)),
+      base::BindOnce(&SharingHubBubbleController::OnSharesheetClosed,
                      base::Unretained(this)));
 }
 
-void SharingHubBubbleController::OnSharesheetShown(
+void SharingHubBubbleController::OnShareDelivered(
     sharesheet::SharesheetResult result) {
   LogCrOSSharesheetResult(result);
 }
+
+void SharingHubBubbleController::OnSharesheetClosed() {
+  // Deselect the omnibox icon now that the sharesheet is closed.
+  views::Button* button =
+      views::Button::AsButton(highlighted_button_tracker_.view());
+  if (button)
+    button->SetHighlighted(false);
+}
 #endif
 
 SharingHubBubbleController::SharingHubBubbleController() = default;
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
index 149f592..298dc818 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
@@ -7,6 +7,7 @@
 
 #include "chrome/browser/sharesheet/sharesheet_types.h"
 #include "content/public/browser/web_contents_user_data.h"
+#include "ui/views/view_tracker.h"
 
 class Profile;
 
@@ -14,6 +15,10 @@
 class WebContents;
 }  // namespace content
 
+namespace views {
+class Button;
+}  // namespace views
+
 namespace sharing_hub {
 
 class SharingHubBubbleView;
@@ -66,8 +71,11 @@
   SharingHubModel* GetSharingHubModel();
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  void ShowSharesheet();
-  void OnSharesheetShown(sharesheet::SharesheetResult result);
+  void ShowSharesheet(views::Button* highlighted_button);
+  void OnShareDelivered(sharesheet::SharesheetResult result);
+  void OnSharesheetClosed();
+
+  views::ViewTracker highlighted_button_tracker_;
 #endif
 
   // The web_contents associated with this controller.
diff --git a/chrome/browser/ui/signin/profile_colors_util_unittest.cc b/chrome/browser/ui/signin/profile_colors_util_unittest.cc
index 7442345..42d25dfa 100644
--- a/chrome/browser/ui/signin/profile_colors_util_unittest.cc
+++ b/chrome/browser/ui/signin/profile_colors_util_unittest.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_init_params.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/themes/browser_theme_pack.h"
 #include "chrome/browser/themes/custom_theme_supplier.h"
diff --git a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
index 9506246..fcfb48f 100644
--- a/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
+++ b/chrome/browser/ui/startup/credential_provider_signin_dialog_win.cc
@@ -193,7 +193,7 @@
     DCHECK(out_exit_code);
 
     const base::Value* dict_result = nullptr;
-    if (!args || args->empty() || !args->Get(0, &dict_result) ||
+    if (!args || args->GetList().empty() || !args->Get(0, &dict_result) ||
         !dict_result->is_dict()) {
       *out_exit_code = credential_provider::kUiecMissingSigninData;
       return base::Value(base::Value::Type::DICTIONARY);
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
index 0bbc1e82..4f1d05ef 100644
--- a/chrome/browser/ui/ui_features.cc
+++ b/chrome/browser/ui/ui_features.cc
@@ -100,12 +100,12 @@
 
 // Sign-in functionality in the profile creation flow. https://crbug.com/1126913
 const base::Feature kSignInProfileCreation{"SignInProfileCreation",
-                                           base::FEATURE_DISABLED_BY_DEFAULT};
+                                           base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Smoother enterprise experience in the sign-in profile creation flow.
 // https://crbug.com/1178494
 const base::Feature kSignInProfileCreationEnterprise{
-    "SignInProfileCreationEnterprise", base::FEATURE_DISABLED_BY_DEFAULT};
+    "SignInProfileCreationEnterprise", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Automatically create groups for users based on domain.
 // https://crbug.com/1128703
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index c385d801..6f60399b 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -1035,12 +1035,7 @@
     bb_view_->GetMenu()->GetMenuController()->Cancel(
         views::MenuController::ExitType::kAll);
 
-    // On linux, Cancelling menu will call Quit on the message loop,
-    // which can interfere with Done. We need to run Done in the
-    // next execution loop.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&ViewEventTestBase::Done, base::Unretained(this)));
+    Done();
   }
 
   int start_y_;
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
index 459f61e8..6fa625a5 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
@@ -10,7 +10,6 @@
 #include "ui/base/buildflags.h"
 #include "ui/base/cursor/cursor_factory.h"
 #include "ui/base/ime/linux/fake_input_method_context_factory.h"
-#include "ui/display/screen.h"
 #include "ui/views/linux_ui/linux_ui.h"
 
 #if BUILDFLAG(USE_GTK)
@@ -47,12 +46,7 @@
     default;
 
 ChromeBrowserMainExtraPartsViewsLinux::
-    ~ChromeBrowserMainExtraPartsViewsLinux() {
-  // It's not expected that the screen is destroyed by this point, but it can happen during fuzz
-  // tests.
-  if (display::Screen::GetScreen())
-    display::Screen::GetScreen()->RemoveObserver(this);
-}
+    ~ChromeBrowserMainExtraPartsViewsLinux() = default;
 
 void ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized() {
   ChromeBrowserMainExtraPartsViews::ToolkitInitialized();
@@ -97,7 +91,7 @@
   // We could do that during the ToolkitInitialized call, which is called before
   // this method, but the display::Screen is only created after PreCreateThreads
   // is called. Thus, do that here instead.
-  display::Screen::GetScreen()->AddObserver(this);
+  display_observer_.emplace(this);
 }
 
 void ChromeBrowserMainExtraPartsViewsLinux::OnCurrentWorkspaceChanged(
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h
index 771415f4..ee36fad 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h
@@ -30,6 +30,8 @@
   // display::DisplayObserver:
   void OnCurrentWorkspaceChanged(const std::string& new_workspace) override;
 
+  absl::optional<display::ScopedDisplayObserver> display_observer_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsViewsLinux);
 };
 
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc
index 25fa1d6..88e9a278 100644
--- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc
+++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.cc
@@ -62,11 +62,10 @@
                                  desktop_native_widget_aura),
       browser_view_(browser_view),
       browser_frame_(browser_frame) {
-#if defined(OS_LINUX)
-  native_frame_ = static_cast<DesktopBrowserFrameAuraLinux*>(
+  native_frame_ = static_cast<DesktopBrowserFrameAuraPlatform*>(
       browser_frame->native_browser_frame());
   native_frame_->set_host(this);
-#endif
+
   browser_frame->set_frame_type(browser_frame->UseCustomFrame()
                                     ? views::Widget::FrameType::kForceCustom
                                     : views::Widget::FrameType::kForceNative);
diff --git a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h
index a7abd0d..c5a3b08 100644
--- a/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h
+++ b/chrome/browser/ui/views/frame/browser_desktop_window_tree_host_linux.h
@@ -17,6 +17,7 @@
 class BrowserFrame;
 class BrowserView;
 class DesktopBrowserFrameAuraLinux;
+class DesktopBrowserFrameLacros;
 enum class TabDragKind;
 
 namespace views {
@@ -73,9 +74,14 @@
 
 // TODO(crbug.com/1221374): Separate Lacros specific code into
 // browser_desktop_window_tree_host_lacros.cc.
-#if defined(OS_LINUX)
-  DesktopBrowserFrameAuraLinux* native_frame_ = nullptr;
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  using DesktopBrowserFrameAuraPlatform = DesktopBrowserFrameLacros;
+#elif defined(OS_LINUX)
+  using DesktopBrowserFrameAuraPlatform = DesktopBrowserFrameAuraLinux;
+#else
+#error Unknown platform
 #endif
+  DesktopBrowserFrameAuraPlatform* native_frame_ = nullptr;
 
 #if defined(USE_DBUS_MENU)
   // Each browser frame maintains its own menu bar object because the lower
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
index 87368524..77bb5dd 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -45,7 +45,6 @@
 #include "ui/base/layout.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
-#include "ui/display/screen.h"
 #include "ui/events/gestures/gesture_recognizer.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/rect.h"
@@ -110,8 +109,6 @@
 }
 
 BrowserNonClientFrameViewChromeOS::~BrowserNonClientFrameViewChromeOS() {
-  display::Screen::GetScreen()->RemoveObserver(this);
-
   ImmersiveModeController* immersive_controller =
       browser_view()->immersive_mode_controller();
   if (immersive_controller)
@@ -145,7 +142,7 @@
         chromeos::kBlockedForAssistantSnapshotKey, true);
   }
 
-  display::Screen::GetScreen()->AddObserver(this);
+  display_observer_.emplace(this);
 
   if (frame()->ShouldDrawFrameHeader())
     frame_header_ = CreateFrameHeader();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
index a01d28aa..f7772e5 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
@@ -224,6 +224,8 @@
   base::ScopedObservation<aura::Window, aura::WindowObserver>
       window_observation_{this};
 
+  absl::optional<display::ScopedDisplayObserver> display_observer_;
+
   base::WeakPtrFactory<BrowserNonClientFrameViewChromeOS> weak_ptr_factory_{
       this};
 };
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
index 9c0d965..fcf6a1a 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.h
@@ -101,6 +101,11 @@
 
   void AddRoutingForWindowControlsOverlayViews();
 
+  // Toggle the visibility of the web_app_frame_toolbar_view() for PWAs with
+  // window controls overlay display override when entering full screen or when
+  // toolbar style is changed.
+  void ToggleWebAppFrameToolbarViewVisibility();
+
   // Used to keep track of the update of kShowFullscreenToolbar preference.
   BooleanPrefMember show_fullscreen_toolbar_;
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
index b2b04204..6d01f28 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -113,6 +113,8 @@
     return;
   }
   if (browser_view()->IsFullscreen()) {
+    ToggleWebAppFrameToolbarViewVisibility();
+
     [fullscreen_toolbar_controller_ enterFullscreenMode];
   } else {
     // Exiting tab fullscreen requires updating Top UI.
@@ -218,6 +220,9 @@
     browser_view()->UnhideDownloadShelf();
   }
   [fullscreen_toolbar_controller_ setToolbarStyle:new_style];
+
+  ToggleWebAppFrameToolbarViewVisibility();
+
   if (![fullscreen_toolbar_controller_ isInFullscreen] ||
       old_style == new_style)
     return;
@@ -233,11 +238,6 @@
     // requires a re-layout when in fullscreen and shown.
     if (web_app_frame_toolbar() && !ShouldHideTopUIForFullscreen())
       InvalidateLayout();
-
-    if (ShouldHideTopUIForFullscreen() &&
-        browser_view()->IsWindowControlsOverlayEnabled()) {
-      InvalidateLayout();
-    }
   }
 }
 
@@ -588,3 +588,10 @@
           remote_cocoa::mojom::WindowControlsOverlayNSViewType::
               kWebAppFrameToolbar);
 }
+
+void BrowserNonClientFrameViewMac::ToggleWebAppFrameToolbarViewVisibility() {
+  if (browser_view()->IsWindowControlsOverlayEnabled()) {
+    web_app_frame_toolbar()->SetVisible(!ShouldHideTopUIForFullscreen());
+    InvalidateLayout();
+  }
+}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
index 82d5086..9799802d 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac_browsertest.mm
@@ -454,6 +454,14 @@
   EXPECT_NE(frame_view_->NonClientHitTest(kBorderPoint), HTCAPTION);
   EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
       browser_view_->GetWidget()->GetNativeView(), kBorderPoint));
+
+  // Validate that the draggable region is reset on navigation and the point is
+  // no longer draggable.
+  ui_test_utils::NavigateToURL(browser_view_->browser(),
+                               GURL("http://example.test/"));
+  EXPECT_NE(frame_view_->NonClientHitTest(kPoint), HTCAPTION);
+  EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
+      browser_view_->GetWidget()->GetNativeView(), kPoint));
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppBrowserFrameViewMacWindowControlsOverlayTest,
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index c56e17d3..3460fc0 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1899,6 +1899,12 @@
   return bubble;
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+views::Button* BrowserView::GetSharingHubIconButton() {
+  return toolbar_button_provider()->GetPageActionIconView(
+      PageActionIconType::kSharingHub);
+}
+#else
 sharing_hub::SharingHubBubbleView* BrowserView::ShowSharingHubBubble(
     content::WebContents* web_contents,
     sharing_hub::SharingHubBubbleController* controller,
@@ -1921,6 +1927,7 @@
 
   return bubble;
 }
+#endif
 
 ShowTranslateBubbleResult BrowserView::ShowTranslateBubble(
     content::WebContents* web_contents,
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 474b10932..02f0019 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -459,10 +459,14 @@
       content::WebContents* contents,
       send_tab_to_self::SendTabToSelfBubbleController* controller,
       bool is_user_gesture) override;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  views::Button* GetSharingHubIconButton() override;
+#else
   sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents,
       sharing_hub::SharingHubBubbleController* controller,
       bool is_user_gesture) override;
+#endif
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.cc b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.cc
index 972cc5e9..ffa6a69 100644
--- a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.cc
+++ b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.cc
@@ -23,6 +23,12 @@
   return params;
 }
 
+void DesktopBrowserFrameLacros::TabDraggingKindChanged(
+    TabDragKind tab_drag_kind) {
+  if (host_)
+    host_->TabDraggingKindChanged(tab_drag_kind);
+}
+
 NativeBrowserFrame* NativeBrowserFrameFactory::Create(
     BrowserFrame* browser_frame,
     BrowserView* browser_view) {
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
index 39c77215..c5ec66ae 100644
--- a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
+++ b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
@@ -9,6 +9,7 @@
 
 class BrowserFrame;
 class BrowserView;
+class BrowserDesktopWindowTreeHostLinux;
 
 // Provides the window frame for the Chrome browser window on Lacros.
 class DesktopBrowserFrameLacros : public DesktopBrowserFrameAura {
@@ -20,11 +21,17 @@
   DesktopBrowserFrameLacros& operator=(const DesktopBrowserFrameLacros&) =
       delete;
 
+  void set_host(BrowserDesktopWindowTreeHostLinux* host) { host_ = host; }
+
  protected:
   ~DesktopBrowserFrameLacros() override;
 
   // Overridden from NativeBrowserFrame:
   views::Widget::InitParams GetWidgetParams() override;
+  void TabDraggingKindChanged(TabDragKind tab_drag_kind) override;
+
+ private:
+  BrowserDesktopWindowTreeHostLinux* host_ = nullptr;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_LACROS_H_
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
index ac52e9c..67d5e03f 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_navigation_observer.h"
@@ -410,6 +411,14 @@
   EXPECT_NE(glass_frame_view_->NonClientHitTest(kBorderPoint), HTCAPTION);
   EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
       browser_view_->GetWidget()->GetNativeView(), kBorderPoint));
+
+  // Validate that the draggable region is reset on navigation and the point is
+  // no longer draggable.
+  ui_test_utils::NavigateToURL(browser_view_->browser(),
+                               GURL("http://example.test/"));
+  EXPECT_NE(glass_frame_view_->NonClientHitTest(kPoint), HTCAPTION);
+  EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
+      browser_view_->GetNativeWindow(), kPoint));
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewWindowControlsOverlayTest,
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
index 00943a38..097309c 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_browsertest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "ui/base/hit_test.h"
@@ -484,6 +485,14 @@
             HTCAPTION);
   EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
       browser_view_->GetWidget()->GetNativeView(), kBorderPoint));
+
+  // Validate that the draggable region is reset on navigation and the point is
+  // no longer draggable.
+  ui_test_utils::NavigateToURL(browser_view_->browser(),
+                               GURL("http://example.test/"));
+  EXPECT_NE(opaque_browser_frame_view_->NonClientHitTest(kPoint), HTCAPTION);
+  EXPECT_TRUE(browser_view_->ShouldDescendIntoChildForEventHandling(
+      browser_view_->GetWidget()->GetNativeView(), kPoint));
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewWindowControlsOverlayTest,
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
index 83a780fb..420e8052 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -30,7 +30,7 @@
 #include "ui/aura/window_tree_host.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
-#include "ui/display/screen.h"
+#include "ui/display/display.h"
 #include "ui/views/controls/native/native_view_host.h"
 
 namespace {
@@ -290,7 +290,6 @@
   observed_omni_box_->AddObserver(this);
 
   browser_view_->browser()->tab_strip_model()->AddObserver(this);
-  display::Screen::GetScreen()->AddObserver(this);
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   auto* accessibility_manager = ash::AccessibilityManager::Get();
@@ -308,7 +307,6 @@
 TopControlsSlideControllerChromeOS::~TopControlsSlideControllerChromeOS() {
   OnEnabledStateChanged(false);
 
-  display::Screen::GetScreen()->RemoveObserver(this);
   browser_view_->browser()->tab_strip_model()->RemoveObserver(this);
 
   if (observed_omni_box_)
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
index d890746..89534f8a 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
@@ -193,6 +193,8 @@
   base::CallbackListSubscription accessibility_status_subscription_;
 #endif
 
+  display::ScopedDisplayObserver display_observer_{this};
+
   DISALLOW_COPY_AND_ASSIGN(TopControlsSlideControllerChromeOS);
 };
 
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
index 449e131..83b5ec0f 100644
--- a/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
+++ b/chrome/browser/ui/views/frame/webui_tab_strip_container_view.cc
@@ -919,9 +919,7 @@
   const int width = bounds.width().is_bounded()
                         ? bounds.width().value()
                         : tab_contents_container_->width();
-  const int height = TabStripUILayout::CalculateForWebViewportSize(
-                         tab_contents_container_->size())
-                         .CalculateContainerHeight();
+  const int height = TabStripUILayout::GetContainerHeight();
 
   return gfx::Size(width, height);
 }
diff --git a/chrome/browser/ui/views/frame/window_controls_overlay_input_routing_mac.mm b/chrome/browser/ui/views/frame/window_controls_overlay_input_routing_mac.mm
index 4acb481..b4c978d 100644
--- a/chrome/browser/ui/views/frame/window_controls_overlay_input_routing_mac.mm
+++ b/chrome/browser/ui/views/frame/window_controls_overlay_input_routing_mac.mm
@@ -19,19 +19,13 @@
       overlay_type_(overlay_type) {
   // WebAppOriginText animates and disappears during initial launch so we want
   // to observe that and update the remote view accordingly.
-  if (overlay_type_ ==
-      remote_cocoa::mojom::WindowControlsOverlayNSViewType::kWebAppFrameToolbar)
-    overlay_view_->AddObserver(this);
-  else
-    browser_non_client_frame_view_mac_->AddObserver(this);
+  overlay_view_->AddObserver(this);
+  browser_non_client_frame_view_mac_->AddObserver(this);
 }
 
 WindowControlsOverlayInputRoutingMac::~WindowControlsOverlayInputRoutingMac() {
-  if (overlay_type_ ==
-      remote_cocoa::mojom::WindowControlsOverlayNSViewType::kWebAppFrameToolbar)
-    overlay_view_->RemoveObserver(this);
-  else
-    browser_non_client_frame_view_mac_->RemoveObserver(this);
+  overlay_view_->RemoveObserver(this);
+  browser_non_client_frame_view_mac_->RemoveObserver(this);
 }
 
 void WindowControlsOverlayInputRoutingMac::OnViewBoundsChanged(
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
index 51f8130..dc093ce 100644
--- a/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
+++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view_interactive_browsertest.cc
@@ -891,8 +891,15 @@
   WaitForPictureInPictureButtonVisibility(true);
 }
 
+// Flaky on linux (https://crbug.com/1218003).
+#if defined(OS_LINUX)
+#define MAYBE_PlayingSessionAlwaysDisplayFirst \
+  DISABLED_PlayingSessionAlwaysDisplayFirst
+#else
+#define MAYBE_PlayingSessionAlwaysDisplayFirst PlayingSessionAlwaysDisplayFirst
+#endif
 IN_PROC_BROWSER_TEST_F(MediaDialogViewBrowserTest,
-                       PlayingSessionAlwaysDisplayFirst) {
+                       MAYBE_PlayingSessionAlwaysDisplayFirst) {
   OpenTestURL();
   StartPlayback();
   WaitForStart();
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
index de4b301..1bfc769 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
@@ -533,10 +533,8 @@
 
 // Test that loading a page with pushState() call that changes URL
 // updates the intent picker view.
-//
-// TODO(crbug.com/1201397): fix flakiness and reenable
 IN_PROC_BROWSER_TEST_F(IntentPickerBubbleViewBrowserTestChromeOS,
-                       DISABLED_PushStateURLChangeTest) {
+                       PushStateURLChangeTest) {
   ASSERT_TRUE(embedded_test_server()->Start());
   const GURL test_url =
       embedded_test_server()->GetURL("/intent_picker/push_state_test.html");
@@ -570,7 +568,9 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   content::TestNavigationObserver observer(web_contents);
-  SimulateMouseClickOrTapElementWithId(web_contents, "push_to_new_url_button");
+  ASSERT_TRUE(content::ExecuteScript(
+      web_contents,
+      "document.getElementById('push_to_new_url_button').click();"));
   observer.WaitForNavigationFinished();
   EXPECT_FALSE(intent_picker_view->GetVisible());
 }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index c02d3168..ca31e38 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -56,6 +56,8 @@
 #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_layout.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
+#include "chrome/browser/ui/views/location_bar/permission_quiet_chip.h"
+#include "chrome/browser/ui/views/location_bar/permission_request_chip.h"
 #include "chrome/browser/ui/views/location_bar/selected_keyword_view.h"
 #include "chrome/browser/ui/views/location_bar/star_view.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_container.h"
@@ -819,12 +821,16 @@
 
 PermissionChip* LocationBarView::DisplayChip(
     permissions::PermissionPrompt::Delegate* delegate) {
-  DCHECK(!chip_);
   DCHECK(delegate);
-  // `chip_` must come first so it's in the correct place in the focus order.
-  chip_ = AddChildViewAt(
-      std::make_unique<PermissionRequestChip>(browser(), delegate), 0);
-  return chip_;
+  return AddChip(std::make_unique<PermissionRequestChip>(browser(), delegate));
+}
+
+PermissionChip* LocationBarView::DisplayQuietChip(
+    permissions::PermissionPrompt::Delegate* delegate,
+    bool should_expand) {
+  DCHECK(delegate);
+  return AddChip(std::make_unique<PermissionQuietChip>(browser(), delegate,
+                                                       should_expand));
 }
 
 void LocationBarView::FinalizeChip() {
@@ -914,6 +920,13 @@
       0, LocationBarView::GetAvailableTextHeight() - (bubble_padding * 2));
 }
 
+PermissionChip* LocationBarView::AddChip(std::unique_ptr<PermissionChip> chip) {
+  DCHECK(!chip_);
+  // `chip_` must come first so it's in the correct place in the focus order.
+  chip_ = AddChildViewAt(std::move(chip), 0);
+  return chip_;
+}
+
 int LocationBarView::GetMinimumLeadingWidth() const {
   // If the keyword bubble is showing, the view can collapse completely.
   if (ShouldShowKeywordBubble())
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index c2cd957..a62759d 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -25,7 +25,7 @@
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
-#include "chrome/browser/ui/views/location_bar/permission_request_chip.h"
+#include "chrome/browser/ui/views/location_bar/permission_chip.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "components/security_state/core/security_state.h"
@@ -183,6 +183,11 @@
   PermissionChip* DisplayChip(
       permissions::PermissionPrompt::Delegate* delegate);
 
+  // Creates and displays an instance of PermissionQuietChip.
+  PermissionChip* DisplayQuietChip(
+      permissions::PermissionPrompt::Delegate* delegate,
+      bool should_expand);
+
   // Removes previously displayed PermissionChip.
   void FinalizeChip();
 
@@ -266,6 +271,9 @@
       geolocation_permission_observation_{this};
 #endif
 
+  // Adds `chip` as the first child view.
+  PermissionChip* AddChip(std::unique_ptr<PermissionChip> chip);
+
   // Returns the amount of space required to the left of the omnibox text.
   int GetMinimumLeadingWidth() const;
 
diff --git a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
index 2ed437d..63747e4 100644
--- a/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
+++ b/chrome/browser/ui/views/location_bar/omnibox_chip_button.cc
@@ -4,12 +4,10 @@
 
 #include "chrome/browser/ui/views/location_bar/omnibox_chip_button.h"
 
-#include "base/location.h"
-#include "base/time/time.h"
+#include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/layout_constants.h"
-#include "chrome/browser/ui/views/chrome_layout_provider.h"
-#include "components/vector_icons/vector_icons.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/base/theme_provider.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/native_theme/native_theme.h"
 #include "ui/views/controls/highlight_path_generator.h"
@@ -116,14 +114,16 @@
 }
 
 SkColor OmniboxChipButton::GetMainColor() {
-  ui::NativeTheme* native_theme = GetNativeTheme();
   switch (theme_) {
     case Theme::kBlue:
       // TODO(crbug.com/1003612): ui::NativeTheme::kColorId_ProminentButtonColor
       // does not always represent the blue color we need, but it is OK to use
       // for now.
-      return native_theme->GetSystemColor(
+      return GetNativeTheme()->GetSystemColor(
           ui::NativeTheme::kColorId_ProminentButtonColor);
+    case Theme::kGray:
+      return GetThemeProvider()->GetColor(
+          ThemeProperties::COLOR_OMNIBOX_TEXT_DIMMED);
   }
 }
 
diff --git a/chrome/browser/ui/views/location_bar/omnibox_chip_button.h b/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
index 1b37b8e8..84316fe 100644
--- a/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
+++ b/chrome/browser/ui/views/location_bar/omnibox_chip_button.h
@@ -26,7 +26,7 @@
   // of Chip.
   enum class Theme {
     kBlue,
-    // TODO(crbug.com/1177760): Other themes will follow.
+    kGray,
   };
 
   void AnimateCollapse();
@@ -49,6 +49,8 @@
   void SetTheme(Theme theme);
   void SetForceExpandedForTesting(bool force_expanded_for_testing);
 
+  Theme get_theme_for_testing() { return theme_; }
+
  private:
   int GetIconSize() const;
 
diff --git a/chrome/browser/ui/views/location_bar/permission_chip.cc b/chrome/browser/ui/views/location_bar/permission_chip.cc
index eb9a266..1bc10c0 100644
--- a/chrome/browser/ui/views/location_bar/permission_chip.cc
+++ b/chrome/browser/ui/views/location_bar/permission_chip.cc
@@ -55,28 +55,25 @@
 
 PermissionChip::PermissionChip(
     permissions::PermissionPrompt::Delegate* delegate,
-    const gfx::VectorIcon& icon,
-    std::u16string message,
-    bool should_start_open)
-    : delegate_(delegate), should_start_open_(should_start_open) {
-  DCHECK(delegate);
+    DisplayParams initializer)
+    : delegate_(delegate),
+      should_start_open_(initializer.should_start_open),
+      should_expand_(initializer.should_expand) {
+  DCHECK(delegate_);
   SetUseDefaultFillLayout(true);
 
   chip_button_ = AddChildView(std::make_unique<OmniboxChipButton>(
       base::BindRepeating(&PermissionChip::ChipButtonPressed,
                           base::Unretained(this)),
-      icon, message, true));
-
+      initializer.icon, initializer.message, initializer.is_prominent));
+  chip_button_->SetTheme(initializer.theme);
   chip_button_->SetButtonController(std::make_unique<BubbleButtonController>(
       chip_button_, this,
       std::make_unique<views::Button::DefaultButtonControllerDelegate>(
           chip_button_)));
-
   chip_button_->SetExpandAnimationEndedCallback(base::BindRepeating(
       &PermissionChip::ExpandAnimationEnded, base::Unretained(this)));
 
-  chip_button_->SetTheme(OmniboxChipButton::Theme::kBlue);
-
   Show(should_start_open_);
 }
 
@@ -125,7 +122,8 @@
 void PermissionChip::Show(bool always_open_bubble) {
   // TODO(olesiamarukhno): Add tests for animation logic.
   chip_button_->ResetAnimation();
-  if (!delegate_->WasCurrentRequestAlreadyDisplayed() || always_open_bubble) {
+  if (should_expand_ &&
+      (!delegate_->WasCurrentRequestAlreadyDisplayed() || always_open_bubble)) {
     chip_button_->AnimateExpand();
   } else {
     StartDismissTimer();
@@ -170,11 +168,18 @@
 }
 
 void PermissionChip::StartDismissTimer() {
-  if (base::FeatureList::IsEnabled(
-          permissions::features::kPermissionChipAutoDismiss)) {
-    auto delay = base::TimeDelta::FromMilliseconds(
-        permissions::features::kPermissionChipAutoDismissDelay.Get());
-    dismiss_timer_.Start(FROM_HERE, delay, this, &PermissionChip::Dismiss);
+  if (should_expand_) {
+    if (base::FeatureList::IsEnabled(
+            permissions::features::kPermissionChipAutoDismiss)) {
+      auto delay = base::TimeDelta::FromMilliseconds(
+          permissions::features::kPermissionChipAutoDismissDelay.Get());
+      dismiss_timer_.Start(FROM_HERE, delay, this, &PermissionChip::Dismiss);
+    }
+  } else {
+    // Abusive origins do not support expand animation, hence the dismiss timer
+    // should be longer.
+    dismiss_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(18), this,
+                         &PermissionChip::Dismiss);
   }
 }
 
diff --git a/chrome/browser/ui/views/location_bar/permission_chip.h b/chrome/browser/ui/views/location_bar/permission_chip.h
index 096880a0..e9b11213 100644
--- a/chrome/browser/ui/views/location_bar/permission_chip.h
+++ b/chrome/browser/ui/views/location_bar/permission_chip.h
@@ -28,12 +28,21 @@
 class PermissionChip : public views::AccessiblePaneView,
                        public views::WidgetObserver,
                        public BubbleOwnerDelegate {
+ protected:
+  // Holds all parameters needed for a chip initialization.
+  struct DisplayParams {
+    const gfx::VectorIcon& icon;
+    std::u16string message;
+    bool should_start_open;
+    bool is_prominent;
+    OmniboxChipButton::Theme theme;
+    bool should_expand;
+  };
+
  public:
   METADATA_HEADER(PermissionChip);
-  PermissionChip(permissions::PermissionPrompt::Delegate* delegate,
-                 const gfx::VectorIcon& icon,
-                 std::u16string message,
-                 bool should_start_open);
+  explicit PermissionChip(permissions::PermissionPrompt::Delegate* delegate,
+                          DisplayParams initializer);
   PermissionChip(const PermissionChip& chip) = delete;
   PermissionChip& operator=(const PermissionChip& chip) = delete;
   ~PermissionChip() override;
@@ -61,6 +70,8 @@
   GetPermissionPromptBubbleForTest() = 0;
 
   bool should_start_open_for_testing() { return should_start_open_; }
+  bool should_expand_for_testing() { return should_expand_; }
+  OmniboxChipButton* get_chip_button_for_testing() { return chip_button_; }
 
  protected:
   permissions::PermissionPrompt::Delegate* delegate() const {
@@ -76,6 +87,7 @@
   void Collapse(bool allow_restart);
   void StartDismissTimer();
   void Dismiss();
+
   void AnimateCollapse();
   void AnimateExpand();
 
@@ -92,6 +104,7 @@
   OmniboxChipButton* chip_button_ = nullptr;
 
   bool should_start_open_ = false;
+  bool should_expand_ = true;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_PERMISSION_CHIP_H_
diff --git a/chrome/browser/ui/views/location_bar/permission_quiet_chip.cc b/chrome/browser/ui/views/location_bar/permission_quiet_chip.cc
new file mode 100644
index 0000000..a193dfa
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/permission_quiet_chip.cc
@@ -0,0 +1,133 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/location_bar/permission_quiet_chip.h"
+
+#include "base/location.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h"
+#include "chrome/browser/ui/views/permission_bubble/permission_prompt_style.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/permissions/permission_request.h"
+#include "components/permissions/request_type.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/vector_icons/vector_icons.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/events/event.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/accessibility/view_accessibility.h"
+#include "ui/views/bubble/bubble_dialog_delegate_view.h"
+#include "ui/views/controls/button/button_controller.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/widget/widget.h"
+
+#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
+#include "chrome/browser/ui/views/content_setting_bubble_contents.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+
+namespace {
+
+const gfx::VectorIcon& GetPermissionIconId(
+    permissions::PermissionPrompt::Delegate* delegate) {
+  DCHECK(delegate);
+
+  if (delegate->Requests()[0]->GetRequestType() ==
+      permissions::RequestType::kNotifications) {
+    return vector_icons::kNotificationsOffIcon;
+  }
+
+  NOTREACHED();
+  return gfx::kNoneIcon;
+}
+
+std::u16string GetPermissionMessage(
+    permissions::PermissionPrompt::Delegate* delegate) {
+  DCHECK(delegate);
+
+  if (delegate->Requests()[0]->GetRequestType() ==
+      permissions::RequestType::kNotifications) {
+    return l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_OFF_EXPLANATORY_TEXT);
+  }
+
+  NOTREACHED();
+  return std::u16string();
+}
+
+}  // namespace
+
+PermissionQuietChip::PermissionQuietChip(
+    Browser* browser,
+    permissions::PermissionPrompt::Delegate* delegate,
+    bool should_expand)
+    : PermissionChip(
+          delegate,
+          {GetPermissionIconId(delegate), GetPermissionMessage(delegate), false,
+           /*is_prominent=*/false, OmniboxChipButton::Theme::kGray,
+           /*should_expand=*/should_expand}),
+      browser_(browser) {
+  DCHECK_EQ(1u, delegate->Requests().size());
+  chip_shown_time_ = base::TimeTicks::Now();
+}
+
+PermissionQuietChip::~PermissionQuietChip() {
+  if (quiet_request_bubble_) {
+    views::Widget* widget = quiet_request_bubble_->GetWidget();
+    widget->RemoveObserver(this);
+    widget->Close();
+  }
+}
+
+void PermissionQuietChip::OpenBubble() {
+  // The prompt bubble is either not opened yet or already closed on
+  // deactivation.
+  DCHECK(!quiet_request_bubble_);
+
+  LocationBarView* lbv = GetLocationBarView();
+  content::WebContents* web_contents = lbv->GetContentSettingWebContents();
+
+  if (web_contents) {
+    quiet_request_bubble_ = new ContentSettingBubbleContents(
+        std::make_unique<ContentSettingNotificationsBubbleModel>(
+            lbv->GetContentSettingBubbleModelDelegate(), web_contents),
+        web_contents, lbv, views::BubbleBorder::TOP_LEFT);
+    quiet_request_bubble_->SetHighlightedButton(button());
+    views::Widget* bubble_widget =
+        views::BubbleDialogDelegateView::CreateBubble(quiet_request_bubble_);
+    bubble_widget->AddObserver(this);
+    bubble_widget->Show();
+  }
+
+  RecordChipButtonPressed();
+}
+
+views::BubbleDialogDelegateView*
+PermissionQuietChip::GetPermissionPromptBubbleForTest() {
+  return quiet_request_bubble_;
+}
+
+void PermissionQuietChip::OnWidgetClosing(views::Widget* widget) {
+  DCHECK_EQ(widget, quiet_request_bubble_->GetWidget());
+  PermissionChip::OnWidgetClosing(widget);
+  quiet_request_bubble_ = nullptr;
+}
+
+bool PermissionQuietChip::IsBubbleShowing() const {
+  return quiet_request_bubble_;
+}
+
+void PermissionQuietChip::RecordChipButtonPressed() {
+  base::UmaHistogramMediumTimes("Permissions.QuietChip.TimeToInteraction",
+                                base::TimeTicks::Now() - chip_shown_time_);
+}
+
+LocationBarView* PermissionQuietChip::GetLocationBarView() {
+  return BrowserView::GetBrowserViewForBrowser(browser_)->GetLocationBarView();
+}
+
+BEGIN_METADATA(PermissionQuietChip, views::View)
+END_METADATA
diff --git a/chrome/browser/ui/views/location_bar/permission_quiet_chip.h b/chrome/browser/ui/views/location_bar/permission_quiet_chip.h
new file mode 100644
index 0000000..e49bef8
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/permission_quiet_chip.h
@@ -0,0 +1,49 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_PERMISSION_QUIET_CHIP_H_
+#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_PERMISSION_QUIET_CHIP_H_
+
+#include "chrome/browser/ui/views/location_bar/permission_chip.h"
+
+class Browser;
+class LocationBarView;
+
+// A less prominent version of `PermissionRequestChip`. It is used to display a
+// permission request from origins with an abusive reputation, low acceptance
+// rate, or if a user manually enabled "quieter messaging" in
+// chrome://settings/content/notifications.
+class PermissionQuietChip : public PermissionChip {
+ public:
+  METADATA_HEADER(PermissionQuietChip);
+  PermissionQuietChip(Browser* browser,
+                      permissions::PermissionPrompt::Delegate* delegate,
+                      bool should_expand);
+  PermissionQuietChip(const PermissionQuietChip& chip) = delete;
+  PermissionQuietChip& operator=(const PermissionQuietChip& chip) = delete;
+  ~PermissionQuietChip() override;
+
+  // PermissionChip:
+  void OpenBubble() override;
+  views::BubbleDialogDelegateView* GetPermissionPromptBubbleForTest() override;
+
+  // views::WidgetObserver:
+  void OnWidgetClosing(views::Widget* widget) override;
+
+  // BubbleOwnerDelegate:
+  bool IsBubbleShowing() const override;
+
+ private:
+  void RecordChipButtonPressed();
+  LocationBarView* GetLocationBarView();
+
+  Browser* browser_ = nullptr;
+
+  // The time when the chip was displayed.
+  base::TimeTicks chip_shown_time_;
+
+  views::BubbleDialogDelegateView* quiet_request_bubble_ = nullptr;
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_PERMISSION_QUIET_CHIP_H_
diff --git a/chrome/browser/ui/views/location_bar/permission_request_chip.cc b/chrome/browser/ui/views/location_bar/permission_request_chip.cc
index 40c7e09..58a25bf7 100644
--- a/chrome/browser/ui/views/location_bar/permission_request_chip.cc
+++ b/chrome/browser/ui/views/location_bar/permission_request_chip.cc
@@ -25,6 +25,7 @@
 #include "ui/views/widget/widget.h"
 
 namespace {
+
 bool IsCameraPermission(permissions::RequestType type) {
   return type == permissions::RequestType::kCameraStream;
 }
@@ -112,10 +113,11 @@
 PermissionRequestChip::PermissionRequestChip(
     Browser* browser,
     permissions::PermissionPrompt::Delegate* delegate)
-    : PermissionChip(delegate,
-                     GetPermissionIconId(delegate),
-                     GetPermissionMessage(delegate),
-                     ShouldBubbleStartOpen(delegate)),
+    : PermissionChip(
+          delegate,
+          {GetPermissionIconId(delegate), GetPermissionMessage(delegate),
+           ShouldBubbleStartOpen(delegate), /*is_prominent=*/true,
+           OmniboxChipButton::Theme::kBlue, /*should_expand=*/true}),
       browser_(browser) {
   chip_shown_time_ = base::TimeTicks::Now();
   VerifyCameraAndMicRequest(delegate);
@@ -159,7 +161,7 @@
 }
 
 void PermissionRequestChip::RecordChipButtonPressed() {
-    base::UmaHistogramLongTimes("Permissions.Chip.TimeToInteraction",
+  base::UmaHistogramMediumTimes("Permissions.Chip.TimeToInteraction",
                                 base::TimeTicks::Now() - chip_shown_time_);
 }
 
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.cc b/chrome/browser/ui/views/page_info/chosen_object_view.cc
index c15ef57..03121ea 100644
--- a/chrome/browser/ui/views/page_info/chosen_object_view.cc
+++ b/chrome/browser/ui/views/page_info/chosen_object_view.cc
@@ -82,6 +82,12 @@
 
 ChosenObjectView::~ChosenObjectView() = default;
 
+void ChosenObjectView::ResetPermission() {
+  if (delete_button_->GetVisible()) {
+    ExecuteDeleteCommand();
+  }
+}
+
 void ChosenObjectView::ExecuteDeleteCommand() {
   // Policy-managed permissions cannot be deleted. This isn't normally
   // reachable but views::test::ButtonTestApi::NotifyClick doesn't check
@@ -98,6 +104,11 @@
   DCHECK(delete_button_->GetVisible());
   delete_button_->SetVisible(false);
 
+  // In the page info v2, hide the row after revoking access.
+  if (base::FeatureList::IsEnabled(page_info::kPageInfoV2Desktop)) {
+    SetVisible(false);
+  }
+
   for (ChosenObjectViewObserver& observer : observer_list_) {
     observer.OnChosenObjectDeleted(*info_);
   }
diff --git a/chrome/browser/ui/views/page_info/chosen_object_view.h b/chrome/browser/ui/views/page_info/chosen_object_view.h
index a6cd3e6..854e24d 100644
--- a/chrome/browser/ui/views/page_info/chosen_object_view.h
+++ b/chrome/browser/ui/views/page_info/chosen_object_view.h
@@ -31,6 +31,7 @@
   ~ChosenObjectView() override;
 
   void AddObserver(ChosenObjectViewObserver* observer);
+  void ResetPermission();
 
   // views::View:
   void OnThemeChanged() override;
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
index 37ea4aaa..487cc84 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc
@@ -24,6 +24,8 @@
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
 #include "chrome/browser/ui/page_info/chrome_page_info_delegate.h"
 #include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 #include "chrome/browser/ui/page_info/page_info_dialog.h"
@@ -228,6 +230,11 @@
 }
 
 void PageInfoBubbleView::SecurityDetailsClicked(const ui::Event& event) {
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->InteractedWithPageInfo();
+  }
+
   if (GetSecurityDescriptionType() == SecurityDescriptionType::SAFETY_TIP)
     presenter_->OpenSafetyTipHelpCenterPage();
   else
@@ -235,6 +242,11 @@
 }
 
 void PageInfoBubbleView::ResetDecisionsClicked() {
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->InteractedWithPageInfo();
+  }
+
   presenter_->OnRevokeSSLErrorBypassButtonPressed();
   GetWidget()->Close();
 }
@@ -256,6 +268,11 @@
       closing_callback_(std::move(closing_callback)) {
   DCHECK(closing_callback_);
 
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->PageInfoOpened();
+  }
+
   // Capture the default bubble margin, and move it to the Layout classes. This
   // is necessary so that the views::Separator can extend the full width of the
   // bubble.
@@ -336,6 +353,11 @@
 
 void PageInfoBubbleView::OnPermissionChanged(
     const PageInfo::PermissionInfo& permission) {
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->InteractedWithPageInfo();
+  }
+
   presenter_->OnSitePermissionChanged(permission.type, permission.setting,
                                       permission.is_one_time);
   // The menu buttons for the permissions might have longer strings now, so we
@@ -346,6 +368,11 @@
 
 void PageInfoBubbleView::OnChosenObjectDeleted(
     const PageInfoUI::ChosenObjectInfo& info) {
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->InteractedWithPageInfo();
+  }
+
   presenter_->OnSiteChosenObjectDeleted(info.ui_info,
                                         info.chooser_object->value);
 }
@@ -358,9 +385,17 @@
 
   // This method mostly shouldn't be re-entrant but there are a few cases where
   // it can be (see crbug/966308). In that case, we have already run the closing
-  // callback so should not attempt to do it again.
-  if (closing_callback_)
+  // callback so should not attempt to do it again. As there will always be a
+  // |closing_callback_|, this is also used to ensure that the sentiment service
+  // is informed exactly once.
+  if (closing_callback_) {
     std::move(closing_callback_).Run(widget->closed_reason(), reload_prompt);
+
+    if (auto* sentiment_service =
+            TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+      sentiment_service->PageInfoClosed();
+    }
+  }
 }
 
 
@@ -608,11 +643,21 @@
         identity_info.safe_browsing_status,
         base::BindRepeating(
             [](PageInfoBubbleView* view) {
+              if (auto* sentiment_service =
+                      TrustSafetySentimentServiceFactory::GetForProfile(
+                          view->profile_)) {
+                sentiment_service->InteractedWithPageInfo();
+              }
               view->presenter_->OnChangePasswordButtonPressed();
             },
             this),
         base::BindRepeating(
             [](PageInfoBubbleView* view) {
+              if (auto* sentiment_service =
+                      TrustSafetySentimentServiceFactory::GetForProfile(
+                          view->profile_)) {
+                sentiment_service->InteractedWithPageInfo();
+              }
               view->GetWidget()->Close();
               view->presenter_->OnAllowlistPasswordReuseButtonPressed();
             },
@@ -769,6 +814,11 @@
   content::GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE, base::BindOnce(&PageInfoBubbleView::HandleMoreInfoRequestAsync,
                                 weak_factory_.GetWeakPtr(), source->GetID()));
+
+  if (auto* sentiment_service =
+          TrustSafetySentimentServiceFactory::GetForProfile(profile_)) {
+    sentiment_service->InteractedWithPageInfo();
+  }
 }
 
 void PageInfoBubbleView::HandleMoreInfoRequestAsync(int view_id) {
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
index 6faa862..95f4a40 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.h
@@ -13,6 +13,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/reputation/safety_tip_ui.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service.h"
 #include "chrome/browser/ui/page_info/page_info_dialog.h"
 #include "chrome/browser/ui/views/bubble_anchor_util_views.h"
 #include "chrome/browser/ui/views/hover_button.h"
@@ -101,6 +102,7 @@
   friend class PageInfoBubbleViewDialogBrowserTest;
   friend class PageInfoBubbleViewSyncBrowserTest;
   friend class test::PageInfoBubbleViewTestApi;
+  friend class TrustSafetySentimentServiceBrowserTest;
 
   PageInfoBubbleView(
       views::View* anchor_view,
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
index cba0e4a..ef16078 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -12,12 +12,15 @@
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
 #include "chrome/browser/ui/page_info/page_info_dialog.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
+#include "chrome/browser/ui/views/page_info/page_info_new_bubble_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/chrome_features.h"
@@ -25,6 +28,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/common/content_settings_types.h"
+#include "components/page_info/features.h"
 #include "components/page_info/page_info.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_test_util.h"
@@ -122,11 +126,31 @@
 
 }  // namespace
 
-class PageInfoBubbleViewBrowserTest : public InProcessBrowserTest {
+class PageInfoBubbleViewBrowserTest
+    : public InProcessBrowserTest,
+      public ::testing::WithParamInterface<bool> {
  public:
-  PageInfoBubbleViewBrowserTest() = default;
+  PageInfoBubbleViewBrowserTest() {
+    feature_list_.InitWithFeatureState(page_info::kPageInfoV2Desktop,
+                                       is_page_info_v2_enabled());
+  }
+
+  PageInfoBubbleViewBrowserTest(const PageInfoBubbleViewBrowserTest& test) =
+      delete;
+  PageInfoBubbleViewBrowserTest& operator=(
+      const PageInfoBubbleViewBrowserTest& test) = delete;
+
+  void SetUpOnMainThread() override {
+    mock_sentiment_service_ = static_cast<MockTrustSafetySentimentService*>(
+        TrustSafetySentimentServiceFactory::GetInstance()
+            ->SetTestingFactoryAndUse(
+                browser()->profile(),
+                base::BindRepeating(&BuildMockTrustSafetySentimentService)));
+  }
 
  protected:
+  bool is_page_info_v2_enabled() const { return GetParam(); }
+
   GURL GetSimplePageUrl() const {
     return ui_test_utils::GetTestUrl(
         base::FilePath(base::FilePath::kCurrentDirectory),
@@ -155,12 +179,22 @@
     run_loop.Run();
   }
 
-  void TriggerReloadPromptOnClose() const {
-    PageInfoBubbleView* const page_info_bubble_view =
-        static_cast<PageInfoBubbleView*>(
-            PageInfoBubbleView::GetPageInfoBubbleForTesting());
-    ASSERT_NE(nullptr, page_info_bubble_view);
+  PageInfo* GetPresenter() const {
+    PageInfo* presenter = nullptr;
+    if (is_page_info_v2_enabled()) {
+      presenter = static_cast<PageInfoNewBubbleView*>(
+                      PageInfoBubbleView::GetPageInfoBubbleForTesting())
+                      ->presenter_.get();
+    } else {
+      presenter = static_cast<PageInfoBubbleView*>(
+                      PageInfoBubbleView::GetPageInfoBubbleForTesting())
+                      ->presenter_.get();
+    }
+    DCHECK(presenter);
+    return presenter;
+  }
 
+  void TriggerReloadPromptOnClose() const {
     // Set some dummy non-default permissions. This will trigger a reload prompt
     // when the bubble is closed.
     PageInfo::PermissionInfo permission;
@@ -168,59 +202,95 @@
     permission.setting = ContentSetting::CONTENT_SETTING_BLOCK;
     permission.default_setting = ContentSetting::CONTENT_SETTING_ASK;
     permission.source = content_settings::SettingSource::SETTING_SOURCE_USER;
-    page_info_bubble_view->OnPermissionChanged(permission);
+    GetPresenter()->OnSitePermissionChanged(permission.type, permission.setting,
+                                            permission.is_one_time);
   }
 
   void SetPageInfoBubbleIdentityInfo(
       const PageInfoUI::IdentityInfo& identity_info) {
-    static_cast<PageInfoBubbleView*>(
-        PageInfoBubbleView::GetPageInfoBubbleForTesting())
-        ->SetIdentityInfo(identity_info);
+    auto* presenter = GetPresenter();
+    EXPECT_TRUE(presenter->ui_for_testing());
+    presenter->ui_for_testing()->SetIdentityInfo(identity_info);
   }
 
   std::u16string GetCertificateButtonTitle() const {
     // Only PageInfoBubbleViewBrowserTest can access certificate_button_ in
     // PageInfoBubbleView, or title() in HoverButton.
-    PageInfoBubbleView* page_info_bubble_view =
-        static_cast<PageInfoBubbleView*>(
-            PageInfoBubbleView::GetPageInfoBubbleForTesting());
-    return page_info_bubble_view->certificate_button_->title()->GetText();
+    auto* certificate_button = static_cast<PageInfoHoverButton*>(
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::
+                VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_CERTIFICATE_VIEWER));
+    return certificate_button->title()->GetText();
   }
 
   std::u16string GetCertificateButtonSubtitle() const {
-    PageInfoBubbleView* page_info_bubble_view =
-        static_cast<PageInfoBubbleView*>(
-            PageInfoBubbleView::GetPageInfoBubbleForTesting());
-    return page_info_bubble_view->certificate_button_->subtitle()->GetText();
+    auto* certificate_button = static_cast<PageInfoHoverButton*>(
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::
+                VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_CERTIFICATE_VIEWER));
+    return certificate_button->subtitle()->GetText();
   }
 
   const std::u16string GetPageInfoBubbleViewDetailText() {
-    PageInfoBubbleView* page_info_bubble_view =
-        static_cast<PageInfoBubbleView*>(
-            PageInfoBubbleView::GetPageInfoBubbleForTesting());
-    return page_info_bubble_view->details_text();
+    auto* label =
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL);
+    return static_cast<views::StyledLabel*>(label)->GetText();
   }
 
+  const std::u16string GetPageInfoBubbleViewSummaryText() {
+    auto* label =
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_SUMMARY_LABEL);
+    return static_cast<views::StyledLabel*>(label)->GetText();
+  }
+
+  const std::u16string GetSecurityInformationButtonText() {
+    auto* button =
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::
+                VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_SECURITY_INFORMATION);
+    return static_cast<PageInfoHoverButton*>(button)->title()->GetText();
+  }
+
+  SecurityInformationView* GetPageInfoHeader() {
+    return static_cast<PageInfoBubbleView*>(
+               PageInfoBubbleView::GetPageInfoBubbleForTesting())
+        ->header_;
+  }
+
+  void SetupSentimentServiceExpectations(bool interacted) {
+    if (is_page_info_v2_enabled())
+      return;
+    testing::InSequence sequence;
+    EXPECT_CALL(*mock_sentiment_service_, PageInfoOpened);
+    EXPECT_CALL(*mock_sentiment_service_, InteractedWithPageInfo)
+        .Times(interacted ? testing::Exactly(1) : testing::Exactly(0));
+    EXPECT_CALL(*mock_sentiment_service_, PageInfoClosed);
+  }
+
+  MockTrustSafetySentimentService* mock_sentiment_service_;
+
  private:
   std::vector<PageInfoViewFactory::PageInfoViewID> expected_identifiers_;
-
-  DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleViewBrowserTest);
+  base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ShowBubble) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, ShowBubble) {
+  SetupSentimentServiceExpectations(/*interacted=*/false);
   OpenPageInfoBubble(browser());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_PAGE_INFO,
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ChromeURL) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, ChromeURL) {
   ui_test_utils::NavigateToURL(browser(), GURL("chrome://settings"));
   OpenPageInfoBubble(browser());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_INTERNAL_PAGE,
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ChromeExtensionURL) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, ChromeExtensionURL) {
   ui_test_utils::NavigateToURL(
       browser(), GURL("chrome-extension://extension-id/options.html"));
   OpenPageInfoBubble(browser());
@@ -228,7 +298,7 @@
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ChromeDevtoolsURL) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, ChromeDevtoolsURL) {
   ui_test_utils::NavigateToURL(
       browser(), GURL("devtools://devtools/bundled/inspector.html"));
   OpenPageInfoBubble(browser());
@@ -236,7 +306,7 @@
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, ViewSourceURL) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, ViewSourceURL) {
   ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
   browser()
       ->tab_strip_model()
@@ -250,7 +320,8 @@
 
 // Test opening "Site Details" via Page Info from an ASCII origin does the
 // correct URL canonicalization.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, SiteSettingsLink) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, SiteSettingsLink) {
+  SetupSentimentServiceExpectations(/*interacted=*/true);
   GURL url = GURL("https://www.google.com/");
   std::string expected_origin = "https%3A%2F%2Fwww.google.com";
   EXPECT_EQ(GURL(chrome::kChromeUISiteDetailsPrefixURL + expected_origin),
@@ -259,7 +330,7 @@
 
 // Test opening "Site Details" via Page Info from a non-ASCII URL converts it to
 // an origin and does punycode conversion as well as URL canonicalization.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        SiteSettingsLinkWithNonAsciiUrl) {
   GURL url = GURL("http://🥄.ws/other/stuff.htm");
   std::string expected_origin = "http%3A%2F%2Fxn--9q9h.ws";
@@ -269,7 +340,7 @@
 
 // Test opening "Site Details" via Page Info from an origin with a non-default
 // (scheme, port) pair will specify port # in the origin passed to query params.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        SiteSettingsLinkWithNonDefaultPort) {
   GURL url = GURL("https://www.example.com:8372");
   std::string expected_origin = "https%3A%2F%2Fwww.example.com%3A8372";
@@ -279,7 +350,7 @@
 
 // Test opening "Site Details" via Page Info from about:blank goes to "Content
 // Settings" (the alternative is a blank origin being sent to "Site Details").
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        SiteSettingsLinkWithAboutBlankURL) {
   EXPECT_EQ(GURL(chrome::kChromeUIContentSettingsURL),
             OpenSiteSettingsForUrl(browser(), GURL(url::kAboutBlankURL)));
@@ -287,7 +358,7 @@
 
 // Test opening page info bubble that matches
 // SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE threat type.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        VerifyEnterprisePasswordReusePageInfoBubble) {
   ASSERT_TRUE(embedded_test_server()->Start());
   base::HistogramTester histograms;
@@ -327,14 +398,15 @@
   ASSERT_EQ(security_state::MALICIOUS_CONTENT_STATUS_ENTERPRISE_PASSWORD_REUSE,
             visible_security_state->malicious_content_status);
   ASSERT_EQ(l10n_util::GetStringUTF16(
-                IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE),
+                IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_ENTERPRISE) +
+                u" " + l10n_util::GetStringUTF16(IDS_LEARN_MORE),
             GetPageInfoBubbleViewDetailText());
 
   // Verify these two buttons are showing.
   EXPECT_TRUE(change_password_button->GetVisible());
   EXPECT_TRUE(allowlist_password_reuse_button->GetVisible());
 
-  // Verify clicking on button will increment corresponding bucket of
+  // Verify clicking on button will increment corresponding bucket
   // PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry histogram.
   PerformMouseClickOnView(change_password_button);
   EXPECT_THAT(
@@ -368,7 +440,7 @@
 
 // Test opening page info bubble that matches
 // SB_THREAT_TYPE_SAVED_PASSWORD_REUSE threat type.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        VerifySavedPasswordReusePageInfoBubble) {
   ASSERT_TRUE(embedded_test_server()->Start());
   base::HistogramTester histograms;
@@ -412,8 +484,14 @@
   EXPECT_TRUE(change_password_button->GetVisible());
   EXPECT_TRUE(allowlist_password_reuse_button->GetVisible());
 
-  // Verify clicking on button will increment corresponding bucket of
-  // PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry histogram.
+  // Verify clicking on each button will both inform the sentiment service,
+  // and increment the corresponding bucket of
+  // PasswordProtection.PageInfoAction.NonGaiaEnterprisePasswordEntry
+  // histogram.
+  if (!is_page_info_v2_enabled()) {
+    EXPECT_CALL(*mock_sentiment_service_, InteractedWithPageInfo).Times(2);
+  }
+
   PerformMouseClickOnView(change_password_button);
   EXPECT_THAT(
       histograms.GetAllSamples(safe_browsing::kSavedPasswordPageInfoHistogram),
@@ -442,7 +520,7 @@
             visible_security_state->malicious_content_status);
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        ClosesOnUserNavigateToSamePage) {
   ui_test_utils::NavigateToURL(browser(), GetSimplePageUrl());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_NONE,
@@ -455,7 +533,7 @@
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        ClosesOnUserNavigateToDifferentPage) {
   ui_test_utils::NavigateToURL(browser(), GetSimplePageUrl());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_NONE,
@@ -468,7 +546,7 @@
             PageInfoBubbleView::GetShownBubbleType());
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        DoesntCloseOnSubframeNavigate) {
   ui_test_utils::NavigateToURL(browser(), GetIframePageUrl());
   EXPECT_EQ(PageInfoBubbleView::BUBBLE_NONE,
@@ -485,6 +563,17 @@
             PageInfoBubbleView::GetShownBubbleType());
 }
 
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
+                       InteractedWithCookiesButton) {
+  SetupSentimentServiceExpectations(/*interacted=*/true);
+  OpenPageInfoBubble(browser());
+
+  views::View* cookies_button = GetView(
+      browser(),
+      PageInfoViewFactory::VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_COOKIE_DIALOG);
+  PerformMouseClickOnView(cookies_button);
+}
+
 class PageInfoBubbleViewBrowserTestWithAutoupgradesDisabled
     : public PageInfoBubbleViewBrowserTest {
  public:
@@ -498,8 +587,12 @@
   base::test::ScopedFeatureList feature_list;
 };
 
+INSTANTIATE_TEST_SUITE_P(All,
+                         PageInfoBubbleViewBrowserTestWithAutoupgradesDisabled,
+                         ::testing::Values(false, true));
+
 // Ensure changes to security state are reflected in an open PageInfo bubble.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTestWithAutoupgradesDisabled,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTestWithAutoupgradesDisabled,
                        UpdatesOnSecurityStateChange) {
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.AddDefaultHandlers(
@@ -513,17 +606,29 @@
   views::BubbleDialogDelegateView* page_info =
       PageInfoBubbleView::GetPageInfoBubbleForTesting();
 
-  EXPECT_EQ(page_info->GetWindowTitle(),
-            l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURE_SUMMARY));
+  if (is_page_info_v2_enabled()) {
+    EXPECT_EQ(GetSecurityInformationButtonText(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURE_SUMMARY));
+  } else {
+    EXPECT_EQ(page_info->GetWindowTitle(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURE_SUMMARY));
+  }
 
   ExecuteJavaScriptForTests("load_mixed();");
-  EXPECT_EQ(page_info->GetWindowTitle(),
-            l10n_util::GetStringUTF16(IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY));
+  if (is_page_info_v2_enabled()) {
+    EXPECT_EQ(GetPageInfoBubbleViewSummaryText(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY));
+  } else {
+    EXPECT_EQ(page_info->GetWindowTitle(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MIXED_CONTENT_SUMMARY));
+  }
 }
 
 // Ensure a page can both have an invalid certificate *and* be blocked by Safe
 // Browsing.  Regression test for bug 869925.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, BlockedAndInvalidCert) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, BlockedAndInvalidCert) {
+  SetupSentimentServiceExpectations(/*interacted=*/true);
+
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.AddDefaultHandlers(
       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
@@ -545,20 +650,38 @@
       PageInfoBubbleView::GetPageInfoBubbleForTesting();
 
   // Verify bubble complains of malware...
-  EXPECT_EQ(page_info->GetWindowTitle(),
-            l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  if (is_page_info_v2_enabled()) {
+    EXPECT_EQ(GetPageInfoBubbleViewSummaryText(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  } else {
+    EXPECT_EQ(page_info->GetWindowTitle(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  }
 
   // ...and has a "Certificate (Invalid)" button.
-  const std::u16string invalid_parens = l10n_util::GetStringUTF16(
-      IDS_PAGE_INFO_CERTIFICATE_INVALID_PARENTHESIZED);
-  EXPECT_EQ(GetCertificateButtonTitle(),
-            l10n_util::GetStringFUTF16(IDS_PAGE_INFO_CERTIFICATE_BUTTON_TEXT,
-                                       invalid_parens));
+  std::u16string invalid_text;
+  if (is_page_info_v2_enabled()) {
+    invalid_text =
+        l10n_util::GetStringUTF16(IDS_PAGE_INFO_CERTIFICATE_IS_NOT_VALID);
+  } else {
+    const std::u16string invalid_subtext = l10n_util::GetStringUTF16(
+        IDS_PAGE_INFO_CERTIFICATE_INVALID_PARENTHESIZED);
+    invalid_text = l10n_util::GetStringFUTF16(
+        IDS_PAGE_INFO_CERTIFICATE_BUTTON_TEXT, invalid_subtext);
+  }
+  EXPECT_EQ(GetCertificateButtonTitle(), invalid_text);
+
+  // Check that clicking the certificate viewer button is reported to the
+  // sentiment service.
+  views::View* certificates_button = GetView(
+      browser(),
+      PageInfoViewFactory::VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_CERTIFICATE_VIEWER);
+  PerformMouseClickOnView(certificates_button);
 }
 
 // Ensure a page that has an EV certificate *and* is blocked by Safe Browsing
 // shows the correct PageInfo UI. Regression test for crbug.com/1014240.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest, MalwareAndEvCert) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest, MalwareAndEvCert) {
   net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
   https_server.AddDefaultHandlers(
       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
@@ -587,8 +710,13 @@
       PageInfoBubbleView::GetPageInfoBubbleForTesting();
 
   // Verify bubble complains of malware...
-  EXPECT_EQ(page_info->GetWindowTitle(),
-            l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  if (is_page_info_v2_enabled()) {
+    EXPECT_EQ(GetPageInfoBubbleViewSummaryText(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  } else {
+    EXPECT_EQ(page_info->GetWindowTitle(),
+              l10n_util::GetStringUTF16(IDS_PAGE_INFO_MALWARE_SUMMARY));
+  }
 
   // ...and has the correct organization details in the Certificate button.
   EXPECT_EQ(GetCertificateButtonSubtitle(),
@@ -616,7 +744,7 @@
 
  protected:
   explicit FocusTracker(bool initially_focused) : focused_(initially_focused) {}
-  virtual ~FocusTracker() {}
+  virtual ~FocusTracker() = default;
 
   void OnFocused() {
     focused_ = true;
@@ -701,7 +829,7 @@
 
 // Test that when the PageInfo bubble is closed, focus is returned to the web
 // contents pane.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        MAYBE_FocusReturnsToContentOnClose) {
   content::WebContents* const web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -710,8 +838,8 @@
   web_contents_focus_tracker.WaitForFocus(true);
 
   OpenPageInfoBubble(browser());
-  PageInfoBubbleView* page_info_bubble_view = static_cast<PageInfoBubbleView*>(
-      PageInfoBubbleView::GetPageInfoBubbleForTesting());
+  auto* page_info_bubble_view =
+      PageInfoBubbleView::GetPageInfoBubbleForTesting();
   EXPECT_FALSE(web_contents_focus_tracker.focused());
 
   page_info_bubble_view->GetWidget()->CloseWithReason(
@@ -733,7 +861,7 @@
 // displayed, focus is NOT returned to the web contents pane, but rather returns
 // to the location bar so accessibility users must tab through the reload prompt
 // before getting back to web contents (see https://crbug.com/910067).
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewBrowserTest,
                        MAYBE_FocusDoesNotReturnToContentsOnReloadPrompt) {
   content::WebContents* const web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -744,8 +872,8 @@
   web_contents_focus_tracker.WaitForFocus(true);
 
   OpenPageInfoBubble(browser());
-  PageInfoBubbleView* page_info_bubble_view = static_cast<PageInfoBubbleView*>(
-      PageInfoBubbleView::GetPageInfoBubbleForTesting());
+  auto* page_info_bubble_view =
+      PageInfoBubbleView::GetPageInfoBubbleForTesting();
   EXPECT_FALSE(web_contents_focus_tracker.focused());
 
   TriggerReloadPromptOnClose();
@@ -756,3 +884,8 @@
   EXPECT_TRUE(location_bar_focus_tracker.focused());
   EXPECT_FALSE(web_contents_focus_tracker.focused());
 }
+
+// Run tests with kPageInfoV2Desktop flag enabled and disabled.
+INSTANTIATE_TEST_SUITE_P(All,
+                         PageInfoBubbleViewBrowserTest,
+                         ::testing::Values(false, true));
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
index 7058f20..abe8721 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_dialog_browsertest.cc
@@ -9,11 +9,14 @@
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
+#include "chrome/browser/ui/views/page_info/page_info_main_view.h"
+#include "chrome/browser/ui/views/page_info/page_info_new_bubble_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/browser/content_settings_registry.h"
+#include "components/page_info/features.h"
 #include "components/page_info/page_info.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_test_util.h"
 #include "components/safe_browsing/core/browser/password_protection/metrics_util.h"
@@ -60,16 +63,31 @@
 
 }  // namespace
 
-class PageInfoBubbleViewDialogBrowserTest : public DialogBrowserTest {
+class PageInfoBubbleViewDialogBrowserTest
+    : public DialogBrowserTest,
+      public ::testing::WithParamInterface<bool> {
  public:
-  PageInfoBubbleViewDialogBrowserTest() = default;
+  PageInfoBubbleViewDialogBrowserTest() {
+    feature_list_.InitWithFeatureState(page_info::kPageInfoV2Desktop,
+                                       is_page_info_v2_enabled());
+  }
+
+  PageInfoBubbleViewDialogBrowserTest(
+      const PageInfoBubbleViewDialogBrowserTest& test) = delete;
+  PageInfoBubbleViewDialogBrowserTest& operator=(
+      const PageInfoBubbleViewDialogBrowserTest& test) = delete;
+
+  bool is_page_info_v2_enabled() const { return GetParam(); }
 
   // DialogBrowserTest:
-  void ShowUi(const std::string& name) override {
+  void ShowUi(const std::string& name_with_param_suffix) override {
     // Bubble dialogs' bounds may exceed the display's work area.
     // https://crbug.com/893292.
     set_should_verify_dialog_bounds(false);
 
+    const std::string& name =
+        name_with_param_suffix.substr(0, name_with_param_suffix.find("/"));
+
     // All the possible test names.
     constexpr char kInsecure[] = "Insecure";
     constexpr char kInternal[] = "Internal";
@@ -77,7 +95,9 @@
     constexpr char kInternalViewSource[] = "InternalViewSource";
     constexpr char kFile[] = "File";
     constexpr char kSecure[] = "Secure";
+    constexpr char kSecureSubpage[] = "SecureSubpage";
     constexpr char kEvSecure[] = "EvSecure";
+    constexpr char kEvSecureSubpage[] = "EvSecureSubpage";
     constexpr char kMalware[] = "Malware";
     constexpr char kDeceptive[] = "Deceptive";
     constexpr char kUnwantedSoftware[] = "UnwantedSoftware";
@@ -99,6 +119,7 @@
     // URL each IdentityInfo type would normally be associated with.
     const GURL https_url("https://example.com");
     const GURL http_url("http://example.com");
+    const std::string kSiteOrigin = "example.com";
 
     GURL url = http_url;
     if (name == kSecure || name == kEvSecure || name == kMixedContentForm ||
@@ -127,13 +148,13 @@
     if (name == kInsecure) {
       identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_NO_CERT;
     } else if (name == kSecure || name == kAllowAllPermissions ||
-               name == kBlockAllPermissions) {
+               name == kBlockAllPermissions || name == kSecureSubpage) {
       // Generate a valid mock HTTPS identity, with a certificate.
       identity.identity_status = PageInfo::SITE_IDENTITY_STATUS_CERT;
       constexpr char kGoodCertificateFile[] = "ok_cert.pem";
       identity.certificate = net::ImportCertFromFile(
           net::GetTestCertsDirectory(), kGoodCertificateFile);
-    } else if (name == kEvSecure) {
+    } else if (name == kEvSecure || name == kEvSecureSubpage) {
       // Generate a valid mock EV HTTPS identity, with an EV certificate. Must
       // match conditions in PageInfoBubbleView::SetIdentityInfo() for setting
       // the certificate button subtitle.
@@ -210,19 +231,31 @@
       }
 
       ChosenObjectInfoList chosen_object_list;
-
-      PageInfoBubbleView* page_info_bubble_view =
-          static_cast<PageInfoBubbleView*>(
-              PageInfoBubbleView::GetPageInfoBubbleForTesting());
+      PageInfo* presenter = GetPresenter();
+      EXPECT_TRUE(presenter);
+      EXPECT_TRUE(presenter->ui_for_testing());
+      auto* current_ui = presenter->ui_for_testing();
+      views::View* bubble_view =
+          PageInfoBubbleView::GetPageInfoBubbleForTesting();
       // Normally |PageInfoBubbleView| doesn't update the permissions already
       // shown if they change while it's still open. For this test, manually
       // force an update by clearing the existing permission views here.
-      page_info_bubble_view->GetFocusManager()->SetFocusedView(nullptr);
-      page_info_bubble_view->selector_rows_.clear();
-      page_info_bubble_view->permissions_view_->RemoveAllChildViews(true);
+      bubble_view->GetFocusManager()->SetFocusedView(nullptr);
 
-      page_info_bubble_view->SetPermissionInfo(permissions_list,
-                                               std::move(chosen_object_list));
+      if (is_page_info_v2_enabled()) {
+        auto* main_page = static_cast<PageInfoMainView*>(current_ui);
+        main_page->selector_rows_.clear();
+        main_page->permissions_view_->RemoveAllChildViews(true);
+
+      } else {
+        auto* page_info_bubble_view =
+            static_cast<PageInfoBubbleView*>(bubble_view);
+        page_info_bubble_view->selector_rows_.clear();
+        page_info_bubble_view->permissions_view_->RemoveAllChildViews(true);
+      }
+
+      current_ui->SetPermissionInfo(permissions_list,
+                                    std::move(chosen_object_list));
     }
 
     if (name == kSignInSyncPasswordReuse ||
@@ -239,13 +272,21 @@
           &placeholder_offsets);
     }
 
+    if (name == kSecureSubpage || name == kEvSecureSubpage) {
+      PageInfoNewBubbleView* bubble_view = static_cast<PageInfoNewBubbleView*>(
+          PageInfoBubbleView::GetPageInfoBubbleForTesting());
+      bubble_view->OpenSecurityPage();
+    }
+
     if (name != kInsecure && name.find(kInternal) == std::string::npos &&
         name != kFile) {
+      identity.site_identity = kSiteOrigin;
       // The bubble may be PageInfoBubbleView or InternalPageInfoBubbleView. The
       // latter is only used for |kInternal|, so it is safe to static_cast here.
-      static_cast<PageInfoBubbleView*>(
-          PageInfoBubbleView::GetPageInfoBubbleForTesting())
-          ->SetIdentityInfo(identity);
+      PageInfo* presenter = GetPresenter();
+      EXPECT_TRUE(presenter);
+      EXPECT_TRUE(presenter->ui_for_testing());
+      presenter->ui_for_testing()->SetIdentityInfo(identity);
     }
   }
 
@@ -263,70 +304,96 @@
     return true;
   }
 
+  PageInfo* GetPresenter() {
+    if (is_page_info_v2_enabled()) {
+      return static_cast<PageInfoNewBubbleView*>(
+                 PageInfoBubbleView::GetPageInfoBubbleForTesting())
+          ->presenter_.get();
+    }
+
+    return static_cast<PageInfoBubbleView*>(
+               PageInfoBubbleView::GetPageInfoBubbleForTesting())
+        ->presenter_.get();
+  }
+
  private:
   std::vector<PageInfoViewFactory::PageInfoViewID> expected_identifiers_;
-
-  DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleViewDialogBrowserTest);
+  base::test::ScopedFeatureList feature_list_;
 };
 
 // Shows the Page Info bubble for a HTTP page (specifically, about:blank).
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Insecure) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Insecure) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a HTTPS page.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Secure) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Secure) {
   ShowAndVerifyUi();
 }
 
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_EvSecure) {
+// Shows the Page Info bubble for a HTTPS page.
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
+                       InvokeUi_SecureSubpage) {
+  if (!is_page_info_v2_enabled())
+    return;
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_EvSecure) {
+  ShowAndVerifyUi();
+}
+
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
+                       InvokeUi_EvSecureSubpage) {
+  if (!is_page_info_v2_enabled())
+    return;
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for an internal page, e.g. chrome://settings.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Internal) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Internal) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for an extensions page.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_InternalExtension) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a chrome page that displays the source HTML.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_InternalViewSource) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a file:// URL.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_File) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_File) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a site flagged for malware by Safe Browsing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Malware) {
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest, InvokeUi_Malware) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a site flagged for social engineering by Safe
 // Browsing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_Deceptive) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a site flagged for distributing unwanted
 // software by Safe Browsing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_UnwantedSoftware) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for a site flagged for malware that also has a bad
 // certificate.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_MalwareAndBadCert) {
   ShowAndVerifyUi();
 }
@@ -334,14 +401,14 @@
 // Disabled because of flakiness: crbug.com/1208502.
 // Shows the Page Info bubble for an admin-provided cert when the page is
 // secure, but has a form that submits to an insecure url.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        DISABLED_InvokeUi_MixedContentForm) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble for an admin-provided cert when the page is
 // secure, but it uses insecure resources (e.g. images).
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_MixedContent) {
   ShowAndVerifyUi();
 }
@@ -354,7 +421,7 @@
 #else
 #define MAYBE_InvokeUi_AllowAllPermissions InvokeUi_AllowAllPermissions
 #endif
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        MAYBE_InvokeUi_AllowAllPermissions) {
   ShowAndVerifyUi();
 }
@@ -367,14 +434,14 @@
 #else
 #define MAYBE_InvokeUi_BlockAllPermissions InvokeUi_BlockAllPermissions
 #endif
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        MAYBE_InvokeUi_BlockAllPermissions) {
   ShowAndVerifyUi();
 }
 
 // Shows the Page Info bubble Safe Browsing warning after detecting the user has
 // re-used an existing password on a site, e.g. due to phishing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_SavedPasswordReuse) {
   ShowAndVerifyUi();
 }
@@ -382,14 +449,14 @@
 // Shows the Page Info bubble Safe Browsing warning after detecting the
 // signed-in syncing user has re-used an existing password on a site, e.g. due
 // to phishing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_SignInSyncPasswordReuse) {
   ShowAndVerifyUi();
 }
 // Shows the Page Info bubble Safe Browsing warning after detecting the
 // signed-in not syncing user has re-used an existing password on a site, e.g.
 // due to phishing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_SignInNonSyncPasswordReuse) {
   ShowAndVerifyUi();
 }
@@ -397,7 +464,12 @@
 // Shows the Page Info bubble Safe Browsing warning after detecting the
 // enterprise user has re-used an existing password on a site, e.g. due to
 // phishing.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewDialogBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewDialogBrowserTest,
                        InvokeUi_EnterprisePasswordReuse) {
   ShowAndVerifyUi();
 }
+
+// Run tests with kPageInfoV2Desktop flag enabled and disabled.
+INSTANTIATE_TEST_SUITE_P(All,
+                         PageInfoBubbleViewDialogBrowserTest,
+                         ::testing::Values(false, true));
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
index 3efca19..6a92714 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/page_info/features.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/safe_browsing/content/browser/password_protection/password_protection_test_util.h"
 #include "components/safe_browsing/core/browser/password_protection/metrics_util.h"
@@ -86,11 +87,23 @@
 }  // namespace
 
 // This test suite tests functionality that requires Sync to be active.
-class PageInfoBubbleViewSyncBrowserTest : public SyncTest {
+class PageInfoBubbleViewSyncBrowserTest
+    : public SyncTest,
+      public ::testing::WithParamInterface<bool> {
  public:
-  PageInfoBubbleViewSyncBrowserTest() : SyncTest(SINGLE_CLIENT) {}
+  PageInfoBubbleViewSyncBrowserTest() : SyncTest(SINGLE_CLIENT) {
+    feature_list_.InitWithFeatureState(page_info::kPageInfoV2Desktop,
+                                       is_page_info_v2_enabled());
+  }
+
+  PageInfoBubbleViewSyncBrowserTest(
+      const PageInfoBubbleViewSyncBrowserTest& chip) = delete;
+  PageInfoBubbleViewSyncBrowserTest& operator=(
+      const PageInfoBubbleViewSyncBrowserTest& chip) = delete;
 
  protected:
+  bool is_page_info_v2_enabled() const { return GetParam(); }
+
   void SetupSyncForAccount(Profile* profile) {
     syncer::SyncServiceImpl* sync_service =
         SyncServiceFactory::GetAsSyncServiceImplForProfile(profile);
@@ -130,18 +143,18 @@
   }
 
   const std::u16string GetPageInfoBubbleViewDetailText() {
-    PageInfoBubbleView* page_info_bubble_view =
-        static_cast<PageInfoBubbleView*>(
-            PageInfoBubbleView::GetPageInfoBubbleForTesting());
-    return page_info_bubble_view->details_text();
+    auto* label =
+        PageInfoBubbleView::GetPageInfoBubbleForTesting()->GetViewByID(
+            PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL);
+    return static_cast<views::StyledLabel*>(label)->GetText();
   }
 
-  DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleViewSyncBrowserTest);
+  base::test::ScopedFeatureList feature_list_;
 };
 
 // Test opening page info bubble that matches
 // SB_THREAT_TYPE_GAIA_PASSWORD_REUSE threat type.
-IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewSyncBrowserTest,
+IN_PROC_BROWSER_TEST_P(PageInfoBubbleViewSyncBrowserTest,
                        VerifySignInPasswordReusePageInfoBubble) {
   Profile* profile = browser()->profile();
   // PageInfo calls GetPasswordProtectionReusedPasswordAccountType which checks
@@ -187,7 +200,8 @@
       security_state::MALICIOUS_CONTENT_STATUS_SIGNED_IN_SYNC_PASSWORD_REUSE,
       visible_security_state->malicious_content_status);
   ASSERT_EQ(
-      l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_SYNC),
+      l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS_SYNC) +
+          u" " + l10n_util::GetStringUTF16(IDS_LEARN_MORE),
       GetPageInfoBubbleViewDetailText());
 
   // Verify these two buttons are showing.
@@ -223,3 +237,8 @@
   EXPECT_EQ(security_state::MALICIOUS_CONTENT_STATUS_NONE,
             visible_security_state->malicious_content_status);
 }
+
+// Run tests with kPageInfoV2Desktop flag enabled and disabled.
+INSTANTIATE_TEST_SUITE_P(All,
+                         PageInfoBubbleViewSyncBrowserTest,
+                         ::testing::Values(false, true));
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
index 7127f416..1c9a0ac1 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_unittest.cc
@@ -13,6 +13,8 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
+#include "chrome/browser/ui/hats/mock_trust_safety_sentiment_service.h"
+#include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h"
 #include "chrome/browser/ui/views/hover_button.h"
 #include "chrome/browser/ui/views/page_info/chosen_object_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_hover_button.h"
@@ -213,6 +215,12 @@
     parent_window_ = new views::Widget();
     parent_window_->Init(std::move(parent_params));
 
+    mock_sentiment_service_ = static_cast<MockTrustSafetySentimentService*>(
+        TrustSafetySentimentServiceFactory::GetInstance()
+            ->SetTestingFactoryAndUse(
+                web_contents_helper_.profile(),
+                base::BindRepeating(&BuildMockTrustSafetySentimentService)));
+
     content::WebContents* web_contents = web_contents_helper_.web_contents();
     content_settings::PageSpecificContentSettings::CreateForWebContents(
         web_contents,
@@ -232,6 +240,7 @@
   ScopedWebContentsTestHelper web_contents_helper_;
   views::ScopedViewsTestHelper views_helper_{
       std::make_unique<ChromeTestViewsDelegate<>>()};
+  MockTrustSafetySentimentService* mock_sentiment_service_;
 
   views::Widget* parent_window_ = nullptr;  // Weak. Owned by the NativeWidget.
   std::unique_ptr<test::PageInfoBubbleViewTestApi> api_;
@@ -371,6 +380,7 @@
 
 // Test UI construction and reconstruction with USB devices.
 TEST_F(PageInfoBubbleViewTest, SetPermissionInfoWithUsbDevice) {
+  EXPECT_CALL(*mock_sentiment_service_, InteractedWithPageInfo);
   constexpr size_t kExpectedChildren = 0;
   EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
 
@@ -466,6 +476,7 @@
 // Test UI construction and reconstruction with both user and policy USB
 // devices.
 TEST_F(PageInfoBubbleViewTest, SetPermissionInfoWithUserAndPolicyUsbDevices) {
+  EXPECT_CALL(*mock_sentiment_service_, InteractedWithPageInfo);
   constexpr size_t kExpectedChildren = 0;
   EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
 
@@ -711,6 +722,16 @@
             api_->closed_reason());
 }
 
+TEST_F(PageInfoBubbleViewTest, CheckHeaderInteractions) {
+  // Confirm that interactions with the header tips are reported to the
+  // sentiment service correctly.
+  EXPECT_CALL(*mock_sentiment_service_, InteractedWithPageInfo).Times(2);
+  const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
+                             ui::EventTimeForNow(), 0, 0);
+  api_->view()->SecurityDetailsClicked(event);
+  api_->view()->ResetDecisionsClicked();
+}
+
 TEST_F(PageInfoBubbleViewTest, CertificateButtonShowsEvCertDetails) {
   SecurityStateTabHelper::CreateForWebContents(
       web_contents_helper_.web_contents());
diff --git a/chrome/browser/ui/views/page_info/page_info_main_view.cc b/chrome/browser/ui/views/page_info/page_info_main_view.cc
index 5fe29b6..14a7c7de 100644
--- a/chrome/browser/ui/views/page_info/page_info_main_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_main_view.cc
@@ -7,6 +7,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/reputation/safety_tip_ui_helper.h"
+#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
@@ -16,8 +17,10 @@
 #include "chrome/browser/ui/views/page_info/page_info_navigation_handler.h"
 #include "chrome/browser/ui/views/page_info/page_info_security_content_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
+#include "chrome/browser/ui/views/page_info/permission_toggle_row_view.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
 #include "chrome/common/url_constants.h"
+#include "components/permissions/permission_util.h"
 #include "components/strings/grit/components_chromium_strings.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -147,6 +150,11 @@
 void PageInfoMainView::SetPermissionInfo(
     const PermissionInfoList& permission_info_list,
     ChosenObjectInfoList chosen_object_info_list) {
+  if (permission_info_list.empty() && chosen_object_info_list.empty()) {
+    permissions_view_->RemoveAllChildViews(true);
+    return;
+  }
+
   // This method is called when Page Info is constructed/displayed, then called
   // again whenever permissions/chosen objects change while the bubble is still
   // opened. Once Page Info is displaying a non-zero number of permissions, all
@@ -157,20 +165,29 @@
   // case that can be recovered from by closing & reopening the bubble.
   // TODO(patricialor): Investigate removing callsites to this method other than
   // the constructor.
-  if (!permissions_view_->children().empty())
+  if (!permissions_view_->children().empty()) {
+    UpdateResetButton(permission_info_list);
     return;
+  }
 
-  if (permission_info_list.empty() && chosen_object_info_list.empty())
-    return;
-
-  permissions_view_->SetLayoutManager(std::make_unique<views::BoxLayout>())
-      ->SetOrientation(views::BoxLayout::Orientation::kVertical);
+  permissions_view_->SetLayoutManager(std::make_unique<views::FlexLayout>())
+      ->SetOrientation(views::LayoutOrientation::kVertical);
   permissions_view_->AddChildView(PageInfoViewFactory::CreateSeparator());
 
+  // If there is a permission that supports one time grants, offset all other
+  // permissions to align toggles.
+  bool should_show_spacer = false;
+  for (const auto& permission : permission_info_list) {
+    if (permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+            permission.type)) {
+      should_show_spacer = true;
+    }
+  }
+
   for (const auto& permission : permission_info_list) {
     auto* selector = permissions_view_->AddChildView(
         std::make_unique<PermissionToggleRowView>(
-            ui_delegate_, navigation_handler_, permission));
+            ui_delegate_, navigation_handler_, permission, should_show_spacer));
     selector->AddObserver(this);
     selector_rows_.push_back(std::move(selector));
   }
@@ -182,14 +199,72 @@
         presenter_->GetChooserContextFromUIInfo(object->ui_info)
             ->GetObjectDisplayName(object->chooser_object->value));
     object_view->AddObserver(this);
-    permissions_view_->AddChildView(std::move(object_view));
+    chosen_object_rows_.push_back(
+        permissions_view_->AddChildView(std::move(object_view)));
   }
 
+  const int controls_spacing = ChromeLayoutProvider::Get()->GetDistanceMetric(
+      views::DISTANCE_RELATED_CONTROL_VERTICAL);
+  reset_button_ = permissions_view_->AddChildView(
+      std::make_unique<views::MdTextButton>(base::BindRepeating(
+          [=](PageInfoMainView* view) {
+            for (auto* selector_row : view->selector_rows_) {
+              selector_row->ResetPermission();
+            }
+            for (auto* object_row : view->chosen_object_rows_) {
+              object_row->ResetPermission();
+            }
+            view->chosen_object_rows_.clear();
+            view->PreferredSizeChanged();
+          },
+          base::Unretained(this))));
+  reset_button_->SetProperty(views::kCrossAxisAlignmentKey,
+                             views::LayoutAlignment::kStart);
+  ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get();
+  // Offset the reset button by left button padding, icon size and distance
+  // between icon and label to match text in the row above.
+  const int side_offset =
+      layout_provider
+          ->GetInsetsMetric(ChromeInsetsMetric::INSETS_PAGE_INFO_HOVER_BUTTON)
+          .left() +
+      GetLayoutConstant(PAGE_INFO_ICON_SIZE) +
+      layout_provider->GetDistanceMetric(
+          views::DISTANCE_RELATED_LABEL_HORIZONTAL);
+  reset_button_->SetProperty(
+      views::kMarginsKey,
+      gfx::Insets(controls_spacing, side_offset, controls_spacing, 0));
+
+  // If a permission is in a non-default state or chooser object is present,
+  // show reset button.
+  reset_button_->SetVisible(false);
+  UpdateResetButton(permission_info_list);
   permissions_view_->AddChildView(PageInfoViewFactory::CreateSeparator());
 
   PreferredSizeChanged();
 }
 
+void PageInfoMainView::UpdateResetButton(
+    const PermissionInfoList& permission_info_list) {
+  reset_button_->SetEnabled(false);
+  int num_permissions = 0;
+  for (const auto& permission : permission_info_list) {
+    if (permission.setting != CONTENT_SETTING_DEFAULT) {
+      reset_button_->SetEnabled(true);
+      reset_button_->SetVisible(true);
+    }
+    num_permissions++;
+  }
+  for (auto* object_view : chosen_object_rows_) {
+    if (object_view->GetVisible()) {
+      reset_button_->SetEnabled(true);
+      reset_button_->SetVisible(true);
+      num_permissions++;
+    }
+  }
+  reset_button_->SetText(l10n_util::GetPluralStringFUTF16(
+      IDS_PAGE_INFO_RESET_PERMISSIONS, num_permissions));
+}
+
 void PageInfoMainView::SetIdentityInfo(const IdentityInfo& identity_info) {
   std::unique_ptr<PageInfoUI::SecurityDescription> security_description =
       GetSecurityDescription(identity_info);
@@ -201,6 +276,7 @@
     // base::Unretained(navigation_handler_) is safe because navigation_handler_
     // is the bubble view which is the owner of this view and therefore will
     // always exist when this view exists.
+    // TODO(crbug.com/1225563): Replace with actual strings.
     connection_button_ = security_container_view_->AddChildView(
         std::make_unique<PageInfoHoverButton>(
             base::BindRepeating(&PageInfoNavigationHandler::OpenSecurityPage,
@@ -208,7 +284,7 @@
             PageInfoViewFactory::GetConnectionSecureIcon(), 0, std::u16string(),
             PageInfoViewFactory::
                 VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_SECURITY_INFORMATION,
-            std::u16string(), std::u16string(),
+            u"Open security subpage", std::u16string(),
             PageInfoViewFactory::GetOpenSubpageIcon())
             .release());
     connection_button_->SetTitleText(security_description->summary);
@@ -303,6 +379,7 @@
     const PageInfoUI::ChosenObjectInfo& info) {
   presenter_->OnSiteChosenObjectDeleted(info.ui_info,
                                         info.chooser_object->value);
+  PreferredSizeChanged();
 }
 
 std::unique_ptr<views::View> PageInfoMainView::CreateContainerView() {
diff --git a/chrome/browser/ui/views/page_info/page_info_main_view.h b/chrome/browser/ui/views/page_info/page_info_main_view.h
index bb65eaa6..a94eaf3 100644
--- a/chrome/browser/ui/views/page_info/page_info_main_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_main_view.h
@@ -5,19 +5,27 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_PAGE_INFO_PAGE_INFO_MAIN_VIEW_H_
 #define CHROME_BROWSER_UI_VIEWS_PAGE_INFO_PAGE_INFO_MAIN_VIEW_H_
 
+#include <map>
+#include <vector>
+
 #include "build/build_config.h"
 #include "chrome/browser/ui/views/page_info/chosen_object_view_observer.h"
-#include "chrome/browser/ui/views/page_info/page_info_hover_button.h"
 #include "chrome/browser/ui/views/page_info/permission_selector_row_observer.h"
-#include "chrome/browser/ui/views/page_info/permission_toggle_row_view.h"
-#include "chrome/browser/ui/views/page_info/security_information_view.h"
 #include "components/page_info/page_info_ui.h"
-#include "content/public/browser/web_contents_observer.h"
+#include "device/vr/buildflags/buildflags.h"
 #include "ui/views/view.h"
 
+namespace views {
+class Label;
+class LabelButton;
+}  // namespace views
+
 class ChromePageInfoUiDelegate;
-class PageInfoSecurityContentView;
+class ChosenObjectView;
+class PageInfoHoverButton;
 class PageInfoNavigationHandler;
+class PageInfoSecurityContentView;
+class PermissionToggleRowView;
 
 // The main view of the page info, contains security information, permissions
 // and  site-related settings. This is used in the experimental
@@ -56,6 +64,8 @@
   const std::u16string details_text() const { return details_text_; }
 
  private:
+  friend class PageInfoBubbleViewDialogBrowserTest;
+
   // Creates a view with vertical box layout that will used a container for
   // other views.
   std::unique_ptr<views::View> CreateContainerView() WARN_UNUSED_RESULT;
@@ -72,6 +82,11 @@
   // be alive to finish handling the mouse or keyboard click.
   void HandleMoreInfoRequestAsync(int view_id);
 
+  // Makes the permission reset button visible if there is any permission and
+  // enables it if any permission is in a non-default state. Also updates
+  // the label depending on the number of visible permissions.
+  void UpdateResetButton(const PermissionInfoList& permission_info_list);
+
   PageInfo* presenter_;
 
   ChromePageInfoUiDelegate* ui_delegate_;
@@ -110,10 +125,14 @@
   // |Permission| changes.
   std::vector<PermissionToggleRowView*> selector_rows_;
 
+  std::vector<ChosenObjectView*> chosen_object_rows_;
+
   views::Label* title_ = nullptr;
 
   views::View* security_container_view_ = nullptr;
 
+  views::LabelButton* reset_button_ = nullptr;
+
   base::WeakPtrFactory<PageInfoMainView> weak_factory_{this};
 };
 
diff --git a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.cc b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.cc
index b9e88ac8..139143ca 100644
--- a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.cc
@@ -43,13 +43,6 @@
   const int top_margin =
       layout_provider->GetInsetsMetric(views::INSETS_DIALOG).top();
   set_margins(gfx::Insets(top_margin, 0, bottom_margin, 0));
-
-  views::BubbleDialogDelegateView::CreateBubble(this);
-
-  // CreateBubble() may not set our size synchronously so explicitly set it here
-  // before PageInfo updates trigger child layouts.
-  SetSize(GetPreferredSize());
-
   ui_delegate_ = std::make_unique<ChromePageInfoUiDelegate>(profile, url);
   presenter_ = std::make_unique<PageInfo>(
       std::make_unique<ChromePageInfoDelegate>(web_contents), web_contents,
@@ -59,9 +52,10 @@
 
   SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical));
-  page_container_ = AddChildView(std::make_unique<PageSwitcherView>());
-  OpenMainPage();
-  SizeToContents();
+  page_container_ = AddChildView(
+      std::make_unique<PageSwitcherView>(view_factory_->CreateMainPageView()));
+
+  views::BubbleDialogDelegateView::CreateBubble(this);
 }
 
 PageInfoNewBubbleView::~PageInfoNewBubbleView() = default;
@@ -83,6 +77,10 @@
       views::Widget::ClosedReason::kCloseButtonClicked);
 }
 
+void PageInfoNewBubbleView::DidChangeVisibleSecurityState() {
+  presenter_->UpdateSecurityState();
+}
+
 void PageInfoNewBubbleView::OnWidgetDestroying(views::Widget* widget) {
   PageInfoBubbleViewBase::OnWidgetDestroying(widget);
 
diff --git a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
index 5fc63cd2..69cacc5 100644
--- a/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_new_bubble_view.h
@@ -37,7 +37,13 @@
   void OpenPermissionPage(ContentSettingsType type) override;
   void CloseBubble() override;
 
+  // WebContentsObserver:
+  void DidChangeVisibleSecurityState() override;
+
  private:
+  friend class PageInfoBubbleViewBrowserTest;
+  friend class PageInfoBubbleViewDialogBrowserTest;
+
   // PageInfoBubbleViewBase:
   gfx::Size CalculatePreferredSize() const override;
   void OnWidgetDestroying(views::Widget* widget) override;
diff --git a/chrome/browser/ui/views/page_info/page_info_permission_content_view.cc b/chrome/browser/ui/views/page_info/page_info_permission_content_view.cc
index 42476dd..d12cf07 100644
--- a/chrome/browser/ui/views/page_info/page_info_permission_content_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_permission_content_view.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/page_info/page_info_hover_button.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
-#include "components/permissions/features.h"
+#include "components/permissions/permission_util.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -22,14 +22,6 @@
 #include "ui/views/controls/separator.h"
 #include "ui/views/layout/flex_layout.h"
 
-namespace {
-bool CanBeAllowedOnce(ContentSettingsType type) {
-  return base::FeatureList::IsEnabled(
-             permissions::features::kOneTimeGeolocationPermission) &&
-         type == ContentSettingsType::GEOLOCATION;
-}
-}  // namespace
-
 PageInfoPermissionContentView::PageInfoPermissionContentView(
     PageInfo* presenter,
     ChromePageInfoUiDelegate* ui_delegate,
@@ -70,6 +62,15 @@
       views::style::STYLE_SECONDARY));
   state_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
 
+  // Add extra details as sublabel.
+  std::u16string detail = ui_delegate_->GetPermissionDetail(type);
+  if (!detail.empty()) {
+    auto detail_label = std::make_unique<views::Label>(
+        detail, views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY);
+    detail_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+    label_wrapper->AddChildView(std::move(detail_label));
+  }
+
   remember_setting_ =
       label_wrapper->AddChildView(std::make_unique<views::Checkbox>(
           l10n_util::GetStringUTF16(
@@ -97,7 +98,7 @@
   toggle_button_->SetProperty(views::kMarginsKey, gfx::Insets(margin, 0));
 
   AddChildView(PageInfoViewFactory::CreateSeparator());
-  // TODO(olesiamarukhno): Add toolip for manage button.
+  // TODO(crbug.com/1225563): Replace with actual strings.
   AddChildView(std::make_unique<PageInfoHoverButton>(
       base::BindRepeating(
           [](PageInfoPermissionContentView* view) {
@@ -106,7 +107,8 @@
           this),
       PageInfoViewFactory::GetSiteSettingsIcon(),
       IDS_PAGE_INFO_PERMISSIONS_SUBPAGE_MANAGE_BUTTON, std::u16string(), 0,
-      std::u16string(), std::u16string()));
+      u"Open permission settings", std::u16string(),
+      PageInfoViewFactory::GetLaunchIcon()));
 
   presenter_->InitializeUiState(this);
 }
@@ -127,73 +129,37 @@
   permission_ = *permission_it;
   icon_->SetImage(PageInfoViewFactory::GetPermissionIcon(permission_));
 
-  state_label_->SetText(PageInfoUI::PermissionActionToUIString(
-      ui_delegate_, permission_.type, permission_.setting,
-      permission_.default_setting, permission_.source,
-      permission_.is_one_time));
+  std::u16string auto_blocked_label =
+      PageInfoUI::PermissionAutoBlockedToUIString(ui_delegate_, permission_);
+  // TODO(olesiamarukhno): For pending request if available show a longer
+  // version of auto-block explanation here instead (same as in content
+  // settings bubble).
+  if (!auto_blocked_label.empty()) {
+    state_label_->SetText(auto_blocked_label);
+  } else {
+    state_label_->SetText(
+        PageInfoUI::PermissionStateToUIString(ui_delegate_, permission_));
+  }
 
-  auto setting = permission_.setting == CONTENT_SETTING_DEFAULT
-                     ? permission_.default_setting
-                     : permission_.setting;
-  toggle_button_->SetIsOn(setting == CONTENT_SETTING_ALLOW);
-
+  toggle_button_->SetIsOn(PageInfoUI::IsToggleOn(permission_));
   remember_setting_->SetChecked(!permission_.is_one_time &&
                                 permission_.setting != CONTENT_SETTING_DEFAULT);
+  remember_setting_->SetVisible(
+      permissions::PermissionUtil::IsPermission(type_) &&
+      permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+          permission_.type) &&
+      (permission_.default_setting != CONTENT_SETTING_BLOCK ||
+       permission_.setting != CONTENT_SETTING_DEFAULT));
   PreferredSizeChanged();
 }
 
 void PageInfoPermissionContentView::OnToggleButtonPressed() {
-  switch (permission_.setting) {
-    case CONTENT_SETTING_ALLOW:
-      permission_.setting = permission_.is_one_time ? CONTENT_SETTING_DEFAULT
-                                                    : CONTENT_SETTING_BLOCK;
-      permission_.is_one_time = false;
-      break;
-    case CONTENT_SETTING_BLOCK:
-      permission_.setting = CONTENT_SETTING_ALLOW;
-      permission_.is_one_time = false;
-      break;
-    case CONTENT_SETTING_DEFAULT:
-      permission_.setting = CONTENT_SETTING_ALLOW;
-      // If one-time permissions are supported, permission should go from
-      // default state to allow once state, not directly to allow.
-      if (CanBeAllowedOnce(permission_.type)) {
-        permission_.is_one_time = true;
-      }
-      break;
-    default:
-      break;
-  }
+  PageInfoUI::ToggleBetweenAllowAndBlock(permission_);
   PermissionChanged();
 }
 
 void PageInfoPermissionContentView::OnRememberSettingPressed() {
-  switch (permission_.setting) {
-    case CONTENT_SETTING_ALLOW:
-      // If one-time permissions are supported, toggle is_one_time.
-      // Otherwise, go directly to default.
-      if (CanBeAllowedOnce(permission_.type)) {
-        permission_.is_one_time = !permission_.is_one_time;
-      } else {
-        permission_.setting = CONTENT_SETTING_DEFAULT;
-      }
-      break;
-    case CONTENT_SETTING_BLOCK:
-      permission_.setting = CONTENT_SETTING_DEFAULT;
-      break;
-    case CONTENT_SETTING_DEFAULT:
-      // When user checks the checkbox to remember the permission setting,
-      // it should go to the "allow" state, only if default setting is
-      // explicitly allow.
-      if (permission_.default_setting == CONTENT_SETTING_ALLOW) {
-        permission_.setting = CONTENT_SETTING_ALLOW;
-      } else {
-        permission_.setting = CONTENT_SETTING_BLOCK;
-      }
-      break;
-    default:
-      break;
-  }
+  PageInfoUI::ToggleBetweenRememberAndForget(permission_);
   PermissionChanged();
 }
 
diff --git a/chrome/browser/ui/views/page_info/page_info_row_view.cc b/chrome/browser/ui/views/page_info/page_info_row_view.cc
index de091688..30a6b6c 100644
--- a/chrome/browser/ui/views/page_info/page_info_row_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_row_view.cc
@@ -53,7 +53,7 @@
   return title_->GetLineHeight();
 }
 
-void PageInfoRowView::AddSecondaryLabel(std::u16string text) {
+views::Label* PageInfoRowView::AddSecondaryLabel(std::u16string text) {
   auto secondary_label = std::make_unique<views::Label>(
       text, views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY);
   secondary_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
@@ -66,7 +66,7 @@
           .WithWeight(1));
   secondary_label->SetProperty(views::kCrossAxisAlignmentKey,
                                views::LayoutAlignment::kStart);
-  labels_wrapper_->AddChildView(std::move(secondary_label));
+  return labels_wrapper_->AddChildView(std::move(secondary_label));
 }
 
 gfx::Size PageInfoRowView::CalculatePreferredSize() const {
diff --git a/chrome/browser/ui/views/page_info/page_info_row_view.h b/chrome/browser/ui/views/page_info/page_info_row_view.h
index 68e1d92..9fa74c0 100644
--- a/chrome/browser/ui/views/page_info/page_info_row_view.h
+++ b/chrome/browser/ui/views/page_info/page_info_row_view.h
@@ -27,7 +27,7 @@
 
   void SetIcon(const ui::ImageModel image);
   void SetTitle(std::u16string title);
-  void AddSecondaryLabel(std::u16string text);
+  views::Label* AddSecondaryLabel(std::u16string text);
   template <typename T>
   T* AddControl(std::unique_ptr<T> control_view) {
     control_view->SetProperty(views::kInternalPaddingKey,
diff --git a/chrome/browser/ui/views/page_info/page_info_security_content_view.cc b/chrome/browser/ui/views/page_info/page_info_security_content_view.cc
index c906693..cb11ff1 100644
--- a/chrome/browser/ui/views/page_info/page_info_security_content_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_security_content_view.cc
@@ -136,6 +136,7 @@
             },
             this));
   }
+  PreferredSizeChanged();
 }
 
 void PageInfoSecurityContentView::ResetDecisionsClicked() {
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.cc b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
index 774d9b5..61d00d3 100644
--- a/chrome/browser/ui/views/page_info/page_info_view_factory.cc
+++ b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
@@ -7,12 +7,15 @@
 #include "build/build_config.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
+#include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/page_info/page_info_main_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_navigation_handler.h"
 #include "chrome/browser/ui/views/page_info/page_info_permission_content_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_security_content_view.h"
+#include "components/page_info/features.h"
 #include "components/page_info/page_info.h"
+#include "components/permissions/permission_util.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -152,8 +155,12 @@
                           base::Unretained(navigation_handler_)),
       vector_icons::kArrowBackIcon);
   views::InstallCircleHighlightPathGenerator(back_button.get());
+  back_button->SetID(VIEW_ID_BACK_BUTTON);
+  back_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK));
   back_button->SetProperty(views::kInternalPaddingKey,
                            back_button->GetInsets());
+  // TODO(crbug.com/1225563): Replace with actual strings.
+  back_button->SetTooltipText(u"Back to main page");
   header->AddChildView(std::move(back_button));
 
   auto* label_wrapper = header->AddChildView(CreateLabelWrapper());
@@ -173,6 +180,7 @@
   auto close_button = views::BubbleFrameView::CreateCloseButton(
       base::BindRepeating(&PageInfoNavigationHandler::CloseBubble,
                           base::Unretained(navigation_handler_)));
+  close_button->SetID(VIEW_ID_PAGE_INFO_CLOSE_BUTTON);
   close_button->SetVisible(true);
   close_button->SetProperty(views::kInternalPaddingKey,
                             close_button->GetInsets());
@@ -281,10 +289,14 @@
   ContentSetting setting = info.setting == CONTENT_SETTING_DEFAULT
                                ? info.default_setting
                                : info.setting;
+  const bool show_blocked_badge =
+      base::FeatureList::IsEnabled(page_info::kPageInfoV2Desktop) &&
+              !permissions::PermissionUtil::IsGuardContentSetting(info.type)
+          ? setting == CONTENT_SETTING_BLOCK || setting == CONTENT_SETTING_ASK
+          : setting == CONTENT_SETTING_BLOCK;
   return ui::ImageModel::FromVectorIcon(
       *icon, ui::NativeTheme::kColorId_DefaultIconColor, GetIconSize(),
-      (setting == CONTENT_SETTING_BLOCK) ? &vector_icons::kBlockedBadgeIcon
-                                         : nullptr);
+      show_blocked_badge ? &vector_icons::kBlockedBadgeIcon : nullptr);
 }
 
 // static
@@ -377,8 +389,13 @@
 }
 
 // static
-const ui::ImageModel PageInfoViewFactory::GetManagedIcon() {
+const ui::ImageModel PageInfoViewFactory::GetManagedPermissionIcon(
+    const PageInfo::PermissionInfo& info) {
+  const gfx::VectorIcon& managed_vector_icon =
+      info.source == content_settings::SETTING_SOURCE_EXTENSION
+          ? vector_icons::kExtensionIcon
+          : vector_icons::kBusinessIcon;
   return ui::ImageModel::FromVectorIcon(
-      vector_icons::kBusinessIcon, ui::NativeTheme::kColorId_DefaultIconColor,
+      managed_vector_icon, ui::NativeTheme::kColorId_DefaultIconColor,
       GetIconSize());
 }
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.h b/chrome/browser/ui/views/page_info/page_info_view_factory.h
index 8f61b24..f384b712 100644
--- a/chrome/browser/ui/views/page_info/page_info_view_factory.h
+++ b/chrome/browser/ui/views/page_info/page_info_view_factory.h
@@ -38,6 +38,11 @@
     VIEW_ID_PAGE_INFO_BUTTON_LEAVE_SITE,
     VIEW_ID_PAGE_INFO_BUTTON_IGNORE_WARNING,
     VIEW_ID_PAGE_INFO_LINK_OR_BUTTON_SECURITY_INFORMATION,
+    VIEW_ID_PAGE_INFO_PERMISSION_VIEW,
+    VIEW_ID_PAGE_INFO_SECURITY_SUMMARY_LABEL,
+    VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL,
+    VIEW_ID_PAGE_INFO_BACK_BUTTON,
+    VIEW_ID_PAGE_INFO_CLOSE_BUTTON,
   };
 
   // Creates a separator view with padding on top and bottom. Use with flex
@@ -86,7 +91,8 @@
   static const ui::ImageModel GetOpenSubpageIcon();
 
   // Returns the icon for a permission in a state not managed by the user.
-  static const ui::ImageModel GetManagedIcon();
+  static const ui::ImageModel GetManagedPermissionIcon(
+      const PageInfo::PermissionInfo& info);
 
   std::unique_ptr<views::View> CreateMainPageView() WARN_UNUSED_RESULT;
   std::unique_ptr<views::View> CreateSecurityPageView() WARN_UNUSED_RESULT;
diff --git a/chrome/browser/ui/views/page_info/page_switcher_view.cc b/chrome/browser/ui/views/page_info/page_switcher_view.cc
index 6342d36..62d23c0 100644
--- a/chrome/browser/ui/views/page_info/page_switcher_view.cc
+++ b/chrome/browser/ui/views/page_info/page_switcher_view.cc
@@ -6,8 +6,9 @@
 
 #include "ui/views/layout/fill_layout.h"
 
-PageSwitcherView::PageSwitcherView() {
+PageSwitcherView::PageSwitcherView(std::unique_ptr<views::View> initial_page) {
   SetLayoutManager(std::make_unique<views::FillLayout>());
+  current_page_ = AddChildView(std::move(initial_page));
 }
 
 PageSwitcherView::~PageSwitcherView() = default;
diff --git a/chrome/browser/ui/views/page_info/page_switcher_view.h b/chrome/browser/ui/views/page_info/page_switcher_view.h
index 45037da..ad16f20 100644
--- a/chrome/browser/ui/views/page_info/page_switcher_view.h
+++ b/chrome/browser/ui/views/page_info/page_switcher_view.h
@@ -12,7 +12,7 @@
 // TODO(crbug.com/1188101): Implement animation when switching.
 class PageSwitcherView : public views::View {
  public:
-  PageSwitcherView();
+  explicit PageSwitcherView(std::unique_ptr<views::View> initial_page);
   PageSwitcherView(const PageSwitcherView&) = delete;
   PageSwitcherView& operator=(const PageSwitcherView&) = delete;
   ~PageSwitcherView() override;
diff --git a/chrome/browser/ui/views/page_info/permission_toggle_row_view.cc b/chrome/browser/ui/views/page_info/permission_toggle_row_view.cc
index 849efa4..343a332 100644
--- a/chrome/browser/ui/views/page_info/permission_toggle_row_view.cc
+++ b/chrome/browser/ui/views/page_info/permission_toggle_row_view.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/page_info/permission_toggle_row_view.h"
 
+#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/page_info/chrome_page_info_ui_delegate.h"
 #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
@@ -13,7 +14,9 @@
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "components/permissions/features.h"
 #include "components/permissions/permission_util.h"
+#include "components/strings/grit/components_strings.h"
 #include "components/vector_icons/vector_icons.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/controls/button/image_button_factory.h"
 #include "ui/views/controls/button/toggle_button.h"
@@ -25,33 +28,37 @@
 PermissionToggleRowView::PermissionToggleRowView(
     ChromePageInfoUiDelegate* delegate,
     PageInfoNavigationHandler* navigation_handler,
-    const PageInfo::PermissionInfo& permission)
-    : permission_(permission), navigation_handler_(navigation_handler) {
+    const PageInfo::PermissionInfo& permission,
+    bool should_show_spacer_view)
+    : permission_(permission),
+      delegate_(delegate),
+      navigation_handler_(navigation_handler) {
   SetUseDefaultFillLayout(true);
   row_view_ = AddChildView(std::make_unique<PageInfoRowView>());
   row_view_->SetTitle(PageInfoUI::PermissionTypeToUIString(permission.type));
-  row_view_->SetIcon(PageInfoViewFactory::GetPermissionIcon(permission));
 
   // Add extra details as sublabel.
   std::u16string detail = delegate->GetPermissionDetail(permission.type);
   if (!detail.empty())
     row_view_->AddSecondaryLabel(detail);
 
-  // Show the permission decision reason, if it was not the user.
-  // TODO(olesiamarukhno): Add correct handling of the managed states: add
-  // showing correct state text "allowed" instead of "allow", "not allowed"
-  // instead of "block"; update tooltip for managed state; update the reason
-  // label to not include managed state, maybe merge it with permission detail.
-  std::u16string reason =
-      PageInfoUI::PermissionDecisionReasonToUIString(delegate, permission);
-  if (!reason.empty())
-    row_view_->AddSecondaryLabel(reason);
-
   if (permission.source == content_settings::SETTING_SOURCE_USER) {
-    InitForUserSource();
+    // If permission is not allowed because of security reasons, show a label
+    // with explanations instead of the controls.
+    std::u16string reason =
+        delegate->GetAutomaticallyBlockedReason(permission_.type);
+    if (!reason.empty()) {
+      row_view_->AddControl(std::make_unique<views::Label>(
+          delegate->GetAutomaticallyBlockedReason(permission_.type),
+          views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY));
+    } else {
+      InitForUserSource(should_show_spacer_view);
+    }
   } else {
     InitForManagedSource(delegate);
   }
+
+  UpdateUiOnPermissionChanged();
 }
 
 PermissionToggleRowView::~PermissionToggleRowView() = default;
@@ -61,79 +68,62 @@
   observer_list_.AddObserver(observer);
 }
 
-void PermissionToggleRowView::PermissionChanged(
-    const PageInfo::PermissionInfo& permission) {
-  // Change the permission icon to reflect the selected setting.
-  row_view_->SetIcon(PageInfoViewFactory::GetPermissionIcon(permission));
+void PermissionToggleRowView::PermissionChanged() {
+  UpdateUiOnPermissionChanged();
 
   for (PermissionSelectorRowObserver& observer : observer_list_) {
-    observer.OnPermissionChanged(permission);
+    observer.OnPermissionChanged(permission_);
   }
 }
 
 void PermissionToggleRowView::OnToggleButtonPressed() {
-  switch (permission_.setting) {
-    case CONTENT_SETTING_ALLOW:
-      permission_.setting = permission_.is_one_time ? CONTENT_SETTING_DEFAULT
-                                                    : CONTENT_SETTING_BLOCK;
-      permission_.is_one_time = false;
-      break;
-    case CONTENT_SETTING_BLOCK:
-      permission_.setting = CONTENT_SETTING_ALLOW;
-      permission_.is_one_time = false;
-      break;
-    case CONTENT_SETTING_DEFAULT:
-      permission_.setting = CONTENT_SETTING_ALLOW;
-      // If one-time permissions are supported, permission should go from
-      // default state to allow once state, not directly to allow.
-      if (base::FeatureList::IsEnabled(
-              permissions::features::kOneTimeGeolocationPermission) &&
-          permission_.type == ContentSettingsType::GEOLOCATION) {
-        permission_.is_one_time = true;
-      }
-      break;
-    default:
-      break;
-  }
-  PermissionChanged(permission_);
+  PageInfoUI::ToggleBetweenAllowAndBlock(permission_);
+  PermissionChanged();
 }
 
-void PermissionToggleRowView::InitForUserSource() {
+void PermissionToggleRowView::InitForUserSource(bool should_show_spacer_view) {
   const int icon_label_spacing = ChromeLayoutProvider::Get()->GetDistanceMetric(
       views::DISTANCE_RELATED_LABEL_HORIZONTAL);
 
   auto toggle_button = std::make_unique<views::ToggleButton>(
       base::BindRepeating(&PermissionToggleRowView::OnToggleButtonPressed,
                           base::Unretained(this)));
-  toggle_button->SetIsOn(permission_.setting == CONTENT_SETTING_ALLOW);
   toggle_button->SetPreferredSize({toggle_button->GetPreferredSize().width(),
                                    row_view_->GetFirstLineHeight()});
   toggle_button->SetProperty(views::kMarginsKey,
                              gfx::Insets(0, icon_label_spacing));
-  row_view_->AddControl(std::move(toggle_button));
+  // TODO(crbug.com/1225563): Replace with actual strings.
+  toggle_button->SetAccessibleName(
+      u"Select state for " +
+      PageInfoUI::PermissionTypeToUIString(permission_.type) + u" permission.");
+  toggle_button_ = row_view_->AddControl(std::move(toggle_button));
 
-  auto subpage_button = views::CreateVectorImageButtonWithNativeTheme(
-      base::BindRepeating(
-          [=](PermissionToggleRowView* row) {
-            row->navigation_handler_->OpenPermissionPage(row->permission_.type);
-          },
-          base::Unretained(this)),
-      vector_icons::kSubmenuArrowIcon);
-  views::InstallCircleHighlightPathGenerator(subpage_button.get());
   const int icon_size = GetLayoutConstant(PAGE_INFO_ICON_SIZE);
-  subpage_button->SetMinimumImageSize({icon_size, icon_size});
-
-  // If type isn't supported by the PermissionManager, don't show the button
-  // that opens subpage. Instead, use a spacer view to align this row with
-  // other rows.
-  if (!permissions::PermissionUtil::IsPermission(permission_.type)) {
-    auto spacer_view = std::make_unique<views::View>();
-    spacer_view->SetPreferredSize(subpage_button->GetMinimumImageSize());
-    row_view_->AddControl(std::move(spacer_view));
-    subpage_button->SetVisible(false);
+  if (permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+          permission_.type)) {
+    auto subpage_button = views::CreateVectorImageButtonWithNativeTheme(
+        base::BindRepeating(
+            [=](PermissionToggleRowView* row) {
+              row->navigation_handler_->OpenPermissionPage(
+                  row->permission_.type);
+            },
+            base::Unretained(this)),
+        vector_icons::kSubmenuArrowIcon);
+    views::InstallCircleHighlightPathGenerator(subpage_button.get());
+    subpage_button->SetMinimumImageSize({icon_size, icon_size});
+    row_view_->AddControl(std::move(subpage_button));
+  } else {
+    // If there is a permission that supports one time grants, offset all other
+    // permissions to align toggles.
+    if (should_show_spacer_view) {
+      auto spacer_view = std::make_unique<views::View>();
+      spacer_view->SetPreferredSize({icon_size, icon_size});
+      spacer_view_ = row_view_->AddControl(std::move(spacer_view));
+    } else {
+      toggle_button_->SetProperty(views::kMarginsKey,
+                                  gfx::Insets(0, icon_label_spacing, 0, 0));
+    }
   }
-
-  row_view_->AddControl(std::move(subpage_button));
 }
 
 void PermissionToggleRowView::InitForManagedSource(
@@ -141,20 +131,48 @@
   const int icon_label_spacing = ChromeLayoutProvider::Get()->GetDistanceMetric(
       views::DISTANCE_RELATED_LABEL_HORIZONTAL);
   auto state_label = std::make_unique<views::Label>(
-      PageInfoUI::PermissionActionToUIString(
-          delegate, permission_.type, permission_.setting,
-          permission_.default_setting, permission_.source,
-          permission_.is_one_time),
+      PageInfoUI::PermissionStateToUIString(delegate, permission_),
       views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY);
   state_label->SetProperty(views::kMarginsKey,
                            gfx::Insets(0, icon_label_spacing));
-  std::u16string reason =
-      PageInfoUI::PermissionDecisionReasonToUIString(delegate, permission_);
-  if (!reason.empty())
-    state_label->SetTooltipText(reason);
   row_view_->AddControl(std::move(state_label));
 
   auto managed_icon = std::make_unique<NonAccessibleImageView>();
-  managed_icon->SetImage(PageInfoViewFactory::GetManagedIcon());
+  managed_icon->SetImage(
+      PageInfoViewFactory::GetManagedPermissionIcon(permission_));
+  std::u16string managed_tooltip =
+      PageInfoUI::PermissionManagedTooltipToUIString(delegate, permission_);
+  managed_icon->SetTooltipText(managed_tooltip);
   row_view_->AddControl(std::move(managed_icon));
 }
+
+void PermissionToggleRowView::UpdateUiOnPermissionChanged() {
+  // Change the permission icon to reflect the selected setting.
+  row_view_->SetIcon(PageInfoViewFactory::GetPermissionIcon(permission_));
+
+  // Update toggle state if it is used.
+  if (toggle_button_) {
+    toggle_button_->SetIsOn(PageInfoUI::IsToggleOn(permission_));
+  }
+
+  // Reset |state_label_|, readd it after if needed.
+  if (state_label_) {
+    delete state_label_;
+    state_label_ = nullptr;
+  }
+
+  // Add explanation for the permission state if needed. This would be shown
+  // if permission is in allowed once or default states or if it is
+  // automatically blocked.
+  std::u16string state_text =
+      PageInfoUI::PermissionMainPageStateToUIString(delegate_, permission_);
+  if (!state_text.empty()) {
+    state_label_ = row_view_->AddSecondaryLabel(state_text);
+  }
+}
+
+void PermissionToggleRowView::ResetPermission() {
+  permission_.setting = CONTENT_SETTING_DEFAULT;
+  permission_.is_one_time = false;
+  PermissionChanged();
+}
diff --git a/chrome/browser/ui/views/page_info/permission_toggle_row_view.h b/chrome/browser/ui/views/page_info/permission_toggle_row_view.h
index 14c60f8..3984f60b 100644
--- a/chrome/browser/ui/views/page_info/permission_toggle_row_view.h
+++ b/chrome/browser/ui/views/page_info/permission_toggle_row_view.h
@@ -13,6 +13,11 @@
 class PageInfoRowView;
 class PageInfoNavigationHandler;
 
+namespace views {
+class Label;
+class ToggleButton;
+}  // namespace views
+
 // A view that shows a permission that a site is able to access, and
 // allows the user to control via toggle whether that access is granted. Has a
 // button that opens a subpage with more controls.
@@ -20,25 +25,32 @@
  public:
   PermissionToggleRowView(ChromePageInfoUiDelegate* delegate,
                           PageInfoNavigationHandler* navigation_handler,
-                          const PageInfo::PermissionInfo& permission);
+                          const PageInfo::PermissionInfo& permission,
+                          bool should_show_spacer_view);
   PermissionToggleRowView(const PermissionToggleRowView&) = delete;
   PermissionToggleRowView& operator=(const PermissionToggleRowView&) = delete;
 
   ~PermissionToggleRowView() override;
 
   void AddObserver(PermissionSelectorRowObserver* observer);
-  void PermissionChanged(const PageInfo::PermissionInfo& permission);
+  void PermissionChanged();
+  void ResetPermission();
 
  private:
   void OnToggleButtonPressed();
-  void InitForUserSource();
+  void InitForUserSource(bool should_show_spacer_view);
   void InitForManagedSource(ChromePageInfoUiDelegate* delegate);
+  void UpdateUiOnPermissionChanged();
 
   PageInfo::PermissionInfo permission_;
 
   PageInfoRowView* row_view_ = nullptr;
+  views::Label* state_label_ = nullptr;
+  views::ToggleButton* toggle_button_ = nullptr;
+  views::View* spacer_view_ = nullptr;
 
-  PageInfoNavigationHandler* navigation_handler_;
+  ChromePageInfoUiDelegate* delegate_ = nullptr;
+  PageInfoNavigationHandler* navigation_handler_ = nullptr;
 
   base::ObserverList<PermissionSelectorRowObserver, false>::Unchecked
       observer_list_;
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
index 39e8ea1..9638411 100644
--- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -26,9 +26,11 @@
 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view_base.h"
+#include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/url_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/lookalikes/core/features.h"
@@ -401,8 +403,13 @@
         NOTREACHED();
         break;
     }
-    EXPECT_EQ(page_info->GetSecurityDescriptionType(),
-              PageInfoUI::SecurityDescriptionType::SAFETY_TIP);
+    content::WebContentsAddedObserver new_tab_observer;
+    static_cast<views::StyledLabel*>(
+        page_info->GetViewByID(
+            PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL))
+        ->ClickLinkForTesting();
+    EXPECT_EQ(chrome::kSafetyTipHelpCenterURL,
+              new_tab_observer.GetWebContents()->GetURL());
   }
 
   void CheckPageInfoDoesNotShowSafetyTipInfo(Browser* browser) {
@@ -417,9 +424,13 @@
             l10n_util::GetStringUTF16(IDS_PAGE_INFO_INTERNAL_PAGE));
     if (PageInfoBubbleViewBase::GetShownBubbleType() ==
         PageInfoBubbleViewBase::BubbleType::BUBBLE_PAGE_INFO) {
-      EXPECT_NE(static_cast<PageInfoBubbleView*>(page_info)
-                    ->GetSecurityDescriptionType(),
-                PageInfoUI::SecurityDescriptionType::SAFETY_TIP);
+      content::WebContentsAddedObserver new_tab_observer;
+      static_cast<views::StyledLabel*>(
+          page_info->GetViewByID(
+              PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL))
+          ->ClickLinkForTesting();
+      EXPECT_EQ(chrome::kPageInfoHelpCenterURL,
+                new_tab_observer.GetWebContents()->GetURL());
     }
   }
 
diff --git a/chrome/browser/ui/views/page_info/security_information_view.cc b/chrome/browser/ui/views/page_info/security_information_view.cc
index 7de3cdc1..77a271f3 100644
--- a/chrome/browser/ui/views/page_info/security_information_view.cc
+++ b/chrome/browser/ui/views/page_info/security_information_view.cc
@@ -58,6 +58,8 @@
     // labels after more UI is implemented.
     security_summary_label->SetTextContext(
         views::style::CONTEXT_DIALOG_BODY_TEXT);
+    security_summary_label->SetID(
+        PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_SUMMARY_LABEL);
     security_summary_label_ =
         layout->AddView(std::move(security_summary_label), 1.0, 1.0,
                         views::GridLayout::FILL, views::GridLayout::LEADING);
@@ -72,6 +74,8 @@
 
   start_secondary_row();
   auto security_details_label = std::make_unique<views::StyledLabel>();
+  security_details_label->SetID(
+      PageInfoViewFactory::VIEW_ID_PAGE_INFO_SECURITY_DETAILS_LABEL);
   security_details_label_ =
       layout->AddView(std::move(security_details_label), 1.0, 1.0,
                       views::GridLayout::FILL, views::GridLayout::LEADING);
@@ -237,9 +241,12 @@
       (password_reuse_button_container_->width() - kSpacingBetweenButtons) >=
       (change_password_button_size +
        allowlist_password_reuse_button->CalculatePreferredSize().width());
+  bool is_page_info_v2 =
+      base::FeatureList::IsEnabled(page_info::kPageInfoV2Desktop);
   auto layout = std::make_unique<views::BoxLayout>(
-      can_fit_in_one_line ? views::BoxLayout::Orientation::kHorizontal
-                          : views::BoxLayout::Orientation::kVertical,
+      can_fit_in_one_line || is_page_info_v2
+          ? views::BoxLayout::Orientation::kHorizontal
+          : views::BoxLayout::Orientation::kVertical,
       gfx::Insets(), kSpacingBetweenButtons);
   // Make buttons left-aligned. For RTL languages, buttons will automatically
   // become right-aligned.
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
index 4c85bad..0db4616e 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view_browsertest.cc
@@ -109,7 +109,7 @@
     }
     base::RunLoop().RunUntilIdle();
 
-    PermissionChip* chip = GetPermissionRequestChipView();
+    PermissionChip* chip = GetChip();
     if (chip) {
       views::test::ButtonTestApi(chip->button())
           .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(),
@@ -120,7 +120,7 @@
   }
 
   bool VerifyUi() override {
-    const bool should_close_on_deactivate = GetPermissionRequestChipView();
+    const bool should_close_on_deactivate = GetChip();
     views::Widget* prompt_widget = test_api_->GetPromptWindow();
     views::BubbleDialogDelegate* bubble_dialog =
         prompt_widget->widget_delegate()->AsBubbleDialogDelegate();
@@ -135,12 +135,24 @@
     return browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
   }
 
-  PermissionChip* GetPermissionRequestChipView() {
+  PermissionChip* GetChip() {
     BrowserView* browser_view =
         BrowserView::GetBrowserViewForBrowser(browser());
     return browser_view->toolbar()->location_bar()->chip();
   }
 
+  ContentSettingImageView& GetContentSettingImageView(
+      ContentSettingImageModel::ImageType image_type) {
+    LocationBarView* location_bar_view =
+        BrowserView::GetBrowserViewForBrowser(browser())->GetLocationBarView();
+    return **std::find_if(
+        location_bar_view->GetContentSettingViewsForTest().begin(),
+        location_bar_view->GetContentSettingViewsForTest().end(),
+        [image_type](ContentSettingImageView* view) {
+          return view->GetTypeForTesting() == image_type;
+        });
+  }
+
   permissions::PermissionRequest* MakeRegisterProtocolHandlerRequest() {
     std::string protocol = "mailto";
     ProtocolHandler handler =
@@ -217,10 +229,52 @@
     }
   }
 
-  void VerifyDisposition(permissions::PermissionPromptDisposition disposition) {
-    EXPECT_EQ(
-        test_api_->manager()->current_request_prompt_disposition_for_testing(),
-        disposition);
+  void ExpectQuietAbusiveChip() {
+    // PermissionChip lifetime is bound to a permission prompt view.
+    ASSERT_TRUE(test_api_->manager()->view_for_testing());
+    // The quiet chip will be shown even if the chip experiment is disabled.
+    PermissionChip* chip = GetChip();
+    ASSERT_TRUE(chip);
+
+    EXPECT_FALSE(chip->should_expand_for_testing());
+    EXPECT_FALSE(chip->get_chip_button_for_testing()->GetProminent());
+    EXPECT_FALSE(chip->get_chip_button_for_testing()->is_animating());
+    EXPECT_EQ(OmniboxChipButton::Theme::kGray,
+              chip->get_chip_button_for_testing()->get_theme_for_testing());
+  }
+
+  void ExpectQuietChip() {
+    // PermissionChip lifetime is bound to a permission prompt view.
+    ASSERT_TRUE(test_api_->manager()->view_for_testing());
+
+    // The quiet chip will be shown even if the chip experiment is disabled.
+    PermissionChip* chip = GetChip();
+    ASSERT_TRUE(chip);
+
+    EXPECT_TRUE(chip->should_expand_for_testing());
+    EXPECT_FALSE(chip->get_chip_button_for_testing()->GetProminent());
+    EXPECT_TRUE(chip->get_chip_button_for_testing()->is_animating());
+    EXPECT_EQ(OmniboxChipButton::Theme::kGray,
+              chip->get_chip_button_for_testing()->get_theme_for_testing());
+  }
+
+  void ExpectNormalChip() {
+    // PermissionChip lifetime is bound to a permission prompt view.
+    ASSERT_TRUE(test_api_->manager()->view_for_testing());
+    if (GetParam()) {
+      PermissionChip* chip = GetChip();
+      ASSERT_TRUE(chip);
+
+      EXPECT_TRUE(chip->should_expand_for_testing());
+      EXPECT_TRUE(chip->get_chip_button_for_testing()->GetProminent());
+      EXPECT_TRUE(chip->get_chip_button_for_testing()->is_animating());
+      EXPECT_EQ(OmniboxChipButton::Theme::kBlue,
+                chip->get_chip_button_for_testing()->get_theme_for_testing());
+
+    } else {
+      // Chip is disabled.
+      EXPECT_FALSE(GetChip());
+    }
   }
 
   base::test::ScopedFeatureList feature_list_;
@@ -237,7 +291,7 @@
 // AnnounceText doesn't go through the path that uses Event::kAlert. Therefore
 // we can't test it.
 #if !defined(OS_MAC)
-  PermissionChip* chip = GetPermissionRequestChipView();
+  PermissionChip* chip = GetChip();
   // If chip UI is used, two notifications will be announced: one that
   // permission was requested and second when bubble is opened.
   if (chip && !chip->should_start_open_for_testing()) {
@@ -414,15 +468,8 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  LocationBarView* location_bar_view =
-      BrowserView::GetBrowserViewForBrowser(browser())->GetLocationBarView();
-  ContentSettingImageView& quiet_ui_icon = **std::find_if(
-      location_bar_view->GetContentSettingViewsForTest().begin(),
-      location_bar_view->GetContentSettingViewsForTest().end(),
-      [](ContentSettingImageView* view) {
-        return view->GetTypeForTesting() ==
-               ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT;
-      });
+  ContentSettingImageView& quiet_ui_icon = GetContentSettingImageView(
+      ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
 
   EXPECT_FALSE(quiet_ui_icon.GetVisible());
   // `ContentSettingImageView::AnimationEnded()` was not triggered and IPH is
@@ -517,7 +564,8 @@
                        DispositionNoAbusiveTest) {
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -527,7 +575,8 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -571,7 +620,8 @@
 
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -581,7 +631,8 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       permissions::PermissionPromptDisposition::LOCATION_BAR_RIGHT_STATIC_ICON);
 }
 
@@ -591,7 +642,8 @@
 
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -601,7 +653,8 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       permissions::PermissionPromptDisposition::LOCATION_BAR_RIGHT_STATIC_ICON);
 }
 
@@ -613,7 +666,8 @@
 
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -623,8 +677,10 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(permissions::PermissionPromptDisposition::
-                        LOCATION_BAR_RIGHT_ANIMATED_ICON);
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
+      permissions::PermissionPromptDisposition::
+          LOCATION_BAR_RIGHT_ANIMATED_ICON);
 }
 
 // For `QuietUiReason::kPredictedVeryUnlikelyGrant` reputation we show an
@@ -636,7 +692,8 @@
 
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -646,8 +703,10 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(permissions::PermissionPromptDisposition::
-                        LOCATION_BAR_RIGHT_ANIMATED_ICON);
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
+      permissions::PermissionPromptDisposition::
+          LOCATION_BAR_RIGHT_ANIMATED_ICON);
 }
 
 // For `QuietUiReason::kTriggeredDueToAbusiveRequests` reputation we show a
@@ -659,7 +718,8 @@
 
   ShowUi("geolocation");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       GetParam()
           ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
           : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
@@ -669,17 +729,161 @@
 
   ShowUi("notifications");
 
-  VerifyDisposition(
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
       permissions::PermissionPromptDisposition::LOCATION_BAR_RIGHT_STATIC_ICON);
 }
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         PermissionPromptBubbleViewQuietUiBrowserTest,
-                         ::testing::Values(false, true));
+class QuietChipPermissionPromptBubbleViewBrowserTest
+    : public PermissionPromptBubbleViewQuietUiBrowserTest {
+ public:
+  QuietChipPermissionPromptBubbleViewBrowserTest() {
+    scoped_feature_list_.InitAndEnableFeature(
+        permissions::features::kPermissionQuietChip);
+  }
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         PermissionPromptBubbleViewBrowserTest,
-                         ::testing::Values(false, true));
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_P(QuietChipPermissionPromptBubbleViewBrowserTest,
+                       LoudChipOrAnchoredBubbleIsShownForNonAbusiveRequests) {
+  SetCannedUiDecision(absl::nullopt, absl::nullopt);
+
+  ShowUi("geolocation");
+
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
+      GetParam()
+          ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
+          : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
+
+  test_api_->manager()->Accept();
+  base::RunLoop().RunUntilIdle();
+
+  ShowUi("notifications");
+
+  EXPECT_EQ(
+      test_api_->manager()->current_request_prompt_disposition_for_testing(),
+      GetParam()
+          ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
+          : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
+}
+
+IN_PROC_BROWSER_TEST_P(QuietChipPermissionPromptBubbleViewBrowserTest,
+                       QuietChipIsShownForAbusiveRequests) {
+  for (QuietUiReason reason : {QuietUiReason::kTriggeredByCrowdDeny,
+                               QuietUiReason::kTriggeredDueToAbusiveRequests,
+                               QuietUiReason::kTriggeredDueToAbusiveContent}) {
+    SetCannedUiDecision(reason, absl::nullopt);
+
+    ShowUi("geolocation");
+
+    EXPECT_EQ(
+        test_api_->manager()->current_request_prompt_disposition_for_testing(),
+        GetParam()
+            ? permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP
+            : permissions::PermissionPromptDisposition::ANCHORED_BUBBLE);
+
+    test_api_->manager()->Accept();
+    base::RunLoop().RunUntilIdle();
+
+    ShowUi("notifications");
+
+    // Quiet Chip is enabled, that means a quiet chip will be shown even if the
+    // Chip experiment is disabled.
+    EXPECT_EQ(
+        test_api_->manager()->current_request_prompt_disposition_for_testing(),
+        permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_QUIET_CHIP);
+  }
+}
+
+// The quiet UI icon is verified to make sure that the quiet chip is not shown
+// when the quiet icon is shown.
+IN_PROC_BROWSER_TEST_P(QuietChipPermissionPromptBubbleViewBrowserTest,
+                       QuietChipIsNotShownForNonAbusiveRequests) {
+  SetCannedUiDecision(absl::nullopt, absl::nullopt);
+
+  ContentSettingImageView& quiet_ui_icon = GetContentSettingImageView(
+      ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
+  EXPECT_FALSE(quiet_ui_icon.GetVisible());
+  EXPECT_FALSE(GetChip());
+
+  ShowUi("geolocation");
+
+  EXPECT_FALSE(quiet_ui_icon.GetVisible());
+  ExpectNormalChip();
+
+  test_api_->manager()->Accept();
+  base::RunLoop().RunUntilIdle();
+
+  ShowUi("notifications");
+
+  EXPECT_FALSE(quiet_ui_icon.GetVisible());
+  ExpectNormalChip();
+
+  test_api_->manager()->Accept();
+  base::RunLoop().RunUntilIdle();
+}
+
+IN_PROC_BROWSER_TEST_P(QuietChipPermissionPromptBubbleViewBrowserTest,
+                       NotAnimatedQuietChipIsShownForAbusiveRequests) {
+  for (QuietUiReason reason : {QuietUiReason::kTriggeredByCrowdDeny,
+                               QuietUiReason::kTriggeredDueToAbusiveRequests,
+                               QuietUiReason::kTriggeredDueToAbusiveContent}) {
+    SetCannedUiDecision(reason, absl::nullopt);
+
+    ContentSettingImageView& quiet_ui_icon = GetContentSettingImageView(
+        ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    EXPECT_FALSE(GetChip());
+
+    ShowUi("geolocation");
+
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    ExpectNormalChip();
+
+    test_api_->manager()->Accept();
+    base::RunLoop().RunUntilIdle();
+
+    ShowUi("notifications");
+
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    ExpectQuietAbusiveChip();
+
+    test_api_->manager()->Accept();
+    base::RunLoop().RunUntilIdle();
+  }
+}
+
+IN_PROC_BROWSER_TEST_P(QuietChipPermissionPromptBubbleViewBrowserTest,
+                       AnimatedQuietChipIsShownForNonAbusiveRequests) {
+  for (QuietUiReason reason : {QuietUiReason::kEnabledInPrefs,
+                               QuietUiReason::kPredictedVeryUnlikelyGrant}) {
+    SetCannedUiDecision(reason, absl::nullopt);
+
+    ContentSettingImageView& quiet_ui_icon = GetContentSettingImageView(
+        ContentSettingImageModel::ImageType::NOTIFICATIONS_QUIET_PROMPT);
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    EXPECT_FALSE(GetChip());
+
+    ShowUi("geolocation");
+
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    ExpectNormalChip();
+
+    test_api_->manager()->Accept();
+    base::RunLoop().RunUntilIdle();
+
+    ShowUi("notifications");
+
+    EXPECT_FALSE(quiet_ui_icon.GetVisible());
+    ExpectQuietChip();
+
+    test_api_->manager()->Accept();
+    base::RunLoop().RunUntilIdle();
+  }
+}
 
 class OneTimePermissionPromptBubbleViewBrowserTest
     : public PermissionPromptBubbleViewBrowserTest {
@@ -699,8 +903,18 @@
   ShowAndVerifyUi();
 }
 
+// False / True values determine if the PermissionChip feature is
+// disabled/enabled.
+INSTANTIATE_TEST_SUITE_P(All,
+                         PermissionPromptBubbleViewBrowserTest,
+                         ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(All,
+                         PermissionPromptBubbleViewQuietUiBrowserTest,
+                         ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(All,
+                         QuietChipPermissionPromptBubbleViewBrowserTest,
+                         ::testing::Values(false, true));
 INSTANTIATE_TEST_SUITE_P(All,
                          OneTimePermissionPromptBubbleViewBrowserTest,
                          ::testing::Values(false, true));
-
 INSTANTIATE_TEST_SUITE_P(All, QuietUIPromoBrowserTest, ::testing::Values(true));
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
index 16adbbb6..957230bc 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/permission_bubble/file_handling_permission_prompt.h"
 #include "chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h"
+#include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/web_launch/web_launch_files_helper.h"
 #include "components/permissions/features.h"
 #include "components/permissions/permission_request.h"
@@ -23,6 +24,27 @@
 #include "content/public/browser/web_contents.h"
 #include "ui/views/bubble/bubble_frame_view.h"
 
+namespace {
+
+bool IsFullScreenMode(content::WebContents* web_contents, Browser* browser) {
+  DCHECK(web_contents);
+  DCHECK(browser);
+
+  // PWA uses the title bar as a substitute for LocationBarView.
+  if (web_app::AppBrowserController::IsWebApp(browser))
+    return false;
+
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
+  if (!browser_view)
+    return false;
+
+  LocationBarView* location_bar = browser_view->GetLocationBarView();
+
+  return !location_bar || !location_bar->IsDrawn();
+}
+
+}  // namespace
+
 std::unique_ptr<permissions::PermissionPrompt> CreatePermissionPrompt(
     content::WebContents* web_contents,
     permissions::PermissionPrompt::Delegate* delegate) {
@@ -33,6 +55,14 @@
     return nullptr;
   }
 
+  permissions::PermissionRequestManager* manager =
+      permissions::PermissionRequestManager::FromWebContents(web_contents);
+
+  if (manager->ShouldDropCurrentRequestIfCannotShowQuietly() &&
+      IsFullScreenMode(web_contents, browser)) {
+    return nullptr;
+  }
+
   if (base::FeatureList::IsEnabled(features::kFileHandlingPermissionUiV2) &&
       delegate->Requests().size() == 1U &&
       delegate->Requests()[0]->GetRequestType() ==
@@ -51,29 +81,18 @@
       web_contents_(web_contents),
       delegate_(delegate),
       browser_(browser),
-      permission_requested_time_(base::TimeTicks::Now()) {
-  permissions::PermissionRequestManager* manager =
-      permissions::PermissionRequestManager::FromWebContents(web_contents_);
-  if (manager->ShouldCurrentRequestUseQuietUI()) {
-    prompt_style_ = PermissionPromptStyle::kQuiet;
-    // Shows the prompt as an indicator in the right side of the omnibox.
-    content_settings::UpdateLocationBarUiForWebContents(web_contents_);
+      permission_requested_time_(base::TimeTicks::Now()),
+      manager_(permissions::PermissionRequestManager::FromWebContents(
+          web_contents)) {
+  if (web_app::AppBrowserController::IsWebApp(browser_)) {
+    SelectPwaPrompt();
+  } else if (manager_->ShouldCurrentRequestUseQuietUI()) {
+    SelectQuietPrompt();
   } else {
-    LocationBarView* lbv = GetLocationBarView();
-    if (lbv && lbv->IsDrawn() && ShouldCurrentRequestUseChipUI()) {
-      ShowChipUI();
-    } else {
-      ShowBubble();
-    }
+    SelectNormalPrompt();
   }
 }
 
-void PermissionPromptImpl::OnWidgetClosing(views::Widget* widget) {
-  DCHECK_EQ(widget, prompt_bubble_->GetWidget());
-  widget->RemoveObserver(this);
-  prompt_bubble_ = nullptr;
-}
-
 PermissionPromptImpl::~PermissionPromptImpl() {
   switch (prompt_style_) {
     case PermissionPromptStyle::kBubbleOnly:
@@ -82,11 +101,12 @@
         prompt_bubble_->GetWidget()->Close();
       break;
     case PermissionPromptStyle::kChip:
+    case PermissionPromptStyle::kQuietChip:
       DCHECK(!prompt_bubble_);
       DCHECK(chip_);
       FinalizeChip();
       break;
-    case PermissionPromptStyle::kQuiet:
+    case PermissionPromptStyle::kLocationBarRightIcon:
       DCHECK(!prompt_bubble_);
       DCHECK(!chip_);
       content_settings::UpdateLocationBarUiForWebContents(web_contents_);
@@ -116,12 +136,12 @@
       if (!prompt_bubble_)
         return;
 
-      if (ShouldCurrentRequestUseChipUI() && is_location_bar_drawn) {
+      if (ShouldCurrentRequestUseChip() && is_location_bar_drawn) {
         // Change prompt style to chip to avoid dismissing request while
         // switching UI style.
         prompt_bubble_->SetPromptStyle(PermissionPromptStyle::kChip);
         prompt_bubble_->GetWidget()->Close();
-        ShowChipUI();
+        ShowChip();
         chip_->OpenBubble();
       } else {
         // If |browser_| changed, recreate bubble for correct browser.
@@ -147,47 +167,27 @@
         ShowBubble();
       }
       break;
-    case PermissionPromptStyle::kQuiet:
+    case PermissionPromptStyle::kQuietChip:
+      DCHECK(!prompt_bubble_);
+
+      if (!lbv->chip()) {
+        chip_ = lbv->DisplayQuietChip(
+            delegate_,
+            !permissions::PermissionUiSelector::ShouldSuppressAnimation(
+                manager_->ReasonForUsingQuietUi()));
+      }
+      // If there is fresh pending request shown as chip UI and location bar
+      // isn't visible anymore, show bubble UI instead.
+      if (!chip_->is_fully_collapsed() && !is_location_bar_drawn) {
+        FinalizeChip();
+        ShowBubble();
+      }
+      break;
+    case PermissionPromptStyle::kLocationBarRightIcon:
       break;
   }
 }
 
-LocationBarView* PermissionPromptImpl::GetLocationBarView() {
-  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
-  return browser_view ? browser_view->GetLocationBarView() : nullptr;
-}
-
-void PermissionPromptImpl::ShowChipUI() {
-  LocationBarView* lbv = GetLocationBarView();
-  DCHECK(lbv);
-
-  chip_ = lbv->DisplayChip(delegate_);
-  prompt_style_ = PermissionPromptStyle::kChip;
-}
-
-void PermissionPromptImpl::ShowBubble() {
-  prompt_style_ = PermissionPromptStyle::kBubbleOnly;
-  prompt_bubble_ = new PermissionPromptBubbleView(
-      browser_, delegate_, permission_requested_time_, prompt_style_);
-  prompt_bubble_->Show();
-  prompt_bubble_->GetWidget()->AddObserver(this);
-}
-
-bool PermissionPromptImpl::ShouldCurrentRequestUseChipUI() {
-  if (!base::FeatureList::IsEnabled(permissions::features::kPermissionChip))
-    return false;
-
-  std::vector<permissions::PermissionRequest*> requests = delegate_->Requests();
-  return std::all_of(requests.begin(), requests.end(), [](auto* request) {
-    return request->GetChipText().has_value();
-  });
-}
-
-void PermissionPromptImpl::FinalizeChip() {
-  GetLocationBarView()->FinalizeChip();
-  chip_ = nullptr;
-}
-
 permissions::PermissionPrompt::TabSwitchingBehavior
 PermissionPromptImpl::GetTabSwitchingBehavior() {
   return permissions::PermissionPrompt::TabSwitchingBehavior::
@@ -201,11 +201,12 @@
       return permissions::PermissionPromptDisposition::ANCHORED_BUBBLE;
     case PermissionPromptStyle::kChip:
       return permissions::PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP;
-    case PermissionPromptStyle::kQuiet: {
-      permissions::PermissionRequestManager* manager =
-          permissions::PermissionRequestManager::FromWebContents(web_contents_);
+    case PermissionPromptStyle::kQuietChip:
+      return permissions::PermissionPromptDisposition::
+          LOCATION_BAR_LEFT_QUIET_CHIP;
+    case PermissionPromptStyle::kLocationBarRightIcon: {
       return permissions::PermissionUiSelector::ShouldSuppressAnimation(
-                 manager->ReasonForUsingQuietUi())
+                 manager_->ReasonForUsingQuietUi())
                  ? permissions::PermissionPromptDisposition::
                        LOCATION_BAR_RIGHT_STATIC_ICON
                  : permissions::PermissionPromptDisposition::
@@ -213,3 +214,109 @@
     }
   }
 }
+
+void PermissionPromptImpl::OnWidgetClosing(views::Widget* widget) {
+  DCHECK_EQ(widget, prompt_bubble_->GetWidget());
+  widget->RemoveObserver(this);
+  prompt_bubble_ = nullptr;
+}
+
+bool PermissionPromptImpl::IsLocationBarDisplayed() {
+  LocationBarView* lbv = GetLocationBarView();
+  return lbv && lbv->IsDrawn();
+}
+
+void PermissionPromptImpl::SelectPwaPrompt() {
+  if (manager_->ShouldCurrentRequestUseQuietUI()) {
+    ShowQuietIcon();
+  } else {
+    ShowBubble();
+  }
+}
+
+void PermissionPromptImpl::SelectNormalPrompt() {
+  DCHECK(!manager_->ShouldCurrentRequestUseQuietUI());
+  if (ShouldCurrentRequestUseChip()) {
+    ShowChip();
+  } else {
+    ShowBubble();
+  }
+}
+
+void PermissionPromptImpl::SelectQuietPrompt() {
+  if (ShouldCurrentRequestUseQuietChip()) {
+    if (IsLocationBarDisplayed()) {
+      ShowChip();
+    } else {
+      // If LocationBar is not displayed (Fullscreen mode), display a default
+      // bubble only for non-abusive origins.
+      DCHECK(!manager_->ShouldDropCurrentRequestIfCannotShowQuietly());
+      ShowBubble();
+    }
+  } else {
+    ShowQuietIcon();
+  }
+}
+
+LocationBarView* PermissionPromptImpl::GetLocationBarView() {
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
+  return browser_view ? browser_view->GetLocationBarView() : nullptr;
+}
+
+void PermissionPromptImpl::ShowQuietIcon() {
+  prompt_style_ = PermissionPromptStyle::kLocationBarRightIcon;
+  // Shows the prompt as an indicator in the right side of the omnibox.
+  content_settings::UpdateLocationBarUiForWebContents(web_contents_);
+}
+
+void PermissionPromptImpl::ShowBubble() {
+  prompt_style_ = PermissionPromptStyle::kBubbleOnly;
+  prompt_bubble_ = new PermissionPromptBubbleView(
+      browser_, delegate_, permission_requested_time_, prompt_style_);
+  prompt_bubble_->Show();
+  prompt_bubble_->GetWidget()->AddObserver(this);
+}
+
+void PermissionPromptImpl::ShowChip() {
+  LocationBarView* lbv = GetLocationBarView();
+  DCHECK(lbv);
+
+  if (manager_->ShouldCurrentRequestUseQuietUI()) {
+    chip_ = lbv->DisplayQuietChip(
+        delegate_, !permissions::PermissionUiSelector::ShouldSuppressAnimation(
+                       manager_->ReasonForUsingQuietUi()));
+    prompt_style_ = PermissionPromptStyle::kQuietChip;
+  } else {
+    chip_ = lbv->DisplayChip(delegate_);
+    prompt_style_ = PermissionPromptStyle::kChip;
+  }
+}
+
+bool PermissionPromptImpl::ShouldCurrentRequestUseChip() {
+  if (!base::FeatureList::IsEnabled(permissions::features::kPermissionChip))
+    return false;
+
+  std::vector<permissions::PermissionRequest*> requests = delegate_->Requests();
+  return std::all_of(requests.begin(), requests.end(), [](auto* request) {
+    return request->GetChipText().has_value();
+  });
+}
+
+bool PermissionPromptImpl::ShouldCurrentRequestUseQuietChip() {
+  if (!base::FeatureList::IsEnabled(
+          permissions::features::kPermissionQuietChip)) {
+    return false;
+  }
+
+  std::vector<permissions::PermissionRequest*> requests = delegate_->Requests();
+  return std::all_of(requests.begin(), requests.end(), [](auto* request) {
+    return request->GetRequestType() ==
+               permissions::RequestType::kNotifications ||
+           request->GetRequestType() == permissions::RequestType::kGeolocation;
+  });
+}
+
+void PermissionPromptImpl::FinalizeChip() {
+  GetLocationBarView()->FinalizeChip();
+  chip_ = nullptr;
+}
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
index a7e8586..915288e 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.h
@@ -18,6 +18,10 @@
 class BubbleDialogDelegateView;
 }
 
+namespace permissions {
+class PermissionRequestManager;
+}
+
 namespace content {
 class WebContents;
 }  // namespace content
@@ -49,10 +53,16 @@
   void OnWidgetClosing(views::Widget* widget) override;
 
  private:
+  bool IsLocationBarDisplayed();
+  void SelectPwaPrompt();
+  void SelectNormalPrompt();
+  void SelectQuietPrompt();
   LocationBarView* GetLocationBarView();
+  void ShowQuietIcon();
   void ShowBubble();
-  void ShowChipUI();
-  bool ShouldCurrentRequestUseChipUI();
+  void ShowChip();
+  bool ShouldCurrentRequestUseChip();
+  bool ShouldCurrentRequestUseQuietChip();
   void FinalizeChip();
 
   // The popup bubble. Not owned by this class; it will delete itself when a
@@ -72,6 +82,9 @@
 
   base::TimeTicks permission_requested_time_;
 
+  // PermissionRequestManager owns `this` and outlives `PermissionPromptImpl`.
+  permissions::PermissionRequestManager* manager_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(PermissionPromptImpl);
 };
 
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_style.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_style.h
index 7a02f1c..b6231b1 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_style.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_style.h
@@ -12,7 +12,10 @@
   // The permission chip view in the location bar.
   kChip,
   // The prompt as an indicator in the right side of the omnibox.
-  kQuiet
+  kLocationBarRightIcon,
+  // The less prominent (quiet) version of permission chip view in the location
+  // bar.
+  kQuietChip
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_PERMISSION_BUBBLE_PERMISSION_PROMPT_STYLE_H_
diff --git a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc
index b4ba1a93..185d842 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_interactive_uitest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/profiles/profile_picker_test_base.h"
 #include "chrome/test/base/interactive_test_utils.h"
+#include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
@@ -213,13 +214,18 @@
 IN_PROC_BROWSER_TEST_F(ProfilePickerInteractiveUiTest,
                        MAYBE_NavigateBackWithKeyboard) {
   // Simulate walking through the flow starting at the picker so that navigating
-  // back to the picker makes sense.
+  // back to the picker makes sense. Check that the navigation list is populated
+  // correctly.
   ShowAndFocusPicker(ProfilePicker::EntryPoint::kProfileMenuManageProfiles);
   WaitForLoadStop(web_contents(), GURL("chrome://profile-picker"));
+  EXPECT_EQ(1, web_contents()->GetController().GetEntryCount());
+  EXPECT_EQ(0, web_contents()->GetController().GetLastCommittedEntryIndex());
   web_contents()->GetController().LoadURL(
       GURL("chrome://profile-picker/new-profile"), content::Referrer(),
       ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
   WaitForLoadStop(web_contents(), GURL("chrome://profile-picker/new-profile"));
+  EXPECT_EQ(2, web_contents()->GetController().GetEntryCount());
+  EXPECT_EQ(1, web_contents()->GetController().GetLastCommittedEntryIndex());
 
   // Simulate a click on the signin button.
   base::MockCallback<base::OnceCallback<void(bool)>> switch_finished_callback;
@@ -235,10 +241,12 @@
   SendBackKeyboardCommand();
   WaitForLayoutWithoutToolbar();
   WaitForLoadStop(web_contents(), GURL("chrome://profile-picker/new-profile"));
+  EXPECT_EQ(1, web_contents()->GetController().GetLastCommittedEntryIndex());
 
   // Navigate again back with the keyboard.
   SendBackKeyboardCommand();
   WaitForLoadStop(web_contents(), GURL("chrome://profile-picker"));
+  EXPECT_EQ(0, web_contents()->GetController().GetLastCommittedEntryIndex());
 
   // Navigating back once again does nothing.
   SendBackKeyboardCommand();
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
index 1f479d1..521e6aa8 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -700,8 +700,8 @@
 // Crash requires specific conditions to be reproduced. Browser should have 2
 // profiles with the same GAIA account name and the first profile should use
 // default local name. This is set up specifically in order to trigger
-// ProfileInfoCache::NotifyIfProfileNamesHaveChanged() when a new third profile
-// is added.
+// ProfileAttributesStorage::NotifyIfProfileNamesHaveChanged() when a new third
+// profile is added.
 IN_PROC_BROWSER_TEST_F(ProfilePickerCreationFlowBrowserTest,
                        PRE_ProfileNameChangesOnProfileAdded) {
   Profile* default_profile = browser()->profile();
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc
index 48c148dd..2e3dab1 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.cc
+++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -405,6 +405,15 @@
   SetInitialURL(navigation_handle->GetURL());
 }
 
+void AppBrowserController::ReadyToCommitNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInMainFrame())
+    return;
+
+  // Reset the draggable regions so they are not cached on navigation.
+  draggable_region_ = absl::nullopt;
+}
+
 void AppBrowserController::DOMContentLoaded(
     content::RenderFrameHost* render_frame_host) {
   // We hold off changing theme color for a new tab until the page is loaded.
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h
index 07c7cab8..db50a9f 100644
--- a/chrome/browser/ui/web_applications/app_browser_controller.h
+++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -193,6 +193,8 @@
 
   // content::WebContentsObserver:
   void DidStartNavigation(content::NavigationHandle* handle) override;
+  void ReadyToCommitNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override;
   void DidChangeThemeColor() override;
   void OnBackgroundColorChanged() override;
diff --git a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
index 25a0357..9e56725 100644
--- a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
+++ b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
@@ -36,10 +36,10 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/components/web_app_provider_base.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
 #include "chrome/browser/web_applications/test/service_worker_registration_waiter.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/security_interstitials/content/security_interstitial_tab_helper.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
@@ -203,8 +203,7 @@
               apps::mojom::AppLaunchSource::kSourceTest));
   DCHECK(web_contents);
 
-  WebAppTabHelperBase* tab_helper =
-      WebAppTabHelperBase::FromWebContents(web_contents);
+  WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents);
   DCHECK(tab_helper);
   EXPECT_EQ(app_id, tab_helper->GetAppId());
 
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc
index d4ef62c..9402f481 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -1343,15 +1343,15 @@
       popup_browser->CanSupportWindowFeature(Browser::FEATURE_LOCATIONBAR));
 }
 
-// Make sure chrome://internals/web-app page loads fine.
-IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, InternalWebAppPage) {
+// Make sure chrome://web-app-internals page loads fine.
+IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, WebAppInternalsPage) {
   // Loads with no web app.
-  NavigateToURLAndWait(browser(), GURL("chrome://internals/web-app"));
+  NavigateToURLAndWait(browser(), GURL("chrome://web-app-internals"));
 
   const GURL app_url = GetSecureAppURL();
   InstallPWA(app_url);
   // Loads with one web app.
-  NavigateToURLAndWait(browser(), GURL("chrome://internals/web-app"));
+  NavigateToURLAndWait(browser(), GURL("chrome://web-app-internals"));
 
   // Install a non-promotable web app.
   NavigateToURLAndWait(
@@ -1363,7 +1363,7 @@
   observer.AwaitNextInstall();
   chrome::SetAutoAcceptWebAppDialogForTesting(false, false);
   // Loads with two apps.
-  NavigateToURLAndWait(browser(), GURL("chrome://internals/web-app"));
+  NavigateToURLAndWait(browser(), GURL("chrome://web-app-internals"));
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_WindowControlsOverlay,
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
index e60057e..d168606 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -78,8 +78,7 @@
                        const std::string& app_id) {
   // TODO(https://crbug.com/1032443):
   // Eventually move this to browser_navigator.cc: CreateTargetContents().
-  WebAppTabHelperBase* tab_helper =
-      WebAppTabHelperBase::FromWebContents(web_contents);
+  WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents);
   DCHECK(tab_helper);
   tab_helper->SetAppId(app_id);
 }
diff --git a/chrome/browser/ui/web_applications/web_app_metrics.cc b/chrome/browser/ui/web_applications/web_app_metrics.cc
index 3553b4b..8aa4341 100644
--- a/chrome/browser/ui/web_applications/web_app_metrics.cc
+++ b/chrome/browser/ui/web_applications/web_app_metrics.cc
@@ -16,10 +16,10 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/web_app_metrics_factory.h"
 #include "chrome/browser/web_applications/components/web_app_prefs_utils.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
 #include "chrome/browser/web_applications/daily_metrics_helper.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "components/site_engagement/content/engagement_type.h"
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "components/webapps/browser/banners/app_banner_manager.h"
@@ -130,10 +130,9 @@
                               engagement_type);
   }
 
-  // A presence of WebAppTabHelperBase with valid app_id indicates an installed
+  // A presence of WebAppTabHelper with valid app_id indicates an installed
   // web app.
-  WebAppTabHelperBase* tab_helper =
-      WebAppTabHelperBase::FromWebContents(web_contents);
+  WebAppTabHelper* tab_helper = WebAppTabHelper::FromWebContents(web_contents);
   if (!tab_helper)
     return;
   AppId app_id = tab_helper->GetAppId();
@@ -208,8 +207,7 @@
          change.GetRemove()->contents) {
       if (contents.remove_reason ==
           TabStripModelChange::RemoveReason::kDeleted) {
-        auto* tab_helper =
-            WebAppTabHelperBase::FromWebContents(contents.contents);
+        auto* tab_helper = WebAppTabHelper::FromWebContents(contents.contents);
         if (tab_helper && !tab_helper->GetAppId().empty())
           app_last_interacted_time_.erase(tab_helper->GetAppId());
         // Newly-selected foreground contents should not be going away.
@@ -228,7 +226,7 @@
   // Update current tab as foreground time.
   if (foreground_web_contents_) {
     auto* tab_helper =
-        WebAppTabHelperBase::FromWebContents(foreground_web_contents_);
+        WebAppTabHelper::FromWebContents(foreground_web_contents_);
     if (tab_helper && !tab_helper->GetAppId().empty() &&
         app_last_interacted_time_.contains(tab_helper->GetAppId())) {
       UpdateUkmData(foreground_web_contents_, TabSwitching::kFrom);
@@ -242,7 +240,7 @@
     for (int i = 0; i < tab_count; i++) {
       WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(i);
       DCHECK(contents);
-      auto* tab_helper = WebAppTabHelperBase::FromWebContents(contents);
+      auto* tab_helper = WebAppTabHelper::FromWebContents(contents);
       if (tab_helper && !tab_helper->GetAppId().empty() &&
           app_last_interacted_time_.contains(tab_helper->GetAppId())) {
         UpdateUkmData(contents, TabSwitching::kBackgroundClosing);
@@ -327,7 +325,7 @@
     return;
   DailyInteraction features;
 
-  auto* tab_helper = WebAppTabHelperBase::FromWebContents(web_contents);
+  auto* tab_helper = WebAppTabHelper::FromWebContents(web_contents);
   if (tab_helper &&
       provider->registrar().IsLocallyInstalled(tab_helper->GetAppId())) {
     // App is installed
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
index 9f99bfeb..acbea14 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/ui/web_applications/web_app_dialog_manager.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_metrics.h"
+#include "chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h"
 #include "chrome/browser/web_applications/components/app_registry_controller.h"
 #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
@@ -123,6 +124,10 @@
       FROM_HERE, base::BindOnce(&WebAppUiManagerImpl::OnExtensionSystemReady,
                                 weak_ptr_factory_.GetWeakPtr()));
 
+  // Register the source for the chrome://web-app-internals page.
+  content::URLDataSource::Add(
+      profile_, std::make_unique<WebAppInternalsSource>(profile_));
+
   BrowserList::AddObserver(this);
 }
 
diff --git a/chrome/browser/ui/webui/app_management/app_management.mojom b/chrome/browser/ui/webui/app_management/app_management.mojom
index 788bc9b..2a1502c9 100644
--- a/chrome/browser/ui/webui/app_management/app_management.mojom
+++ b/chrome/browser/ui/webui/app_management/app_management.mojom
@@ -96,3 +96,7 @@
   CAMERA = 1,
   MICROPHONE = 2,
 };
+
+enum BorealisPermissionType {
+  MICROPHONE = 0,
+};
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc
index ff88cf1..8fc21cf7 100644
--- a/chrome/browser/ui/webui/certificate_viewer_webui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -105,7 +105,7 @@
 
 std::unique_ptr<base::DictionaryValue> CertNodeBuilder::Build() {
   DCHECK(!built_);
-  if (!children_.empty()) {
+  if (!children_.GetList().empty()) {
     node_.SetKey("children", std::move(children_));
   }
   built_ = true;
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
index f21ea451..0726209 100644
--- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
+++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -185,7 +185,9 @@
 
  private:
   base::test::ScopedFeatureList feature_list_;
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::FakeBrowserDMTokenStorage fake_dm_token_storage_;
+#endif
 };
 
 // Verify that there's no Trusted Types violation in chrome://chrome-urls
@@ -228,7 +230,6 @@
     "chrome://identity-internals",
     "chrome://indexeddb-internals",
     "chrome://inspect",
-    "chrome://internals/web-app",
     "chrome://interstitials/ssl",
     "chrome://invalidations",
     "chrome://local-state",
@@ -279,6 +280,7 @@
     "chrome://usb-internals",
     "chrome://user-actions",
     "chrome://version",
+    "chrome://web-app-internals",
     "chrome://webrtc-internals",
     "chrome://webrtc-logs",
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index a824959..98b5c2da 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -455,12 +455,12 @@
 }
 
 template <>
-WebUIController* NewWebUI<chromeos::DiagnosticsDialogUI>(WebUI* web_ui,
-                                                         const GURL& url) {
+WebUIController* NewWebUI<ash::DiagnosticsDialogUI>(WebUI* web_ui,
+                                                    const GURL& url) {
   ash::HoldingSpaceKeyedService* holding_space_keyed_service =
       ash::HoldingSpaceKeyedServiceFactory::GetInstance()->GetService(
           web_ui->GetWebContents()->GetBrowserContext());
-  return new chromeos::DiagnosticsDialogUI(
+  return new ash::DiagnosticsDialogUI(
       web_ui, base::BindRepeating(&CreateChromeSelectFilePolicy),
       holding_space_keyed_service->client());
 }
@@ -807,8 +807,8 @@
   if (url.host_piece() == chrome::kChromeUIPowerHost)
     return &NewWebUI<chromeos::PowerUI>;
   if (base::FeatureList::IsEnabled(chromeos::features::kDiagnosticsApp) &&
-      url.host_piece() == chromeos::kChromeUIDiagnosticsAppHost) {
-    return &NewWebUI<chromeos::DiagnosticsDialogUI>;
+      url.host_piece() == ash::kChromeUIDiagnosticsAppHost) {
+    return &NewWebUI<ash::DiagnosticsDialogUI>;
   }
   if (url.host_piece() == chromeos::kChromeUIPrintManagementHost)
     return &NewWebUI<chromeos::printing::printing_manager::PrintManagementUI>;
diff --git a/chrome/browser/ui/webui/chromeos/login/management_transition_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/management_transition_screen_handler.cc
index bb9e68b6..5532825 100644
--- a/chrome/browser/ui/webui/chromeos/login/management_transition_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/management_transition_screen_handler.cc
@@ -98,7 +98,7 @@
 
   registrar_.Init(profile->GetPrefs());
   registrar_.Add(
-      arc::prefs::kArcSupervisionTransition,
+      arc::prefs::kArcManagementTransition,
       base::BindRepeating(
           &ManagementTransitionScreenHandler::OnManagementTransitionFinished,
           weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
index e4aa7fc..cb3646e 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.cc
@@ -60,7 +60,7 @@
 
 void MultideviceSetupHandler::HandleOpenMultiDeviceSettings(
     const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
       Profile::FromWebUI(web_ui()),
       chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath);
diff --git a/chrome/browser/ui/webui/chromeos/projector/selfie_cam_bubble_manager.cc b/chrome/browser/ui/webui/chromeos/projector/selfie_cam_bubble_manager.cc
index b19929162..03b3e61 100644
--- a/chrome/browser/ui/webui/chromeos/projector/selfie_cam_bubble_manager.cc
+++ b/chrome/browser/ui/webui/chromeos/projector/selfie_cam_bubble_manager.cc
@@ -163,7 +163,8 @@
     content_container->SetLayoutManager(std::make_unique<views::FlexLayout>())
         ->SetOrientation(views::LayoutOrientation::kVertical)
         .SetMainAxisAlignment(views::LayoutAlignment::kEnd)
-        .SetCrossAxisAlignment(views::LayoutAlignment::kCenter);
+        .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
+        .SetInteriorMargin(gfx::Insets(0, 0, /*bottom=*/4, 0));
 
     views::Button::PressedCallback expand_or_collapse_callback =
         base::BindRepeating(
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui.cc
index 1b3806f..dd3512b 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui.cc
@@ -93,7 +93,7 @@
     return;
 
   std::string json_retval;
-  if (!args->empty() && !args->GetString(0, &json_retval))
+  if (!args->GetList().empty() && !args->GetString(0, &json_retval))
     NOTREACHED() << "Could not read JSON argument";
   delegate->GetWebDialogDelegate()->OnDialogClosed(json_retval);
   delegate->OnDialogCloseFromWebUI();
diff --git a/chrome/browser/ui/webui/cr_components/most_visited/most_visited_handler.cc b/chrome/browser/ui/webui/cr_components/most_visited/most_visited_handler.cc
index f66ccf3..c6ff3e0 100644
--- a/chrome/browser/ui/webui/cr_components/most_visited/most_visited_handler.cc
+++ b/chrome/browser/ui/webui/cr_components/most_visited/most_visited_handler.cc
@@ -31,7 +31,6 @@
       /*visual_type=*/
       ntp_tiles::TileVisualType::ICON_REAL /* unused on desktop */,
       /*icon_type=*/favicon_base::IconType::kInvalid /* unused on desktop */,
-      /*data_generation_time=*/tile.data_generation_time,
       /*url_for_rappor=*/GURL() /* unused */);
 }
 
@@ -203,7 +202,6 @@
     value->url = tile.url;
     value->source = static_cast<int32_t>(tile.source);
     value->title_source = static_cast<int32_t>(tile.title_source);
-    value->data_generation_time = tile.data_generation_time;
     value->is_query_tile =
         base::FeatureList::IsEnabled(ntp_features::kNtpRepeatableQueries) &&
         template_url_service &&
diff --git a/chrome/browser/ui/webui/family_link_user_internals/family_link_user_internals_message_handler.cc b/chrome/browser/ui/webui/family_link_user_internals/family_link_user_internals_message_handler.cc
index 8c872cb..d68bf20 100644
--- a/chrome/browser/ui/webui/family_link_user_internals/family_link_user_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/family_link_user_internals/family_link_user_internals_message_handler.cc
@@ -164,7 +164,7 @@
 
 void FamilyLinkUserInternalsMessageHandler::HandleRegisterForEvents(
     const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   AllowJavascript();
   if (scoped_observation_.IsObserving())
     return;
diff --git a/chrome/browser/ui/webui/internals/internals_ui.cc b/chrome/browser/ui/webui/internals/internals_ui.cc
index 8ee9d1b..0fb6c9b 100644
--- a/chrome/browser/ui/webui/internals/internals_ui.cc
+++ b/chrome/browser/ui/webui/internals/internals_ui.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ui/webui/internals/query_tiles/query_tiles_internals_ui_message_handler.h"
 #else
 #include "chrome/browser/ui/webui/internals/user_education/user_education_internals_page_handler_impl.h"
-#include "chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #endif  // defined(OS_ANDROID)
 
@@ -83,7 +82,10 @@
                            IDR_USER_EDUCATION_INTERNALS_INDEX_HTML);
 
   // chrome://internals/web-app
-  WebAppInternalsPageHandlerImpl::AddPageResources(source_);
+  // This page has moved to chrome://web-app-internals, see
+  // WebAppInternalsSource.
+  // TODO(crbug.com/1226263): Clean up this redirect after M94 goes stable.
+  source_->AddResourcePath("web-app", IDR_WEB_APP_INTERNALS_HTML);
 #endif  // defined(OS_ANDROID)
 
   // chrome://internals/session-service
@@ -115,14 +117,6 @@
 }
 #else   // defined(OS_ANDROID)
 void InternalsUI::BindInterface(
-    mojo::PendingReceiver<mojom::web_app_internals::WebAppInternalsPageHandler>
-        receiver) {
-  mojo::MakeSelfOwnedReceiver(
-      std::make_unique<WebAppInternalsPageHandlerImpl>(profile_),
-      std::move(receiver));
-}
-
-void InternalsUI::BindInterface(
     mojo::PendingReceiver<
         mojom::user_education_internals::UserEducationInternalsPageHandler>
         receiver) {
diff --git a/chrome/browser/ui/webui/internals/internals_ui.h b/chrome/browser/ui/webui/internals/internals_ui.h
index 29b57787..e49975eb 100644
--- a/chrome/browser/ui/webui/internals/internals_ui.h
+++ b/chrome/browser/ui/webui/internals/internals_ui.h
@@ -14,7 +14,6 @@
 // gn check doesn't understand "#if !defined(OS_ANDROID)" and fails this
 // non-Android include on Android.
 #include "chrome/browser/ui/webui/internals/user_education/user_education_internals.mojom.h"  // nogncheck
-#include "chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom.h"  // nogncheck
 #endif
 
 namespace content {
@@ -31,9 +30,6 @@
 #if !defined(OS_ANDROID)
   void BindInterface(
       mojo::PendingReceiver<
-          mojom::web_app_internals::WebAppInternalsPageHandler> receiver);
-  void BindInterface(
-      mojo::PendingReceiver<
           mojom::user_education_internals::UserEducationInternalsPageHandler>
           receiver);
 #endif  // !defined(OS_ANDROID)
diff --git a/chrome/browser/ui/webui/internals/web_app/BUILD.gn b/chrome/browser/ui/webui/internals/web_app/BUILD.gn
deleted file mode 100644
index 70ca6d1..0000000
--- a/chrome/browser/ui/webui/internals/web_app/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2020 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//mojo/public/tools/bindings/mojom.gni")
-
-mojom("mojo_bindings") {
-  sources = [ "web_app_internals.mojom" ]
-}
diff --git a/chrome/browser/ui/webui/internals/web_app/OWNERS b/chrome/browser/ui/webui/internals/web_app/OWNERS
deleted file mode 100644
index a74f103..0000000
--- a/chrome/browser/ui/webui/internals/web_app/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-file://chrome/browser/web_applications/OWNERS
-
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom b/chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom
deleted file mode 100644
index e708cd73..0000000
--- a/chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module mojom.web_app_internals;
-
-struct WebApp {
-  // The web app's ID.
-  string id;
-
-  // The web app's name.
-  string name;
-
-  // Debugging info about the web app's internal state.
-  string debug_info;
-};
-
-struct DisabledConfig {
-  // The string representation of the config.
-  string config;
-
-  // The reason the config was disabled.
-  string reason;
-};
-
-struct InstallResult {
-  // The install_url of the config being installed.
-  string install_url;
-
-  // The InstallResultCode returned by the installation process.
-  string install_result_code;
-
-  // Whether the installation uninstalled and replaced an old app.
-  bool did_uninstall_and_replace;
-};
-
-struct UninstallResult {
-  // The install_url of the config being uninstalled.
-  string install_url;
-
-  // Whether the uninstallation was successful.
-  bool is_success;
-};
-
-struct PreinstalledWebAppDebugInfo {
-  // Whether preinstalled web apps have completed start up synchronization.
-  bool is_start_up_task_complete;
-
-  // Errors encountered when parsing preinstalled web app configs.
-  array<string> parse_errors;
-
-  // String representations of enabled preinstalled app configs.
-  array<string> enabled_configs;
-
-  // String representations of disabled preinstalled app configs plus the reason
-  // why they are disabled.
-  array<DisabledConfig> disabled_configs;
-
-  // The results of any new preinstalled app installations.
-  array<InstallResult> install_results;
-
-  // The results of any preinstalled app removals.
-  array<UninstallResult> uninstall_results;
-};
-
-// Provides access to browser side internal information about installed web apps
-// (also known as PWAs) for chrome://internals/web-app.
-interface WebAppInternalsPageHandler {
-  // Returns details of all the installed web apps for the current profile.
-  GetWebApps() => (array<WebApp> web_app_list);
-
-  // Returns debug information about the state of preinstalled web apps.
-  GetPreinstalledWebAppDebugInfo() => (PreinstalledWebAppDebugInfo? status);
-
-  // Returns the prefs used for keeping track of non-user installed web apps.
-  GetExternallyInstalledWebAppPrefs() =>
-      (string externally_installed_web_app_prefs);
-
-  // Returns a list of error messages generated by icon reading/writing.
-  GetIconErrorLog() => (array<string>? icon_error_log);
-};
diff --git a/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.cc b/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.cc
deleted file mode 100644
index 5584af5..0000000
--- a/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.h"
-
-#include <sstream>
-#include <utility>
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/web_applications/components/web_app_constants.h"
-#include "chrome/browser/web_applications/preinstalled_web_app_manager.h"
-#include "chrome/browser/web_applications/web_app.h"
-#include "chrome/browser/web_applications/web_app_icon_manager.h"
-#include "chrome/browser/web_applications/web_app_provider.h"
-#include "chrome/browser/web_applications/web_app_registrar.h"
-#include "chrome/common/chrome_features.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/grit/dev_ui_browser_resources.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/web_ui_data_source.h"
-
-namespace {
-
-template <typename T>
-std::string ConvertToString(const T& value) {
-  std::stringstream ss;
-  ss << value;
-  return ss.str();
-}
-
-}  // namespace
-
-WebAppInternalsPageHandlerImpl::WebAppInternalsPageHandlerImpl(Profile* profile)
-    : profile_(profile) {}
-
-WebAppInternalsPageHandlerImpl::~WebAppInternalsPageHandlerImpl() = default;
-
-void WebAppInternalsPageHandlerImpl::AddPageResources(
-    content::WebUIDataSource* source) {
-  source->DisableTrustedTypesCSP();
-  source->AddResourcePath("web_app_internals.mojom-lite.js",
-                          IDR_WEB_APP_INTERNALS_MOJOM_LITE_JS);
-  source->AddResourcePath("web_app_internals.js", IDR_WEB_APP_INTERNALS_JS);
-  source->AddResourcePath("web-app", IDR_WEB_APP_INTERNALS_HTML);
-}
-
-void WebAppInternalsPageHandlerImpl::GetWebApps(GetWebAppsCallback callback) {
-  auto* provider = web_app::WebAppProvider::Get(profile_);
-  if (!provider) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  web_app::AppRegistrar& registrar_base = provider->registrar();
-  web_app::WebAppRegistrar* registrar = registrar_base.AsWebAppRegistrar();
-  if (!registrar) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  std::vector<mojom::web_app_internals::WebAppPtr> result;
-  for (const web_app::WebApp& web_app : registrar->GetAppsIncludingStubs()) {
-    auto info = mojom::web_app_internals::WebApp::New();
-    info->name = web_app.name();
-    info->id = web_app.app_id();
-    info->debug_info = ConvertToString(web_app);
-    result.push_back(std::move(info));
-  }
-
-  std::move(callback).Run(std::move(result));
-}
-
-void WebAppInternalsPageHandlerImpl::GetPreinstalledWebAppDebugInfo(
-    GetPreinstalledWebAppDebugInfoCallback callback) {
-  auto* provider = web_app::WebAppProvider::Get(profile_);
-  if (!provider) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  const web_app::PreinstalledWebAppManager::DebugInfo* debug_info =
-      provider->preinstalled_web_app_manager().debug_info();
-  if (!debug_info) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  auto info = mojom::web_app_internals::PreinstalledWebAppDebugInfo::New();
-
-  info->is_start_up_task_complete = debug_info->is_start_up_task_complete;
-
-  info->parse_errors = debug_info->parse_errors;
-
-  for (const web_app::ExternalInstallOptions& config :
-       debug_info->enabled_configs) {
-    info->enabled_configs.push_back(ConvertToString(config));
-  }
-
-  for (const std::pair<web_app::ExternalInstallOptions, std::string>&
-           disabled_config : debug_info->disabled_configs) {
-    auto disabled_config_info = mojom::web_app_internals::DisabledConfig::New();
-    disabled_config_info->config = ConvertToString(disabled_config.first);
-    disabled_config_info->reason = disabled_config.second;
-    info->disabled_configs.push_back(std::move(disabled_config_info));
-  }
-
-  for (std::pair<const GURL&,
-                 const web_app::ExternallyManagedAppManager::InstallResult&>
-           install_result : debug_info->install_results) {
-    auto install_result_info = mojom::web_app_internals::InstallResult::New();
-    install_result_info->install_url = install_result.first.spec();
-    install_result_info->install_result_code =
-        ConvertToString(install_result.second.code);
-    install_result_info->did_uninstall_and_replace =
-        install_result.second.did_uninstall_and_replace;
-    info->install_results.push_back(std::move(install_result_info));
-  }
-
-  for (std::pair<const GURL&, const bool&> uninstall_result :
-       debug_info->uninstall_results) {
-    auto uninstall_result_info =
-        mojom::web_app_internals::UninstallResult::New();
-    uninstall_result_info->install_url = uninstall_result.first.spec();
-    uninstall_result_info->is_success = uninstall_result.second;
-    info->uninstall_results.push_back(std::move(uninstall_result_info));
-  }
-
-  std::move(callback).Run(std::move(info));
-}
-
-void WebAppInternalsPageHandlerImpl::GetExternallyInstalledWebAppPrefs(
-    GetExternallyInstalledWebAppPrefsCallback callback) {
-  std::move(callback).Run(ConvertToString(
-      *profile_->GetPrefs()->GetDictionary(prefs::kWebAppsExtensionIDs)));
-}
-
-void WebAppInternalsPageHandlerImpl::GetIconErrorLog(
-    GetIconErrorLogCallback callback) {
-  auto* provider = web_app::WebAppProvider::Get(profile_);
-  if (!provider) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  const std::vector<std::string>* icon_error_log =
-      provider->icon_manager().AsWebAppIconManager()->error_log();
-  if (!icon_error_log) {
-    std::move(callback).Run({});
-    return;
-  }
-
-  std::move(callback).Run(*icon_error_log);
-}
diff --git a/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.h b/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.h
deleted file mode 100644
index 5bd0d610..0000000
--- a/chrome/browser/ui/webui/internals/web_app/web_app_internals_page_handler_impl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_INTERNALS_WEB_APP_WEB_APP_INTERNALS_PAGE_HANDLER_IMPL_H_
-#define CHROME_BROWSER_UI_WEBUI_INTERNALS_WEB_APP_WEB_APP_INTERNALS_PAGE_HANDLER_IMPL_H_
-
-#include "chrome/browser/ui/webui/internals/web_app/web_app_internals.mojom.h"
-
-class Profile;
-
-namespace content {
-class WebUIDataSource;
-}
-
-// Handles API requests from chrome://internals/web-app.
-class WebAppInternalsPageHandlerImpl
-    : public mojom::web_app_internals::WebAppInternalsPageHandler {
- public:
-  explicit WebAppInternalsPageHandlerImpl(Profile* profile);
-  WebAppInternalsPageHandlerImpl(const WebAppInternalsPageHandlerImpl&) =
-      delete;
-  WebAppInternalsPageHandlerImpl& operator=(
-      const WebAppInternalsPageHandlerImpl&) = delete;
-  ~WebAppInternalsPageHandlerImpl() override;
-
-  static void AddPageResources(content::WebUIDataSource* source);
-
-  // mojom::web_app_internals::WebAppInternalsPageHandler:
-  void GetWebApps(GetWebAppsCallback callback) override;
-  void GetPreinstalledWebAppDebugInfo(
-      GetPreinstalledWebAppDebugInfoCallback callback) override;
-  void GetExternallyInstalledWebAppPrefs(
-      GetExternallyInstalledWebAppPrefsCallback callback) override;
-  void GetIconErrorLog(GetIconErrorLogCallback callback) override;
-
- private:
-  Profile* profile_ = nullptr;
-};
-
-#endif  // CHROME_BROWSER_UI_WEBUI_INTERNALS_WEB_APP_WEB_APP_INTERNALS_PAGE_HANDLER_IMPL_H_
diff --git a/chrome/browser/ui/webui/management/management_a11y_browsertest.h b/chrome/browser/ui/webui/management/management_a11y_browsertest.h
index 14f76e5f..3fb5f1d 100644
--- a/chrome/browser/ui/webui/management/management_a11y_browsertest.h
+++ b/chrome/browser/ui/webui/management/management_a11y_browsertest.h
@@ -19,7 +19,9 @@
  protected:
   void InstallPowerfulPolicyEnforcedExtension();
   const base::FilePath test_data_dir_;
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::FakeBrowserDMTokenStorage fake_dm_token_storage_;
+#endif
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_MANAGEMENT_MANAGEMENT_A11Y_BROWSERTEST_H_
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index f7ea3e5..aad343ff 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -1186,7 +1186,7 @@
   DCHECK(printer_type == PrinterType::kExtension ||
          printer_type == PrinterType::kPrivet ||
          printer_type == PrinterType::kLocal);
-  DCHECK(!printers.empty());
+  DCHECK(!printers.GetList().empty());
   FireWebUIListener("printers-added",
                     base::Value(static_cast<int>(printer_type)), printers);
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index b3ffb67..31a301f 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -202,7 +202,7 @@
 
   void StartGetPrinters(AddedPrintersCallback added_printers_callback,
                         GetPrintersDoneCallback done_callback) override {
-    if (!printers_.empty())
+    if (!printers_.GetList().empty())
       added_printers_callback.Run(printers_);
     std::move(done_callback).Run();
   }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
index 0664afe..3bf9ed09 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
@@ -173,7 +173,7 @@
 
   VLOG(1) << "Enumerate printers finished, found " << printers.GetSize()
           << " printers";
-  if (!printers.empty())
+  if (!printers.GetList().empty())
     callback.Run(printers);
   std::move(done_callback).Run();
 }
diff --git a/chrome/browser/ui/webui/settings/chromeos/OWNERS b/chrome/browser/ui/webui/settings/chromeos/OWNERS
index e26540b..c7ffc2b 100644
--- a/chrome/browser/ui/webui/settings/chromeos/OWNERS
+++ b/chrome/browser/ui/webui/settings/chromeos/OWNERS
@@ -3,3 +3,4 @@
 per-file languages_section*=myy@chromium.org
 per-file multidevice_handler*=file://chromeos/components/multidevice/OWNERS
 per-file account_manager_*=file://ash/components/account_manager/OWNERS
+per-file apps_section*=file://chrome/browser/ui/webui/app_management/OWNERS
diff --git a/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc b/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
index fa5bb35..1d15407 100644
--- a/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
@@ -181,7 +181,7 @@
 
 void AmbientModeHandler::HandleRequestSettings(const base::ListValue* args) {
   CHECK(args);
-  CHECK(args->empty());
+  CHECK(args->GetList().empty());
 
   AllowJavascript();
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h b/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h
index a87e72e3..fbd61389 100644
--- a/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h
+++ b/chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h
@@ -23,7 +23,8 @@
   kAppManagementMainViewPluginVm = 10,
   kDBusServicePluginVm = 11,
   kNotificationPluginVm = 12,
-  kMaxValue = kNotificationPluginVm,
+  kAppManagementMainViewBorealis = 13,
+  kMaxValue = kAppManagementMainViewBorealis,
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_APP_MANAGEMENT_APP_MANAGEMENT_UMA_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
index 6a78692..52fe0de 100644
--- a/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -138,6 +138,10 @@
       {"appManagementIntentSharingLabel", IDS_APP_MANAGEMENT_INTENT_SHARING},
       {"appManagementIntentSharingOpenAppLabel",
        IDS_APP_MANAGEMENT_INTENT_SHARING_APP_OPEN},
+      {"appManagementIntentSharingTabExplanation",
+       IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_EXPLANATION},
+      {"appManagementIntentSharingTabLearnMore",
+       IDS_APP_MANAGEMENT_INTENT_SHARING_TAB_LEARN_MORE},
       {"appManagementMicrophonePermissionLabel", IDS_APP_MANAGEMENT_MICROPHONE},
       {"appManagementMoreSettingsLabel", IDS_APP_MANAGEMENT_MORE_SETTINGS},
       {"appManagementNoAppsFound", IDS_APP_MANAGEMENT_NO_APPS_FOUND},
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
index e3d774b..7633dea 100644
--- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -162,7 +162,7 @@
 }
 
 void ChangePictureHandler::HandleChooseFile(const base::ListValue* args) {
-  DCHECK(args && args->empty());
+  DCHECK(args && args->GetList().empty());
   select_file_dialog_ = ui::SelectFileDialog::Create(
       this,
       std::make_unique<ChromeSelectFilePolicy>(web_ui()->GetWebContents()));
@@ -184,7 +184,7 @@
 }
 
 void ChangePictureHandler::HandleDiscardPhoto(const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   AccessibilityManager::Get()->PlayEarcon(
       Sound::kObjectDelete, PlaySoundOption::kOnlyIfSpokenFeedbackEnabled);
 }
@@ -219,7 +219,7 @@
 }
 
 void ChangePictureHandler::HandlePageInitialized(const base::ListValue* args) {
-  DCHECK(args && args->empty());
+  DCHECK(args && args->GetList().empty());
 
   AllowJavascript();
 
diff --git a/chrome/browser/ui/webui/settings/import_data_handler.cc b/chrome/browser/ui/webui/settings/import_data_handler.cc
index f1f2fe7..954d6b8 100644
--- a/chrome/browser/ui/webui/settings/import_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/import_data_handler.cc
@@ -167,7 +167,7 @@
   if (select_file_dialog_)
     return;
 
-  DCHECK(args && args->empty());
+  DCHECK(args && args->GetList().empty());
   select_file_dialog_ = ui::SelectFileDialog::Create(
       this,
       std::make_unique<ChromeSelectFilePolicy>(web_ui()->GetWebContents()));
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
index 8220f6a..6b3ca233 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
@@ -75,7 +75,7 @@
 
     // Expect a non-empty list of dictionaries containing non-empty strings for
     // profile avatar icon urls and labels.
-    EXPECT_FALSE(icons->empty());
+    EXPECT_FALSE(icons->GetList().empty());
     if (gaia_included) {
       VerifyGaiaAvatar(icons, gaia_selected);
     } else {
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
index 3559fd59..7869a65 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -795,7 +795,7 @@
           ->GetProfileAttributesStorage()
           .GetAllProfilesAttributesSortedByLocalProfilName();
   base::EraseIf(ordered_entries, [](const ProfileAttributesEntry* entry) {
-    return entry->IsGuest() || entry->IsOmitted();
+    return entry->IsOmitted();
   });
   size_t number_of_profiles = ordered_entries.size();
 
@@ -868,7 +868,7 @@
           ->GetProfileAttributesStorage()
           .GetProfileAttributesWithPath(profile_path);
   CHECK(entry);
-  if (entry->IsGuest() || entry->IsOmitted())
+  if (entry->IsOmitted())
     return;
   AddProfileToList(profile_path);
   PushProfilesList();
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.h b/chrome/browser/ui/webui/signin/profile_picker_handler.h
index b000a77..f5d0b7e 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler.h
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler.h
@@ -113,7 +113,7 @@
   void SetProfilesOrder(const std::vector<ProfileAttributesEntry*>& entries);
 
   // Returns the list of profiles in the same order as when the picker
-  // was first shown. Guest profile is not included here.
+  // was first shown.
   std::vector<ProfileAttributesEntry*> GetProfileAttributes();
 
   // Creation time of the handler, to measure performance on startup. Only set
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
index 6f7695c..1ff72d78 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
+++ b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
@@ -164,7 +164,7 @@
     list.Append(std::move(dict));
     last_log_id_sent = log_entry->id;
   }
-  if (list.empty())
+  if (list.GetList().empty())
     return;
 
   ResolveJavascriptCallback(args->GetList()[0] /* callback_id */, list);
diff --git a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
index ef9e7fe..da4b556 100644
--- a/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -155,7 +155,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestDataAndRegisterForUpdates(
     const ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   AllowJavascript();
 
   // is_registered_ flag protects us from double-registering.  This could
@@ -180,7 +180,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestListOfTypes(
     const ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   AllowJavascript();
 
   DictionaryValue event_details;
@@ -196,7 +196,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestIncludeSpecificsInitialState(
     const ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   AllowJavascript();
 
   DictionaryValue value;
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.cc
index d2da44ca..abda949 100644
--- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.cc
+++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.cc
@@ -8,21 +8,27 @@
 #include "base/values.h"
 #include "ui/gfx/geometry/size.h"
 
+namespace {
+
+// The height of the thumbnail.
+constexpr int kThumbnailHeight = 120;
+
+// The padding of the tab item to the top/bottom of the tab strip.
+constexpr int kPaddingAroundTabList = 16;
+
+// The height of the tab title.
+constexpr int kTabTitleHeight = 40;
+
+}  // namespace
+
 // static
 TabStripUILayout TabStripUILayout::CalculateForWebViewportSize(
     const gfx::Size& viewport_size) {
-  // The smaller of the thumbnail's height or width is fixed to this
-  // value. The other dimension will be at least this long.
-  constexpr int kThumbnailMinDimensionLength = 120;
-
   TabStripUILayout layout;
-  layout.padding_around_tab_list = 16;
-  layout.tab_title_height = 40;
   layout.viewport_width = viewport_size.width();
 
   if (viewport_size.IsEmpty()) {
-    layout.tab_thumbnail_size =
-        gfx::Size(kThumbnailMinDimensionLength, kThumbnailMinDimensionLength);
+    layout.tab_thumbnail_size = gfx::Size(kThumbnailHeight, kThumbnailHeight);
     return layout;
   }
 
@@ -31,19 +37,24 @@
   // narrow.
   double ratio =
       std::max(1.0, 1.0 * viewport_size.width() / viewport_size.height());
-  layout.tab_thumbnail_size.set_height(kThumbnailMinDimensionLength);
-  layout.tab_thumbnail_size.set_width(kThumbnailMinDimensionLength * ratio);
+  layout.tab_thumbnail_size.set_height(kThumbnailHeight);
+  layout.tab_thumbnail_size.set_width(kThumbnailHeight * ratio);
   layout.tab_thumbnail_aspect_ratio = ratio;
 
   return layout;
 }
 
+// static
+int TabStripUILayout::GetContainerHeight() {
+  return 2 * kPaddingAroundTabList + kTabTitleHeight + kThumbnailHeight;
+}
+
 base::Value TabStripUILayout::AsDictionary() const {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetStringKey("--tabstrip-tab-list-vertical-padding",
-                    base::NumberToString(padding_around_tab_list) + "px");
+                    base::NumberToString(kPaddingAroundTabList) + "px");
   dict.SetStringKey("--tabstrip-tab-title-height",
-                    base::NumberToString(tab_title_height) + "px");
+                    base::NumberToString(kTabTitleHeight) + "px");
   dict.SetStringKey("--tabstrip-tab-thumbnail-width",
                     base::NumberToString(tab_thumbnail_size.width()) + "px");
   dict.SetStringKey("--tabstrip-tab-thumbnail-height",
@@ -55,7 +66,3 @@
   return dict;
 }
 
-int TabStripUILayout::CalculateContainerHeight() const {
-  return 2 * padding_around_tab_list + tab_title_height +
-         tab_thumbnail_size.height();
-}
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h
index 261aded..2f59058e 100644
--- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h
+++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_layout.h
@@ -15,18 +15,16 @@
   static TabStripUILayout CalculateForWebViewportSize(
       const gfx::Size& viewport_size);
 
+  // Returns the tab strip's total height. This should be used to size
+  // its container.
+  static int GetContainerHeight();
+
   // Returns a dictionary of CSS variables.
   base::Value AsDictionary() const;
 
-  // Returns the tab strip's total height. This should be used to size
-  // its container.
-  int CalculateContainerHeight() const;
-
-  int padding_around_tab_list;
-  int tab_title_height;
-  int viewport_width;
+  int viewport_width = 0;
   gfx::Size tab_thumbnail_size;
-  double tab_thumbnail_aspect_ratio;
+  double tab_thumbnail_aspect_ratio = 1.0;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_TAB_STRIP_TAB_STRIP_UI_LAYOUT_H_
diff --git a/chrome/browser/ui/webui/web_app_internals/OWNERS b/chrome/browser/ui/webui/web_app_internals/OWNERS
new file mode 100644
index 0000000..1255a2c
--- /dev/null
+++ b/chrome/browser/ui/webui/web_app_internals/OWNERS
@@ -0,0 +1 @@
+file://chrome/browser/web_applications/OWNERS
diff --git a/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc
new file mode 100644
index 0000000..6885f25d
--- /dev/null
+++ b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.cc
@@ -0,0 +1,221 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h"
+
+#include "base/json/json_writer.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/ranges/algorithm.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/preinstalled_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_icon_manager.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/webui_url_constants.h"
+#include "components/prefs/pref_service.h"
+
+namespace {
+
+constexpr char kInstalledWebApps[] = "InstalledWebApps";
+constexpr char kPreinstalledWebAppConfigs[] = "PreinstalledWebAppConfigs";
+constexpr char kExternallyManagedWebAppPrefs[] = "ExternallyManagedWebAppPrefs";
+constexpr char kIconErrorLog[] = "IconErrorLog";
+
+constexpr char kNeedsRecordWebAppDebugInfo[] =
+    "No debugging info available! Please enable: "
+    "chrome://flags/#record-web-app-debug-info";
+
+template <typename T>
+std::string ConvertToString(const T& value) {
+  std::stringstream ss;
+  ss << value;
+  return ss.str();
+}
+
+base::Value BuildIndexJson() {
+  base::Value root(base::Value::Type::DICTIONARY);
+  base::Value& index =
+      *root.SetKey("Index", base::Value(base::Value::Type::LIST));
+
+  index.Append(kInstalledWebApps);
+  index.Append(kPreinstalledWebAppConfigs);
+  index.Append(kExternallyManagedWebAppPrefs);
+  index.Append(kIconErrorLog);
+
+  return root;
+}
+
+base::Value BuildInstalledWebAppsJson(web_app::WebAppProvider& provider) {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  base::Value& installed_web_apps = *root.SetKey(
+      kInstalledWebApps, base::Value(base::Value::Type::DICTIONARY));
+
+  std::vector<const web_app::WebApp*> web_apps;
+  for (const web_app::WebApp& web_app :
+       provider.registrar().AsWebAppRegistrar()->GetAppsIncludingStubs()) {
+    web_apps.push_back(&web_app);
+  }
+  base::ranges::sort(web_apps, {}, &web_app::WebApp::name);
+
+  // Prefix with a ! so this appears at the top when serialized.
+  base::Value& index = *installed_web_apps.SetKey(
+      "!Index", base::Value(base::Value::Type::DICTIONARY));
+  for (const web_app::WebApp* web_app : web_apps) {
+    const std::string& key = web_app->name();
+    base::Value* existing_entry = index.FindKey(key);
+    if (!existing_entry) {
+      index.SetStringKey(key, web_app->app_id());
+      continue;
+    }
+    // If any web apps share identical names then collect a list of app IDs.
+    const std::string* existing_id = existing_entry->GetIfString();
+    if (existing_id) {
+      base::Value id_copy(*existing_id);
+      index.SetKey(key, base::Value(base::Value::Type::LIST))
+          ->Append(std::move(id_copy));
+    }
+    index.FindListKey(key)->Append(web_app->app_id());
+  }
+
+  base::Value& web_app_details = *installed_web_apps.SetKey(
+      "Details", base::Value(base::Value::Type::LIST));
+  for (const web_app::WebApp* web_app : web_apps)
+    web_app_details.Append(web_app->AsDebugValue());
+
+  return root;
+}
+
+base::Value BuildPreinstalledWebAppConfigsJson(
+    web_app::WebAppProvider& provider) {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  const web_app::PreinstalledWebAppManager::DebugInfo* debug_info =
+      provider.preinstalled_web_app_manager().debug_info();
+  if (!debug_info) {
+    root.SetStringKey(kPreinstalledWebAppConfigs, kNeedsRecordWebAppDebugInfo);
+    return root;
+  }
+
+  base::Value& preinstalled_web_app_configs = *root.SetKey(
+      kPreinstalledWebAppConfigs, base::Value(base::Value::Type::DICTIONARY));
+
+  base::Value& config_parse_errors = *preinstalled_web_app_configs.SetKey(
+      "ConfigParseErrors", base::Value(base::Value::Type::LIST));
+  for (const std::string& parse_error : debug_info->parse_errors)
+    config_parse_errors.Append(parse_error);
+
+  base::Value& configs_enabled = *preinstalled_web_app_configs.SetKey(
+      "ConfigsEnabled", base::Value(base::Value::Type::LIST));
+  for (const web_app::ExternalInstallOptions& enabled_config :
+       debug_info->enabled_configs) {
+    configs_enabled.Append(enabled_config.AsDebugValue());
+  }
+
+  base::Value& configs_disabled = *preinstalled_web_app_configs.SetKey(
+      "ConfigsDisabled", base::Value(base::Value::Type::LIST));
+  for (const std::pair<web_app::ExternalInstallOptions, std::string>&
+           disabled_config : debug_info->disabled_configs) {
+    base::Value entry(base::Value::Type::DICTIONARY);
+    entry.SetStringKey("!Reason", disabled_config.second);
+    entry.SetKey("Config", disabled_config.first.AsDebugValue());
+    configs_disabled.Append(std::move(entry));
+  }
+
+  base::Value& install_results = *preinstalled_web_app_configs.SetKey(
+      "InstallResults", base::Value(base::Value::Type::LIST));
+  for (std::pair<const GURL&,
+                 const web_app::ExternallyManagedAppManager::InstallResult&>
+           install_result : debug_info->install_results) {
+    base::Value entry(base::Value::Type::DICTIONARY);
+    entry.SetStringKey("InstallUrl", install_result.first.spec());
+    entry.SetStringKey("ResultCode",
+                       ConvertToString(install_result.second.code));
+    entry.SetBoolKey("DidUninstallAndReplace",
+                     install_result.second.did_uninstall_and_replace);
+    install_results.Append(std::move(entry));
+  }
+
+  preinstalled_web_app_configs.SetBoolKey(
+      "IsStartUpTaskComplete", debug_info->is_start_up_task_complete);
+
+  base::Value& uninstall_results = *preinstalled_web_app_configs.SetKey(
+      "UninstallResults", base::Value(base::Value::Type::LIST));
+  for (std::pair<const GURL&, const bool&> uninstall_result :
+       debug_info->uninstall_results) {
+    base::Value entry(base::Value::Type::DICTIONARY);
+    entry.SetStringKey("InstallUrl", uninstall_result.first.spec());
+    entry.SetBoolKey("Success", uninstall_result.second);
+    uninstall_results.Append(std::move(entry));
+  }
+
+  return root;
+}
+
+base::Value BuildExternallyManagedWebAppPrefsJson(Profile* profile) {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetKey(
+      kExternallyManagedWebAppPrefs,
+      profile->GetPrefs()->GetDictionary(prefs::kWebAppsExtensionIDs)->Clone());
+  return root;
+}
+
+base::Value BuildIconErrorLogJson(web_app::WebAppProvider& provider) {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  const std::vector<std::string>* error_log =
+      provider.icon_manager().AsWebAppIconManager()->error_log();
+
+  if (!error_log) {
+    root.SetStringKey(kIconErrorLog, kNeedsRecordWebAppDebugInfo);
+    return root;
+  }
+
+  base::Value& icon_error_log =
+      *root.SetKey(kIconErrorLog, base::Value(base::Value::Type::LIST));
+  for (const std::string& error : *error_log)
+    icon_error_log.Append(error);
+
+  return root;
+}
+
+base::Value BuildWebAppInternalsJson(Profile* profile) {
+  auto* provider = web_app::WebAppProvider::Get(profile);
+  if (!provider)
+    return base::Value("Web app system not enabled for profile.");
+
+  base::Value root(base::Value::Type::LIST);
+  root.Append(BuildIndexJson());
+  root.Append(BuildInstalledWebAppsJson(*provider));
+  root.Append(BuildPreinstalledWebAppConfigsJson(*provider));
+  root.Append(BuildExternallyManagedWebAppPrefsJson(profile));
+  root.Append(BuildIconErrorLogJson(*provider));
+
+  return root;
+}
+
+}  // namespace
+
+WebAppInternalsSource::WebAppInternalsSource(Profile* profile)
+    : profile_(profile) {}
+
+WebAppInternalsSource::~WebAppInternalsSource() = default;
+
+std::string WebAppInternalsSource::GetSource() {
+  return chrome::kChromeUIWebAppInternalsHost;
+}
+
+std::string WebAppInternalsSource::GetMimeType(const std::string& path) {
+  return "application/json";
+}
+
+void WebAppInternalsSource::StartDataRequest(
+    const GURL& url,
+    const content::WebContents::Getter& wc_getter,
+    content::URLDataSource::GotDataCallback callback) {
+  std::string data = ConvertToString(BuildWebAppInternalsJson(profile_));
+  std::move(callback).Run(base::RefCountedString::TakeString(&data));
+}
diff --git a/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h
new file mode 100644
index 0000000..2c104e7
--- /dev/null
+++ b/chrome/browser/ui/webui/web_app_internals/web_app_internals_source.h
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_WEB_APP_INTERNALS_WEB_APP_INTERNALS_SOURCE_H_
+#define CHROME_BROWSER_UI_WEBUI_WEB_APP_INTERNALS_WEB_APP_INTERNALS_SOURCE_H_
+
+#include <string>
+
+#include "content/public/browser/url_data_source.h"
+
+class Profile;
+
+// A simple JSON data source that returns web app debugging information for the
+// associated profile.
+class WebAppInternalsSource : public content::URLDataSource {
+ public:
+  explicit WebAppInternalsSource(Profile* profile);
+  WebAppInternalsSource(const WebAppInternalsSource&) = delete;
+  WebAppInternalsSource& operator=(const WebAppInternalsSource&) = delete;
+  ~WebAppInternalsSource() override;
+
+  // content::URLDataSource:
+  std::string GetSource() override;
+  std::string GetMimeType(const std::string& path) override;
+  void StartDataRequest(
+      const GURL& url,
+      const content::WebContents::Getter& wc_getter,
+      content::URLDataSource::GotDataCallback callback) override;
+
+ private:
+  Profile* const profile_;
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_WEB_APP_INTERNALS_WEB_APP_INTERNALS_SOURCE_H_
diff --git a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
index 138fa22..80018043 100644
--- a/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
+++ b/chrome/browser/ui/zoom/chrome_zoom_level_prefs.cc
@@ -165,18 +165,18 @@
        !i.IsAtEnd();
        i.Advance()) {
     const std::string& host(i.key());
-    double zoom_level = 0;
+
+    absl::optional<double> maybe_zoom;
     base::Time last_modified;
 
-    bool has_valid_zoom_level;
     if (i.value().is_dict()) {
       const base::DictionaryValue* dict;
       i.value().GetAsDictionary(&dict);
-      has_valid_zoom_level = dict->GetDouble(kZoomLevelPath, &zoom_level);
+      maybe_zoom = dict->FindDoubleKey(kZoomLevelPath);
       last_modified = GetTimeStamp(dict);
     } else {
       // Old zoom level that is stored directly as a double.
-      has_valid_zoom_level = i.value().GetAsDouble(&zoom_level);
+      maybe_zoom = i.value().GetIfDouble();
     }
 
     // Filter out A) the empty host, B) zoom levels equal to the default; and
@@ -186,14 +186,15 @@
     // level was set to its current value. In either case, SetZoomLevelForHost
     // will ignore type B values, thus, to have consistency with HostZoomMap's
     // internal state, these values must also be removed from Prefs.
-    if (host.empty() || !has_valid_zoom_level ||
-        blink::PageZoomValuesEqual(zoom_level,
+    if (host.empty() || !maybe_zoom.has_value() ||
+        blink::PageZoomValuesEqual(maybe_zoom.value_or(0),
                                    host_zoom_map_->GetDefaultZoomLevel())) {
       keys_to_remove.push_back(host);
       continue;
     }
 
-    host_zoom_map_->InitializeZoomLevelForHost(host, zoom_level, last_modified);
+    host_zoom_map_->InitializeZoomLevelForHost(host, maybe_zoom.value(),
+                                               last_modified);
   }
 
   // We don't bother sanitizing non-partition dictionaries as they will be
diff --git a/chrome/browser/usb/usb_chooser_controller.cc b/chrome/browser/usb/usb_chooser_controller.cc
index cba03cc..7513c01 100644
--- a/chrome/browser/usb/usb_chooser_controller.cc
+++ b/chrome/browser/usb/usb_chooser_controller.cc
@@ -96,11 +96,11 @@
                              IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME)),
       filters_(std::move(device_filters)),
       callback_(std::move(callback)),
-      web_contents_(WebContents::FromRenderFrameHost(render_frame_host)) {
-  RenderFrameHost* main_frame = web_contents_->GetMainFrame();
+      requesting_frame_(render_frame_host) {
+  RenderFrameHost* main_frame = requesting_frame_->GetMainFrame();
   origin_ = main_frame->GetLastCommittedOrigin();
   Profile* profile =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
+      Profile::FromBrowserContext(main_frame->GetBrowserContext());
   chooser_context_ =
       UsbChooserContextFactory::GetForProfile(profile)->AsWeakPtr();
   DCHECK(chooser_context_);
@@ -199,10 +199,12 @@
 void UsbChooserController::Close() {}
 
 void UsbChooserController::OpenHelpCenterUrl() const {
-  web_contents_->OpenURL(content::OpenURLParams(
-      GURL(chrome::kChooserUsbOverviewURL), content::Referrer(),
-      WindowOpenDisposition::NEW_FOREGROUND_TAB,
-      ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initialized */));
+  WebContents::FromRenderFrameHost(requesting_frame_)
+      ->OpenURL(content::OpenURLParams(
+          GURL(chrome::kChooserUsbOverviewURL), content::Referrer(),
+          WindowOpenDisposition::NEW_FOREGROUND_TAB,
+          ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
+          false /* is_renderer_initialized */));
 }
 
 void UsbChooserController::OnDeviceAdded(
diff --git a/chrome/browser/usb/usb_chooser_controller.h b/chrome/browser/usb/usb_chooser_controller.h
index feb2639..9acbb27 100644
--- a/chrome/browser/usb/usb_chooser_controller.h
+++ b/chrome/browser/usb/usb_chooser_controller.h
@@ -22,7 +22,6 @@
 
 namespace content {
 class RenderFrameHost;
-class WebContents;
 }
 
 // UsbChooserController creates a chooser for WebUSB.
@@ -62,7 +61,7 @@
   blink::mojom::WebUsbService::GetPermissionCallback callback_;
   url::Origin origin_;
 
-  content::WebContents* const web_contents_;
+  content::RenderFrameHost* const requesting_frame_;
   base::WeakPtr<UsbChooserContext> chooser_context_;
   base::ScopedObservation<UsbChooserContext, UsbChooserContext::DeviceObserver>
       observation_{this};
diff --git a/chrome/browser/web_applications/README.md b/chrome/browser/web_applications/README.md
index 4dfc243..682ba079 100644
--- a/chrome/browser/web_applications/README.md
+++ b/chrome/browser/web_applications/README.md
@@ -132,7 +132,7 @@
 * The `WebAppProvider` core system lives on the `Profile` object.
 * The `WebAppUiManagerImpl` also lives on the `Profile` object (to avoid deps issues).
 * The `AppBrowserController` (typically `WebAppBrowserController` for our interests) lives on the `Browser` object.
-* The `WebAppTabHelperBase` lives on the `WebContents` object.
+* The `WebAppTabHelper` lives on the `WebContents` object.
 
 While most on-disk storage is done in the [`WebAppSyncBridge`](#webappsyncbridge), the system also sometimes uses the `PrefService`. Most of these prefs live on the `Profile` (`profile->GetPrefs()`), but some prefs are in the global browser prefs (`g_browser_process->local_state()`). See the [storage](#storage) section below for more info.
 
@@ -239,5 +239,6 @@
 
 ## Debugging
 
-Use [chrome://internals/web-app](chrome://internals/web-app) to inspect internal
-web app state.
+Use [chrome://web-app-internals](chrome://web-app-internals) to inspect internal
+web app state. For Chromium versions prior to M93 use
+[chrome://internals/web-app](chrome://internals/web-app).
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index f81a02c..ffbf044 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -50,7 +50,6 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/arc/arc_web_contents_data.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
-#include "chrome/browser/chromeos/extensions/gfx_utils.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
 #include "components/full_restore/app_launch_info.h"
 #include "components/full_restore/full_restore_utils.h"
@@ -1009,14 +1008,6 @@
     icon_effects |= IconEffects::kBlocked;
   }
 
-// TODO(crbug.com/1214707): Implement badging for Lacros.
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (extensions::util::ShouldApplyChromeBadgeToWebApp(profile(),
-                                                       web_app->app_id())) {
-    icon_effects |= IconEffects::kChromeBadge;
-  }
-#endif
-
   return icon_effects;
 }
 
diff --git a/chrome/browser/web_applications/app_service/web_apps_chromeos.cc b/chrome/browser/web_applications/app_service/web_apps_chromeos.cc
index 68703268..5b9d594 100644
--- a/chrome/browser/web_applications/app_service/web_apps_chromeos.cc
+++ b/chrome/browser/web_applications/app_service/web_apps_chromeos.cc
@@ -21,11 +21,8 @@
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/apps/app_service/menu_item_constants.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
-#include "chrome/browser/ash/arc/arc_util.h"
-#include "chrome/browser/ash/arc/arc_web_contents_data.h"
 #include "chrome/browser/chromeos/extensions/gfx_utils.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_manager.h"
 #include "chrome/browser/ui/web_applications/web_app_ui_manager_impl.h"
@@ -41,7 +38,6 @@
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/arc/arc_service_manager.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -67,36 +63,7 @@
   Initialize();
 }
 
-WebAppsChromeOs::~WebAppsChromeOs() {
-  // In unit tests, AppServiceProxy might be ReInitializeForTesting, so
-  // WebApps might be destroyed without calling Shutdown, so arc_prefs_
-  // needs to be removed from observer in the destructor function.
-  if (arc_prefs_) {
-    arc_prefs_->RemoveObserver(this);
-    arc_prefs_ = nullptr;
-  }
-}
-
-void WebAppsChromeOs::Shutdown() {
-  if (arc_prefs_) {
-    arc_prefs_->RemoveObserver(this);
-    arc_prefs_ = nullptr;
-  }
-
-  WebAppsBase::Shutdown();
-}
-
-void WebAppsChromeOs::ObserveArc() {
-  // Observe the ARC apps to set the badge on the equivalent web app's icon.
-  if (arc_prefs_) {
-    arc_prefs_->RemoveObserver(this);
-  }
-
-  arc_prefs_ = ArcAppListPrefs::Get(profile());
-  if (arc_prefs_) {
-    arc_prefs_->AddObserver(this);
-  }
-}
+WebAppsChromeOs::~WebAppsChromeOs() = default;
 
 void WebAppsChromeOs::Initialize() {
   DCHECK(profile());
@@ -304,39 +271,4 @@
   publisher_helper().SetWindowMode(app_id, window_mode);
 }
 
-void WebAppsChromeOs::OnPackageInstalled(
-    const arc::mojom::ArcPackageInfo& package_info) {
-  ApplyChromeBadge(package_info.package_name);
-}
-
-void WebAppsChromeOs::OnPackageRemoved(const std::string& package_name,
-                                       bool uninstalled) {
-  ApplyChromeBadge(package_name);
-}
-
-void WebAppsChromeOs::OnPackageListInitialRefreshed() {
-  if (!arc_prefs_) {
-    return;
-  }
-
-  for (const auto& app_name : arc_prefs_->GetPackagesFromPrefs()) {
-    ApplyChromeBadge(app_name);
-  }
-}
-
-void WebAppsChromeOs::OnArcAppListPrefsDestroyed() {
-  arc_prefs_ = nullptr;
-}
-
-void WebAppsChromeOs::ApplyChromeBadge(const std::string& package_name) {
-  const std::vector<std::string> app_ids =
-      extensions::util::GetEquivalentInstalledAppIds(package_name);
-
-  for (auto& app_id : app_ids) {
-    if (GetWebApp(app_id)) {
-      publisher_helper().SetIconEffect(app_id);
-    }
-  }
-}
-
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/app_service/web_apps_chromeos.h b/chrome/browser/web_applications/app_service/web_apps_chromeos.h
index 687aa73b6..19e5257 100644
--- a/chrome/browser/web_applications/app_service/web_apps_chromeos.h
+++ b/chrome/browser/web_applications/app_service/web_apps_chromeos.h
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/scoped_observation.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/web_applications/app_service/web_apps_base.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
 #include "chrome/browser/web_applications/components/web_application_info.h"
@@ -22,7 +21,7 @@
 namespace web_app {
 
 // An app publisher (in the App Service sense) of Web Apps.
-class WebAppsChromeOs : public WebAppsBase, public ArcAppListPrefs::Observer {
+class WebAppsChromeOs : public WebAppsBase {
  public:
   WebAppsChromeOs(const mojo::Remote<apps::mojom::AppService>& app_service,
                   Profile* profile,
@@ -31,10 +30,6 @@
   WebAppsChromeOs& operator=(const WebAppsChromeOs&) = delete;
   ~WebAppsChromeOs() override;
 
-  void Shutdown() override;
-
-  void ObserveArc();
-
  private:
   void Initialize();
 
@@ -61,14 +56,6 @@
   void SetWindowMode(const std::string& app_id,
                      apps::mojom::WindowMode window_mode) override;
 
-  // ArcAppListPrefs::Observer overrides.
-  void OnPackageInstalled(
-      const arc::mojom::ArcPackageInfo& package_info) override;
-  void OnPackageRemoved(const std::string& package_name,
-                        bool uninstalled) override;
-  void OnPackageListInitialRefreshed() override;
-  void OnArcAppListPrefsDestroyed() override;
-
   void OnShortcutsMenuIconsRead(
       const std::string& app_id,
       apps::mojom::MenuType menu_type,
@@ -79,15 +66,7 @@
   void StartPublishingWebApps(
       mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote);
 
-  // Get the equivalent Chrome app from |arc_package_name| and set the Chrome
-  // app badge on the icon effects for the equivalent Chrome apps. If the
-  // equivalent ARC app is installed, add the Chrome app badge, otherwise,
-  // remove the Chrome app badge.
-  void ApplyChromeBadge(const std::string& arc_package_name);
-
   apps::InstanceRegistry* instance_registry_;
-
-  ArcAppListPrefs* arc_prefs_ = nullptr;
 };
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn
index 02ee13f..48193b6 100644
--- a/chrome/browser/web_applications/components/BUILD.gn
+++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -73,8 +73,6 @@
     "web_app_shortcuts_menu.h",
     "web_app_system_web_app_data.cc",
     "web_app_system_web_app_data.h",
-    "web_app_tab_helper_base.cc",
-    "web_app_tab_helper_base.h",
     "web_app_ui_manager.h",
     "web_app_uninstallation_via_os_settings_registration.cc",
     "web_app_uninstallation_via_os_settings_registration.h",
diff --git a/chrome/browser/web_applications/components/app_shim_registry_mac.cc b/chrome/browser/web_applications/components/app_shim_registry_mac.cc
index d4bc3db..dee66834 100644
--- a/chrome/browser/web_applications/components/app_shim_registry_mac.cc
+++ b/chrome/browser/web_applications/components/app_shim_registry_mac.cc
@@ -156,7 +156,7 @@
 
   // If there are no installed profiles, clear the app's key.
   if (installed_profiles && installed_profiles->empty()) {
-    update->Remove(app_id, nullptr);
+    update->Remove(app_id);
     return;
   }
 
diff --git a/chrome/browser/web_applications/components/external_install_options.cc b/chrome/browser/web_applications/components/external_install_options.cc
index 517239c..ade9a3d 100644
--- a/chrome/browser/web_applications/components/external_install_options.cc
+++ b/chrome/browser/web_applications/components/external_install_options.cc
@@ -13,6 +13,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_types.h"
+#include "third_party/blink/public/common/manifest/manifest_util.h"
 
 namespace web_app {
 
@@ -83,92 +84,74 @@
   return AsTuple(*this) == AsTuple(other);
 }
 
-namespace {
+base::Value ExternalInstallOptions::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
 
-template <typename T>
-std::ostream& operator<<(std::ostream& out, const absl::optional<T>& optional) {
-  if (optional)
-    out << *optional;
-  else
-    out << "nullopt";
-  return out;
-}
+  auto ConvertStringList = [](const std::vector<std::string> list) {
+    base::Value list_json(base::Value::Type::LIST);
+    for (const std::string& item : list)
+      list_json.Append(item);
+    return list_json;
+  };
 
-template <typename T>
-std::ostream& operator<<(std::ostream& out, const std::vector<T>& list) {
-  out << '[';
-  for (size_t i = 0; i < list.size(); ++i) {
-    if (i > 0)
-      out << ", ";
-    out << list[i];
-  }
-  out << ']';
-  return out;
-}
+  auto ConvertOptional = [](const auto& value) {
+    return value ? base::Value(*value) : base::Value();
+  };
 
-}  // namespace
-
-std::ostream& operator<<(std::ostream& out,
-                         const ExternalInstallOptions& install_options) {
-  return out
-         << "install_url: " << install_options.install_url
-         << "\n user_display_mode: " << install_options.user_display_mode
-         << "\n install_source: "
-         << static_cast<int32_t>(install_options.install_source)
-         << "\n fallback_app_name: "
-         << install_options.fallback_app_name.value_or("")
-         << "\n add_to_applications_menu: "
-         << install_options.add_to_applications_menu
-         << "\n add_to_desktop: " << install_options.add_to_desktop
-         << "\n add_to_quick_launch_bar: "
-         << install_options.add_to_quick_launch_bar
-         << "\n add_to_search: " << install_options.add_to_search
-         << "\n add_to_management: " << install_options.add_to_management
-         << "\n run_on_os_login: " << install_options.run_on_os_login
-         << "\n is_disabled: " << install_options.is_disabled
-         << "\n override_previous_user_uninstall: "
-         << install_options.override_previous_user_uninstall
-         << "\n only_for_new_users: " << install_options.only_for_new_users
-         << "\n only_if_previously_preinstalled: "
-         << install_options.only_if_previously_preinstalled
-         << "\n user_type_allowlist: " << install_options.user_type_allowlist
-         << "\n gate_on_feature: " << install_options.gate_on_feature
+  // Prefix with a ! so this appears at the top when serialized.
+  root.SetStringKey("!install_url", install_url.spec());
+  root.SetBoolKey("add_to_applications_menu", add_to_applications_menu);
+  root.SetBoolKey("add_to_desktop", add_to_desktop);
+  root.SetBoolKey("add_to_management", add_to_management);
+  root.SetBoolKey("add_to_quick_launch_bar", add_to_quick_launch_bar);
+  root.SetBoolKey("add_to_search", add_to_search);
+  root.SetKey("additional_search_terms",
+              ConvertStringList(additional_search_terms));
+  root.SetBoolKey("app_info_factory", static_cast<bool>(app_info_factory));
+  root.SetBoolKey("bypass_service_worker_check", bypass_service_worker_check);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-         << "\n disable_if_arc_supported: "
-         << install_options.disable_if_arc_supported
-         << "\n disable_if_tablet_form_factor: "
-         << install_options.disable_if_tablet_form_factor
+  root.SetBoolKey("disable_if_arc_supported", disable_if_arc_supported);
+  root.SetBoolKey("disable_if_tablet_form_factor",
+                  disable_if_tablet_form_factor);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-         << "\n bypass_service_worker_check: "
-         << install_options.bypass_service_worker_check
-         << "\n require_manifest: " << install_options.require_manifest
-         << "\n force_reinstall: " << install_options.force_reinstall
-         << "\n force_reinstall_for_milestone: "
-         << install_options.force_reinstall_for_milestone
-         << "\n wait_for_windows_closed: "
-         << install_options.wait_for_windows_closed
-         << "\n install_placeholder: " << install_options.install_placeholder
-         << "\n reinstall_placeholder: "
-         << install_options.reinstall_placeholder
-         << "\n launch_query_params: " << install_options.launch_query_params
-         << "\n load_and_await_service_worker_registration: "
-         << install_options.load_and_await_service_worker_registration
-         << "\n service_worker_registration_url: "
-         << install_options.service_worker_registration_url.value_or(GURL())
-         << "\n uninstall_and_replace:\n   "
-         << base::JoinString(install_options.uninstall_and_replace, "\n   ")
-         << "\n additional_search_terms:\n   "
-         << base::JoinString(install_options.additional_search_terms, "\n   ")
-         << "\n only_use_app_info_factory: "
-         << install_options.only_use_app_info_factory << "\n app_info_factory: "
-         << !install_options.app_info_factory.is_null()
-         << "\n system_app_type: "
-         << (install_options.system_app_type.has_value()
-                 ? static_cast<int32_t>(install_options.system_app_type.value())
-                 : -1)
-         << "\n oem_installed: " << install_options.oem_installed
-         << "\n disable_if_touchscreen_with_stylus_not_supported: "
-         << install_options.disable_if_touchscreen_with_stylus_not_supported;
+  root.SetBoolKey("disable_if_touchscreen_with_stylus_not_supported",
+                  disable_if_touchscreen_with_stylus_not_supported);
+  root.SetKey("fallback_app_name", ConvertOptional(fallback_app_name));
+  root.SetBoolKey("force_reinstall", force_reinstall);
+  root.SetKey("force_reinstall_for_milestone",
+              ConvertOptional(force_reinstall_for_milestone));
+  root.SetKey("gate_on_feature", ConvertOptional(gate_on_feature));
+  root.SetBoolKey("install_placeholder", install_placeholder);
+  root.SetIntKey("install_source", static_cast<int>(install_source));
+  root.SetBoolKey("is_disabled", is_disabled);
+  root.SetKey("launch_query_params", ConvertOptional(launch_query_params));
+  root.SetBoolKey("load_and_await_service_worker_registration",
+                  load_and_await_service_worker_registration);
+  root.SetBoolKey("oem_installed", oem_installed);
+  root.SetBoolKey("only_for_new_users", only_for_new_users);
+  root.SetBoolKey("only_if_previously_preinstalled",
+                  only_if_previously_preinstalled);
+  root.SetBoolKey("only_use_app_info_factory", only_use_app_info_factory);
+  root.SetBoolKey("override_previous_user_uninstall",
+                  override_previous_user_uninstall);
+  root.SetBoolKey("reinstall_placeholder", reinstall_placeholder);
+  root.SetBoolKey("require_manifest", require_manifest);
+  root.SetBoolKey("run_on_os_login", run_on_os_login);
+  root.SetKey("service_worker_registration_url",
+              service_worker_registration_url
+                  ? base::Value(service_worker_registration_url->spec())
+                  : base::Value());
+  root.SetKey("system_app_type",
+              system_app_type ? base::Value(static_cast<int>(*system_app_type))
+                              : base::Value());
+  root.SetKey("uninstall_and_replace",
+              ConvertStringList(uninstall_and_replace));
+  root.SetStringKey("user_display_mode",
+                    blink::DisplayModeToString(user_display_mode));
+  root.SetKey("user_type_allowlist", ConvertStringList(user_type_allowlist));
+  root.SetBoolKey("wait_for_windows_closed", wait_for_windows_closed);
+
+  return root;
 }
 
 InstallManager::InstallParams ConvertExternalInstallOptionsToParams(
diff --git a/chrome/browser/web_applications/components/external_install_options.h b/chrome/browser/web_applications/components/external_install_options.h
index ec956054..d0e9ecf 100644
--- a/chrome/browser/web_applications/components/external_install_options.h
+++ b/chrome/browser/web_applications/components/external_install_options.h
@@ -5,10 +5,10 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_EXTERNAL_INSTALL_OPTIONS_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_EXTERNAL_INSTALL_OPTIONS_H_
 
-#include <iosfwd>
 #include <string>
 #include <vector>
 
+#include "base/values.h"
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
@@ -35,6 +35,8 @@
 
   bool operator==(const ExternalInstallOptions& other) const;
 
+  base::Value AsDebugValue() const;
+
   GURL install_url;
   DisplayMode user_display_mode;
   ExternalInstallSource install_source;
@@ -185,9 +187,6 @@
   bool disable_if_touchscreen_with_stylus_not_supported = false;
 };
 
-std::ostream& operator<<(std::ostream& out,
-                         const ExternalInstallOptions& install_options);
-
 InstallManager::InstallParams ConvertExternalInstallOptionsToParams(
     const ExternalInstallOptions& install_options);
 
diff --git a/chrome/browser/web_applications/components/url_handler_prefs.cc b/chrome/browser/web_applications/components/url_handler_prefs.cc
index efd3744..d2d9b2e 100644
--- a/chrome/browser/web_applications/components/url_handler_prefs.cc
+++ b/chrome/browser/web_applications/components/url_handler_prefs.cc
@@ -5,8 +5,12 @@
 #include "chrome/browser/web_applications/components/url_handler_prefs.h"
 
 #include <algorithm>
+#include <string>
+#include <utility>
+#include <vector>
 
 #include "base/check.h"
+#include "base/containers/flat_set.h"
 #include "base/files/file_path.h"
 #include "base/ranges/algorithm.h"
 #include "base/ranges/functional.h"
@@ -37,6 +41,14 @@
 constexpr const char kChoice[] = "choice";
 constexpr const char kTimestamp[] = "timestamp";
 
+// Used to hold the pieces of handler information needed for saving default
+// choices.
+struct HandlerView {
+  const std::string& app_id;
+  base::FilePath profile_path;
+  base::Value& include_paths;
+};
+
 // Returns true if |url| has the same origin as origin_str. If
 // |look_for_subdomains| is true, url must have an origin that extends
 // |origin_str| by at least one sub-domain.
@@ -225,10 +237,18 @@
   if (matches.empty())
     return;
 
-  // Record the most recent match.
+  // Record the most recent match. If two matches have the same timestamp,
+  // prefer the one with a higher saved_choice value.
   auto most_recent_match_iterator = base::ranges::max_element(
-      matches, base::ranges::less(),
-      &UrlHandlerLaunchParams::saved_choice_timestamp);
+      matches, [](const UrlHandlerLaunchParams& match1,
+                  const UrlHandlerLaunchParams& match2) {
+        if (match1.saved_choice_timestamp > match2.saved_choice_timestamp)
+          return false;
+        if (match1.saved_choice_timestamp < match2.saved_choice_timestamp)
+          return true;
+
+        return match1.saved_choice < match2.saved_choice;
+      });
 
   switch (most_recent_match_iterator->saved_choice) {
     case UrlHandlerSavedChoice::kInApp:
@@ -401,11 +421,42 @@
     pref_value.RemoveKey(origin_to_remove);
 }
 
-// Sets |choice| on every path in |include_paths| that matches |url|.
-void UpdateSavedChoice(base::Value& include_paths,
-                       const GURL& url,
-                       UrlHandlerSavedChoice choice,
-                       const base::Time& time) {
+using PathSet = base::flat_set<std::string>;
+
+// Sets |choice| on every include path in |all_include_paths| where the path
+// exists in |updated_include_paths|.
+void UpdateSavedChoiceInIncludePaths(PathSet updated_include_paths,
+                                     UrlHandlerSavedChoice choice,
+                                     const base::Time& time,
+                                     base::Value& all_include_paths) {
+  // |all_include_paths| is a list of include path dicts. Eg:
+  // [ {
+  //    "choice": 0,
+  //    "path": "/abc",
+  //    "timestamp": "-9223372036854775808"
+  // } ]
+  auto include_paths_list = std::move(all_include_paths).TakeList();
+  for (base::Value& include_path_dict : include_paths_list) {
+    if (!include_path_dict.is_dict())
+      continue;
+    const std::string* path = include_path_dict.FindStringKey(kPath);
+    if (!path)
+      continue;
+
+    if (updated_include_paths.contains(*path)) {
+      include_path_dict.SetIntKey(kChoice, static_cast<int>(choice));
+      include_path_dict.SetKey(kTimestamp, util::TimeToValue(time));
+    }
+  }
+  all_include_paths = base::Value(std::move(include_paths_list));
+}
+
+// Sets |choice| on every path in |include_paths| that matches |url|. Returns
+// a set of paths that are updated.
+PathSet UpdateSavedChoice(const GURL& url,
+                          UrlHandlerSavedChoice choice,
+                          const base::Time& time,
+                          base::Value& include_paths) {
   // |include_paths| is a list of include path dicts. Eg:
   // [ {
   //    "choice": 0,
@@ -413,6 +464,7 @@
   //    "timestamp": "-9223372036854775808"
   // } ]
   auto include_paths_list = std::move(include_paths).TakeList();
+  std::vector<std::string> updated_include_paths;
   for (base::Value& include_path_dict : include_paths_list) {
     if (!include_path_dict.is_dict())
       continue;
@@ -425,9 +477,116 @@
     if (PathMatchesPathPattern(url.path(), *path)) {
       include_path_dict.SetIntKey(kChoice, static_cast<int>(choice));
       include_path_dict.SetKey(kTimestamp, util::TimeToValue(time));
+      updated_include_paths.push_back(*path);
     }
   }
   include_paths = base::Value(std::move(include_paths_list));
+  return std::move(updated_include_paths);
+}
+
+absl::optional<HandlerView> GetHandlerView(base::Value& handler) {
+  if (!handler.is_dict())
+    return absl::nullopt;
+
+  const std::string* const handler_app_id = handler.FindStringKey(kAppId);
+  absl::optional<base::FilePath> handler_profile_path =
+      util::ValueToFilePath(handler.FindKey(kProfilePath));
+  if (!handler_app_id || !handler_profile_path)
+    return absl::nullopt;
+
+  base::Value* const include_paths = handler.FindListKey(kIncludePaths);
+  if (!include_paths)
+    return absl::nullopt;
+
+  HandlerView handler_view = {
+      *handler_app_id,
+      handler_profile_path.value(),
+      *include_paths,
+  };
+
+  return handler_view;
+}
+
+// Update the save choice on every include path that matches the |url|.
+void SaveChoiceToAllMatchingIncludePaths(const GURL& url,
+                                         const UrlHandlerSavedChoice choice,
+                                         const base::Time& time,
+                                         base::Value::ListStorage& handlers) {
+  for (auto& handler : handlers) {
+    auto handler_view = GetHandlerView(handler);
+    if (!handler_view)
+      continue;
+
+    UpdateSavedChoice(url, choice, time, handler_view->include_paths);
+  }
+}
+
+bool AppIdAndProfileMatch(const AppId* app_id,
+                          const base::FilePath* profile_path,
+                          const std::string& handler_app_id,
+                          const base::FilePath& handler_profile_path) {
+  return (*app_id == handler_app_id) && (*profile_path == handler_profile_path);
+}
+
+// Update the matching include paths' saved choice where app id and profile
+// path match |app_id| and |profile_path|. Return which include paths are
+// updated.
+PathSet SaveInAppChoiceToSelectedApp(const AppId* app_id,
+                                     const base::FilePath* profile_path,
+                                     const GURL& url,
+                                     const base::Time& time,
+                                     base::Value::ListStorage& handlers) {
+  PathSet updated_include_paths;
+  for (auto& handler : handlers) {
+    auto handler_view = GetHandlerView(handler);
+    if (!handler_view ||
+        !AppIdAndProfileMatch(app_id, profile_path, handler_view->app_id,
+                              handler_view->profile_path)) {
+      continue;
+    }
+
+    PathSet updated_paths = UpdateSavedChoice(
+        url, UrlHandlerSavedChoice::kInApp, time, handler_view->include_paths);
+    updated_include_paths.insert(updated_paths.begin(), updated_paths.end());
+  }
+  return updated_include_paths;
+}
+
+// Find include paths in |updated_include_paths| from apps that don't match
+// |app_id| and |profile_path|. Reset the saved choice of these to kNone so
+// they don't conflict with the app choice that was just saved.
+void ResetSavedChoiceInOtherApps(const AppId* app_id,
+                                 const base::FilePath* profile_path,
+                                 const base::Time& time,
+                                 PathSet updated_include_paths,
+                                 base::Value::ListStorage& handlers) {
+  for (auto& handler : handlers) {
+    auto handler_view = GetHandlerView(handler);
+    if (!handler_view ||
+        AppIdAndProfileMatch(app_id, profile_path, handler_view->app_id,
+                             handler_view->profile_path)) {
+      continue;
+    }
+
+    UpdateSavedChoiceInIncludePaths(updated_include_paths,
+                                    UrlHandlerSavedChoice::kNone, time,
+                                    handler_view->include_paths);
+  }
+}
+
+void SaveAppChoice(const AppId* app_id,
+                   const base::FilePath* profile_path,
+                   const GURL& url,
+                   const base::Time& time,
+                   base::Value::ListStorage& handlers) {
+  PathSet updated_include_paths =
+      SaveInAppChoiceToSelectedApp(app_id, profile_path, url, time, handlers);
+
+  if (updated_include_paths.empty())
+    return;
+
+  ResetSavedChoiceInOtherApps(app_id, profile_path, time,
+                              std::move(updated_include_paths), handlers);
 }
 
 void SaveChoiceImpl(const AppId* app_id,
@@ -439,31 +598,19 @@
                     const std::string& origin_str,
                     const bool origin_trimmed) {
   base::Value* const handlers_mutable = pref_value.FindListKey(origin_str);
-  if (handlers_mutable) {
-    DCHECK(UrlMatchesOrigin(url, origin_str, origin_trimmed));
-    base::Value::ListStorage handlers = std::move(*handlers_mutable).TakeList();
-    for (auto& handler : handlers) {
-      if (!handler.is_dict())
-        continue;
-      const std::string* const handler_app_id = handler.FindStringKey(kAppId);
-      absl::optional<base::FilePath> handler_profile_path =
-          util::ValueToFilePath(handler.FindKey(kProfilePath));
-      if (!handler_app_id || !handler_profile_path)
-        continue;
+  if (!handlers_mutable)
+    return;
 
-      if (choice == UrlHandlerSavedChoice::kInApp) {
-        if (*handler_app_id != *app_id ||
-            *handler_profile_path != *profile_path) {
-          continue;
-        }
-      }
+  DCHECK(UrlMatchesOrigin(url, origin_str, origin_trimmed));
+  base::Value::ListStorage handlers = std::move(*handlers_mutable).TakeList();
 
-      base::Value* const include_paths = handler.FindListKey(kIncludePaths);
-      if (include_paths)
-        UpdateSavedChoice(*include_paths, url, choice, time);
-    }
-    *handlers_mutable = base::Value(std::move(handlers));
+  if (choice == UrlHandlerSavedChoice::kInApp) {
+    SaveAppChoice(app_id, profile_path, url, time, handlers);
+  } else {
+    SaveChoiceToAllMatchingIncludePaths(url, choice, time, handlers);
   }
+
+  *handlers_mutable = base::Value(std::move(handlers));
 }
 
 // Saves |choice| and |time| to all handler include_paths that match |app_id|,
diff --git a/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc b/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc
index 3051296..df31b17 100644
--- a/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc
+++ b/chrome/browser/web_applications/components/url_handler_prefs_unittest.cc
@@ -1019,6 +1019,71 @@
   }
 }
 
+TEST_F(UrlHandlerPrefsTest, SaveUserChoice_InBrowserThenInApp) {
+  const auto web_app_1 = WebAppWithUrlHandlers(
+      app_url_1_, {apps::UrlHandlerInfo(origin_1_, false, {"/*"}, {})});
+  url_handler_prefs::AddWebApp(LocalState(), web_app_1->app_id(), profile_1_,
+                               web_app_1->url_handlers(), time_1_);
+
+  url_handler_prefs::SaveOpenInBrowser(LocalState(), origin_url_1_, time_1_);
+  {
+    ExpectUrlHandlerPrefs(R"({
+      "https://origin-1.com": [ {
+        "app_id":"hfbpnmjjjooicehokhgjihcnkmbbpefl",
+        "exclude_paths": [  ],
+        "has_origin_wildcard": false,
+        "include_paths": [ {
+          "choice": 0,
+          "path": "/*",
+          "timestamp": "12591158400000000"
+        } ],
+        "profile_path": "/profile1"
+      } ]
+    })");
+  }
+
+  // Install a second app that also handles origin_1_/*.
+  const auto web_app_2 = WebAppWithUrlHandlers(
+      app_url_2_, {apps::UrlHandlerInfo(origin_1_, false, {"/*"}, {})});
+  url_handler_prefs::AddWebApp(LocalState(), web_app_2->app_id(), profile_1_,
+                               web_app_2->url_handlers(), time_2_);
+  // Now save to open origin_1_/* in web_app_2.
+  url_handler_prefs::SaveOpenInApp(LocalState(), web_app_2->app_id(),
+                                   profile_1_, origin_url_1_, time_2_);
+  {
+    // web_app_1 and web_app_2 both can handle origin_1_/*. Since we now saved
+    // web_app_2 as the default handler app, the "/*" path of web_app_2 is
+    // saved as kInApp, and "/*" of web_app_1 is reset to kNone. Timestamps
+    // are updated to time_2_.
+    ExpectUrlHandlerPrefs(R"({
+      "https://origin-1.com": [ {
+        "app_id":"hfbpnmjjjooicehokhgjihcnkmbbpefl",
+        "exclude_paths": [  ],
+        "has_origin_wildcard": false,
+        "include_paths": [ {
+          "choice": 1,
+          "path": "/*",
+          "timestamp": "12591244800000000"
+        } ],
+        "profile_path": "/profile1"
+      }, {
+        "app_id":"dioomdeompgjpnegoidgaopfdnbbljlb",
+        "exclude_paths": [  ],
+        "has_origin_wildcard": false,
+        "include_paths": [ {
+          "choice": 2,
+          "path": "/*",
+          "timestamp": "12591244800000000"
+        } ],
+        "profile_path": "/profile1"
+      } ]
+    })");
+    auto matches =
+        url_handler_prefs::FindMatchingUrlHandlers(LocalState(), origin_url_1_);
+    CheckMatches(matches, {web_app_2.get()}, {profile_1_});
+  }
+}
+
 // Updating an app with a new handler should preserve a previously added handler
 // and previously saved user choice.
 TEST_F(UrlHandlerPrefsTest, UpdateAppWithSavedChoice_AddHandler) {
diff --git a/chrome/browser/web_applications/components/web_app_chromeos_data.cc b/chrome/browser/web_applications/components/web_app_chromeos_data.cc
index b53bd630..88b313d 100644
--- a/chrome/browser/web_applications/components/web_app_chromeos_data.cc
+++ b/chrome/browser/web_applications/components/web_app_chromeos_data.cc
@@ -10,6 +10,16 @@
 
 namespace web_app {
 
+base::Value WebAppChromeOsData::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetBoolKey("show_in_launcher", show_in_launcher);
+  root.SetBoolKey("show_in_search", show_in_search);
+  root.SetBoolKey("show_in_management", show_in_management);
+  root.SetBoolKey("is_disabled", is_disabled);
+  root.SetBoolKey("oem_installed", oem_installed);
+  return root;
+}
+
 bool operator==(const WebAppChromeOsData& chromeos_data1,
                 const WebAppChromeOsData& chromeos_data2) {
   return std::tie(chromeos_data1.show_in_launcher,
@@ -22,16 +32,4 @@
                   chromeos_data2.oem_installed);
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const WebAppChromeOsData& chromeos_data) {
-  out << "show_in_launcher: " << chromeos_data.show_in_launcher << std::endl;
-  out << "show_in_search: " << chromeos_data.show_in_search << std::endl;
-  out << "show_in_management: " << chromeos_data.show_in_management
-      << std::endl;
-  out << "is_disabled: " << chromeos_data.is_disabled << std::endl;
-  out << "oem_installed: " << chromeos_data.oem_installed << std::endl;
-
-  return out;
-}
-
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_chromeos_data.h b/chrome/browser/web_applications/components/web_app_chromeos_data.h
index c47951723..f930057a 100644
--- a/chrome/browser/web_applications/components/web_app_chromeos_data.h
+++ b/chrome/browser/web_applications/components/web_app_chromeos_data.h
@@ -5,11 +5,13 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_CHROMEOS_DATA_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_CHROMEOS_DATA_H_
 
-#include <iosfwd>
+#include "base/values.h"
 
 namespace web_app {
 
 struct WebAppChromeOsData {
+  base::Value AsDebugValue() const;
+
   // By default an app is shown everywhere.
   bool show_in_launcher = true;
   bool show_in_search = true;
@@ -24,9 +26,6 @@
   bool oem_installed = false;
 };
 
-// For logging and debugging purposes.
-std::ostream& operator<<(std::ostream& out, const WebAppChromeOsData& data);
-
 bool operator==(const WebAppChromeOsData& chromeos_data1,
                 const WebAppChromeOsData& chromeos_data2);
 bool operator!=(const WebAppChromeOsData& chromeos_data1,
diff --git a/chrome/browser/web_applications/components/web_app_origin_association_manager_browsertest.cc b/chrome/browser/web_applications/components/web_app_origin_association_manager_browsertest.cc
index 9deccf11..04a6ae07 100644
--- a/chrome/browser/web_applications/components/web_app_origin_association_manager_browsertest.cc
+++ b/chrome/browser/web_applications/components/web_app_origin_association_manager_browsertest.cc
@@ -22,6 +22,7 @@
 const std::string& kValidAndInvalidAppsUrl = "https://c.com";
 const std::string& kMultipleValidAppsUrl = "https://d.com";
 const std::string& kValidAppWithTooManyPathsUrl = "https://e.com";
+const std::string& kValidAppWithDuplicatePathsUrl = "https://f.com";
 
 constexpr char kInvalidFileContent[] = "invalid";
 constexpr char kValidAppFileContent[] =
@@ -79,6 +80,17 @@
     "  }"
     "]}";
 
+constexpr char kValidAppWithDuplicatePathsFileContent[] =
+    "{\"web_apps\": ["
+    "  {"
+    "    \"manifest\": \"https://foo.com/manifest.json\","
+    "    \"details\": {"
+    "      \"paths\": [\"/1\", \"/1\", \"/1\"],"
+    "      \"exclude_paths\": [\"/2\", \"/2\", \"/2\"]"
+    "    }"
+    "  }"
+    "]}";
+
 }  // namespace
 
 namespace web_app {
@@ -104,6 +116,8 @@
         {url::Origin::Create(GURL(kValidAppUrl)), kValidAppFileContent},
         {url::Origin::Create(GURL(kValidAppWithTooManyPathsUrl)),
          kValidAppWithTooManyPathsFileContent},
+        {url::Origin::Create(GURL(kValidAppWithDuplicatePathsUrl)),
+         kValidAppWithDuplicatePathsFileContent},
         {url::Origin::Create(GURL(kValidAndInvalidAppsUrl)),
          kValidAndInvalidAppsFileContent},
         {url::Origin::Create(GURL(kMultipleValidAppsUrl)),
@@ -119,6 +133,8 @@
     valid_app_url_handler_.origin = url::Origin::Create(GURL(kValidAppUrl));
     valid_app_with_too_many_paths_url_handler_.origin =
         url::Origin::Create(GURL(kValidAppWithTooManyPathsUrl));
+    valid_app_with_duplicate_paths_url_handler_.origin =
+        url::Origin::Create(GURL(kValidAppWithDuplicatePathsUrl));
     valid_and_invalid_app_url_handler_.origin =
         url::Origin::Create(GURL(kValidAndInvalidAppsUrl));
     multiple_valid_apps_url_handler_.origin =
@@ -161,6 +177,7 @@
   apps::UrlHandlerInfo invalid_file_url_handler_;
   apps::UrlHandlerInfo valid_app_url_handler_;
   apps::UrlHandlerInfo valid_app_with_too_many_paths_url_handler_;
+  apps::UrlHandlerInfo valid_app_with_duplicate_paths_url_handler_;
   apps::UrlHandlerInfo valid_and_invalid_app_url_handler_;
   apps::UrlHandlerInfo multiple_valid_apps_url_handler_;
 };
@@ -227,10 +244,32 @@
             valid_app_with_too_many_paths_url_handler_.has_origin_wildcard);
 
         ASSERT_EQ(10u, url_handler.paths.size());
-        EXPECT_EQ(url_handler.paths[9], "/10");
-
         ASSERT_EQ(10u, url_handler.exclude_paths.size());
-        EXPECT_EQ(url_handler.exclude_paths[9], "/10");
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
+IN_PROC_BROWSER_TEST_F(WebAppOriginAssociationManagerTest,
+                       OneValidAppWithDuplicatePaths) {
+  base::RunLoop run_loop;
+  apps::UrlHandlers url_handlers{valid_app_with_duplicate_paths_url_handler_};
+  manager_->GetWebAppOriginAssociations(
+      GURL(kManifestUrl), std::move(url_handlers),
+      base::BindLambdaForTesting([&](apps::UrlHandlers result) {
+        ASSERT_TRUE(result.size() == 1);
+        auto url_handler = std::move(result[0]);
+        EXPECT_EQ(url_handler.origin,
+                  valid_app_with_duplicate_paths_url_handler_.origin);
+        EXPECT_EQ(
+            url_handler.has_origin_wildcard,
+            valid_app_with_duplicate_paths_url_handler_.has_origin_wildcard);
+
+        // Check that paths and exclude_paths have been deduplicated.
+        ASSERT_EQ(1u, url_handler.paths.size());
+        EXPECT_EQ(url_handler.paths[0], "/1");
+        ASSERT_EQ(1u, url_handler.exclude_paths.size());
+        EXPECT_EQ(url_handler.exclude_paths[0], "/2");
         run_loop.Quit();
       }));
   run_loop.Run();
diff --git a/chrome/browser/web_applications/components/web_app_origin_association_task.cc b/chrome/browser/web_applications/components/web_app_origin_association_task.cc
index 8b1db71..78d1ee8 100644
--- a/chrome/browser/web_applications/components/web_app_origin_association_task.cc
+++ b/chrome/browser/web_applications/components/web_app_origin_association_task.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/containers/flat_set.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
 #include "components/webapps/services/web_app_origin_association/public/mojom/web_app_origin_association_parser.mojom.h"
@@ -21,9 +22,10 @@
 constexpr size_t kMaxPathLength = 2000;
 
 // Number of paths cannot exceed |kMaxPathsSize|, and each path cannot contain
-// more than |kMaxPathLength| characters.
+// more than |kMaxPathLength| characters. Duplicate paths are ignored and do not
+// count towards kMaxPathsSize.
 std::vector<std::string> GetValidPaths(std::vector<std::string> paths) {
-  std::vector<std::string> result;
+  base::flat_set<std::string> result;
   for (const std::string& path : paths) {
     if (result.size() == kMaxPathsSize)
       break;
@@ -31,9 +33,9 @@
     if (path.length() > kMaxPathLength)
       continue;
 
-    result.push_back(std::move(path));
+    result.insert(std::move(path));
   }
-  return result;
+  return std::move(result).extract();
 }
 }  // namespace
 
diff --git a/chrome/browser/web_applications/components/web_app_prefs_utils.cc b/chrome/browser/web_applications/components/web_app_prefs_utils.cc
index d373fdc..d4dda8c 100644
--- a/chrome/browser/web_applications/components/web_app_prefs_utils.cc
+++ b/chrome/browser/web_applications/components/web_app_prefs_utils.cc
@@ -215,7 +215,7 @@
 
   std::unique_ptr<prefs::DictionaryValueUpdate> web_app_prefs =
       UpdateWebAppDictionary(update.Get(), app_id);
-  web_app_prefs->Remove(path, nullptr);
+  web_app_prefs->Remove(path);
 }
 
 void RecordInstallIphIgnored(PrefService* pref_service,
diff --git a/chrome/browser/web_applications/components/web_app_system_web_app_data.cc b/chrome/browser/web_applications/components/web_app_system_web_app_data.cc
index b608c63..43442f5 100644
--- a/chrome/browser/web_applications/components/web_app_system_web_app_data.cc
+++ b/chrome/browser/web_applications/components/web_app_system_web_app_data.cc
@@ -9,17 +9,15 @@
 
 namespace web_app {
 
+base::Value WebAppSystemWebAppData::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetIntKey("system_app_type", static_cast<int>(system_app_type));
+  return root;
+}
+
 bool operator==(const WebAppSystemWebAppData& chromeos_data1,
                 const WebAppSystemWebAppData& chromeos_data2) {
   return chromeos_data1.system_app_type == chromeos_data2.system_app_type;
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const WebAppSystemWebAppData& chromeos_data) {
-  out << "swa type: " << static_cast<int>(chromeos_data.system_app_type)
-      << std::endl;
-
-  return out;
-}
-
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_system_web_app_data.h b/chrome/browser/web_applications/components/web_app_system_web_app_data.h
index d152f69..2edf319 100644
--- a/chrome/browser/web_applications/components/web_app_system_web_app_data.h
+++ b/chrome/browser/web_applications/components/web_app_system_web_app_data.h
@@ -5,19 +5,17 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SYSTEM_WEB_APP_DATA_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SYSTEM_WEB_APP_DATA_H_
 
-#include <iosfwd>
+#include "base/values.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_app {
 
 struct WebAppSystemWebAppData {
+  base::Value AsDebugValue() const;
+
   SystemAppType system_app_type;
 };
 
-// For logging and debugging purposes.
-std::ostream& operator<<(std::ostream& out, const WebAppSystemWebAppData& data);
-
 bool operator==(const WebAppSystemWebAppData& data1,
                 const WebAppSystemWebAppData& data2);
 bool operator!=(const WebAppSystemWebAppData& data1,
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc b/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
deleted file mode 100644
index c2ce7ca..0000000
--- a/chrome/browser/web_applications/components/web_app_tab_helper_base.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
-
-namespace web_app {
-
-WEB_CONTENTS_USER_DATA_KEY_IMPL(WebAppTabHelperBase)
-
-}  // namespace web_app
diff --git a/chrome/browser/web_applications/components/web_app_tab_helper_base.h b/chrome/browser/web_applications/components/web_app_tab_helper_base.h
deleted file mode 100644
index 28aadeb..0000000
--- a/chrome/browser/web_applications/components/web_app_tab_helper_base.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_
-#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_
-
-#include "chrome/browser/web_applications/components/web_app_id.h"
-#include "content/public/browser/web_contents_user_data.h"
-
-namespace base {
-class UnguessableToken;
-}
-
-namespace web_app {
-
-// Public interface for WebAppTabHelper.
-class WebAppTabHelperBase
-    : public content::WebContentsUserData<WebAppTabHelperBase> {
- public:
-  using content::WebContentsUserData<WebAppTabHelperBase>::FromWebContents;
-
-  virtual const AppId& GetAppId() const = 0;
-  virtual void SetAppId(const AppId& app_id) = 0;
-  virtual bool HasLoadedNonAboutBlankPage() const = 0;
-
-  virtual const base::UnguessableToken& GetAudioFocusGroupIdForTesting()
-      const = 0;
-
-  WEB_CONTENTS_USER_DATA_KEY_DECL();
-};
-
-}  // namespace web_app
-
-#endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_TAB_HELPER_BASE_H_
diff --git a/chrome/browser/web_applications/components/web_application_info.cc b/chrome/browser/web_applications/components/web_application_info.cc
index d58c7a1..1390ef0 100644
--- a/chrome/browser/web_applications/components/web_application_info.cc
+++ b/chrome/browser/web_applications/components/web_application_info.cc
@@ -4,9 +4,22 @@
 
 #include "chrome/browser/web_applications/components/web_application_info.h"
 
+#include <sstream>
+
 #include "components/webapps/common/web_page_metadata.mojom.h"
 #include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
 
+namespace {
+
+template <typename T>
+std::string ConvertToString(const T& value) {
+  std::stringstream ss;
+  ss << value;
+  return ss.str();
+}
+
+}  // namespace
+
 // IconBitmaps
 IconBitmaps::IconBitmaps() = default;
 
@@ -116,6 +129,15 @@
 WebApplicationIconInfo& WebApplicationIconInfo::operator=(
     WebApplicationIconInfo&&) = default;
 
+base::Value WebApplicationIconInfo::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("url", url.spec());
+  root.SetKey("square_size_px",
+              square_size_px ? base::Value(*square_size_px) : base::Value());
+  root.SetStringKey("purpose", ConvertToString(purpose));
+  return root;
+}
+
 // WebApplicationShortcutsMenuItemInfo::Icon
 WebApplicationShortcutsMenuItemInfo::Icon::Icon() = default;
 
@@ -135,6 +157,13 @@
 WebApplicationShortcutsMenuItemInfo::Icon::operator=(
     WebApplicationShortcutsMenuItemInfo::Icon&&) = default;
 
+base::Value WebApplicationShortcutsMenuItemInfo::Icon::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("url", url.spec());
+  root.SetIntKey("square_size_px", square_size_px);
+  return root;
+}
+
 // WebApplicationShortcutsMenuItemInfo
 WebApplicationShortcutsMenuItemInfo::WebApplicationShortcutsMenuItemInfo() =
     default;
@@ -186,6 +215,27 @@
   }
 }
 
+base::Value WebApplicationShortcutsMenuItemInfo::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  root.SetStringKey("name", name);
+
+  root.SetStringKey("url", url.spec());
+
+  base::Value& icons =
+      *root.SetKey("icons", base::Value(base::Value::Type::DICTIONARY));
+  for (IconPurpose purpose : kIconPurposes) {
+    base::Value& purpose_list = *icons.SetKey(
+        ConvertToString(purpose), base::Value(base::Value::Type::LIST));
+    for (const WebApplicationShortcutsMenuItemInfo::Icon& icon :
+         GetShortcutIconInfosForPurpose(purpose)) {
+      purpose_list.Append(icon.AsDebugValue());
+    }
+  }
+
+  return root;
+}
+
 // WebApplicationInfo
 WebApplicationInfo::WebApplicationInfo() = default;
 
@@ -227,18 +277,6 @@
                                                   icon_info2.purpose);
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const WebApplicationIconInfo& icon_info) {
-  out << "url: " << icon_info.url << std::endl;
-  out << "  square_size_px: ";
-  if (icon_info.square_size_px)
-    out << *icon_info.square_size_px << std::endl;
-  else
-    out << "none" << std::endl;
-  out << "  purpose: " << icon_info.purpose << std::endl;
-  return out;
-}
-
 bool operator==(const IconSizes& icon_sizes1, const IconSizes& icon_sizes2) {
   return std::tie(icon_sizes1.any, icon_sizes1.maskable,
                   icon_sizes1.monochrome) == std::tie(icon_sizes2.any,
@@ -259,30 +297,3 @@
          std::tie(shortcut_info2.name, shortcut_info2.url, shortcut_info2.any,
                   shortcut_info2.maskable, shortcut_info2.monochrome);
 }
-
-std::ostream& operator<<(std::ostream& out,
-                         const WebApplicationShortcutsMenuItemInfo& info) {
-  out << "name: " << info.name << std::endl;
-  out << "  url: " << info.url << std::endl;
-  out << "  icons:" << std::endl;
-  out << "    any:" << std::endl;
-
-  for (WebApplicationShortcutsMenuItemInfo::Icon icon : info.any) {
-    out << "      url: " << icon.url << std::endl;
-    out << "      square_size_px: " << icon.square_size_px << std::endl;
-  }
-
-  out << "    maskable:" << std::endl;
-  for (WebApplicationShortcutsMenuItemInfo::Icon icon : info.maskable) {
-    out << "      url: " << icon.url << std::endl;
-    out << "      square_size_px: " << icon.square_size_px << std::endl;
-  }
-
-  out << "    monochrome:" << std::endl;
-  for (WebApplicationShortcutsMenuItemInfo::Icon icon : info.monochrome) {
-    out << "      url: " << icon.url << std::endl;
-    out << "      square_size_px: " << icon.square_size_px << std::endl;
-  }
-
-  return out;
-}
diff --git a/chrome/browser/web_applications/components/web_application_info.h b/chrome/browser/web_applications/components/web_application_info.h
index 8160ace..fe330439 100644
--- a/chrome/browser/web_applications/components/web_application_info.h
+++ b/chrome/browser/web_applications/components/web_application_info.h
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "base/containers/flat_set.h"
+#include "base/values.h"
 #include "components/services/app_service/public/cpp/share_target.h"
 #include "components/services/app_service/public/cpp/url_handler_info.h"
 #include "components/webapps/common/web_page_metadata.mojom-forward.h"
@@ -106,6 +107,7 @@
   ~WebApplicationIconInfo();
   WebApplicationIconInfo& operator=(const WebApplicationIconInfo&);
   WebApplicationIconInfo& operator=(WebApplicationIconInfo&&) noexcept;
+  base::Value AsDebugValue() const;
 
   GURL url;
   absl::optional<SquareSizePx> square_size_px;
@@ -122,6 +124,7 @@
     ~Icon();
     Icon& operator=(const Icon&);
     Icon& operator=(Icon&&);
+    base::Value AsDebugValue() const;
 
     GURL url;
     SquareSizePx square_size_px = 0;
@@ -143,6 +146,8 @@
   void SetShortcutIconInfosForPurpose(IconPurpose purpose,
                                       std::vector<Icon> shortcut_icon_infos);
 
+  base::Value AsDebugValue() const;
+
   // Title of shortcut item in App Icon Shortcut Menu.
   std::u16string name;
 
@@ -287,9 +292,6 @@
   bool is_storage_isolated = false;
 };
 
-std::ostream& operator<<(std::ostream& out,
-                         const WebApplicationIconInfo& icon_info);
-
 bool operator==(const IconSizes& icon_sizes1, const IconSizes& icon_sizes2);
 
 bool operator==(const WebApplicationIconInfo& icon_info1,
@@ -301,7 +303,4 @@
 bool operator==(const WebApplicationShortcutsMenuItemInfo& shortcut_info1,
                 const WebApplicationShortcutsMenuItemInfo& shortcut_info2);
 
-std::ostream& operator<<(std::ostream& out,
-                         const WebApplicationShortcutsMenuItemInfo& info);
-
 #endif  // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APPLICATION_INFO_H_
diff --git a/chrome/browser/web_applications/manifest_update_manager.cc b/chrome/browser/web_applications/manifest_update_manager.cc
index 5c277f5..17f61e3 100644
--- a/chrome/browser/web_applications/manifest_update_manager.cc
+++ b/chrome/browser/web_applications/manifest_update_manager.cc
@@ -115,7 +115,7 @@
   auto it = tasks_.find(app_id);
   if (it != tasks_.end()) {
     NotifyResult(it->second->url(), app_id,
-                 ManifestUpdateResult::kAppUninstalled);
+                 ManifestUpdateResult::kAppUninstalling);
     tasks_.erase(it);
   }
   DCHECK(!tasks_.contains(app_id));
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index a2d63b80..00b95cc 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -433,14 +433,23 @@
   GetManifestUpdateManager(browser()).hang_update_checks_for_testing();
 
   GURL url = GetAppURL();
-  UpdateCheckResultAwaiter awaiter(browser(), url);
   ui_test_utils::NavigateToURL(browser(), url);
+
+  base::RunLoop run_loop;
+  UpdateCheckResultAwaiter awaiter(browser(), url);
   GetProvider().install_finalizer().UninstallWebApp(
-      app_id, webapps::WebappUninstallSource::kAppMenu, base::DoNothing());
+      app_id, webapps::WebappUninstallSource::kAppMenu,
+      base::BindLambdaForTesting([&](bool uninstalled) {
+        EXPECT_TRUE(uninstalled);
+        run_loop.Quit();
+      }));
+
   EXPECT_EQ(std::move(awaiter).AwaitNextResult(),
-            ManifestUpdateResult::kAppUninstalled);
-  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
-                                      ManifestUpdateResult::kAppUninstalled, 1);
+            ManifestUpdateResult::kAppUninstalling);
+
+  run_loop.Run();
+  histogram_tester_.ExpectBucketCount(
+      kUpdateHistogramName, ManifestUpdateResult::kAppUninstalling, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest,
diff --git a/chrome/browser/web_applications/manifest_update_task.h b/chrome/browser/web_applications/manifest_update_task.h
index 527deeb..bf1f07541 100644
--- a/chrome/browser/web_applications/manifest_update_task.h
+++ b/chrome/browser/web_applications/manifest_update_task.h
@@ -53,7 +53,7 @@
   kNoAppInScope = 0,
   kThrottled = 1,
   kWebContentsDestroyed = 2,
-  kAppUninstalled = 3,
+  kAppUninstalling = 3,
   kAppIsPlaceholder = 4,
   kAppUpToDate = 5,
   kAppNotEligible = 6,
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager.h b/chrome/browser/web_applications/preinstalled_web_app_manager.h
index 86d8c19..05087942 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager.h
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager.h
@@ -81,7 +81,7 @@
 
   void LoadForTesting(ConsumeInstallOptions callback);
 
-  // Debugging info used by: chrome://internals/web-app
+  // Debugging info used by: chrome://web-app-internals
   struct DebugInfo {
     DebugInfo();
     ~DebugInfo();
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.cc b/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.cc
index 0c7df0b..ae434c2 100644
--- a/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.cc
+++ b/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.cc
@@ -6,6 +6,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "chrome/browser/profiles/profile.h"
@@ -27,6 +28,9 @@
     bool open_immediately)
     : period(period), url(url), open_immediately(open_immediately) {}
 
+// static
+const char SystemAppBackgroundTask::kBackgroundStartDelayHistogramName[];
+
 SystemAppBackgroundTask::SystemAppBackgroundTask(
     Profile* profile,
     const SystemAppBackgroundTaskInfo& info)
@@ -104,6 +108,10 @@
                   base::BindOnce(&SystemAppBackgroundTask::MaybeOpenPage,
                                  weak_ptr_factory_.GetWeakPtr()));
   }
+
+  base::UmaHistogramLongTimes(kBackgroundStartDelayHistogramName,
+                              polling_duration);
+
   polling_since_time_ = base::Time();
   state_ = WAIT_PERIOD;
   NavigateBackgroundPage();
diff --git a/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.h b/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.h
index 18a7332..6f67b66 100644
--- a/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.h
+++ b/chrome/browser/web_applications/system_web_apps/system_web_app_background_task.h
@@ -77,6 +77,11 @@
   // For up to an hour.
   static const int kIdlePollMaxTimeToWaitSeconds = 3600;
 
+  // The duration we polled for before becoming idle and starting the background
+  // task.
+  static constexpr char kBackgroundStartDelayHistogramName[] =
+      "Webapp.SystemApps.BackgroundTaskStartDelay";
+
   SystemAppBackgroundTask(Profile* profile,
                           const SystemAppBackgroundTaskInfo& info);
   ~SystemAppBackgroundTask();
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
index f44b7805..3aae8d1 100644
--- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -1471,6 +1471,7 @@
   // a hook in the background pages to detect the navigation as an event. That's
   // a little too much work for one test though, and since this is mostly tested
   // in unittests, this is probably enough.
+  base::HistogramTester histograms;
   content::TestNavigationObserver navigation_observer(
       GURL("chrome://test-system-app/page2.html"));
   navigation_observer.StartWatchingNewWebContents();
@@ -1497,6 +1498,10 @@
   EXPECT_EQ(SystemAppBackgroundTask::WAIT_PERIOD,
             tasks[0]->get_state_for_testing());
   EXPECT_EQ(base::TimeDelta::FromDays(1), timer->GetCurrentDelay());
+
+  histograms.ExpectTotalCount("Webapp.SystemApps.BackgroundTaskStartDelay", 1);
+  histograms.ExpectUniqueSample("Webapp.SystemApps.BackgroundTaskStartDelay", 0,
+                                1);
 }
 
 INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_REGULAR_PROFILE_P(
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index c2d65b7a..32cc040 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -10,6 +10,7 @@
 
 #include "base/check_op.h"
 #include "base/notreached.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/web_applications/components/web_app_chromeos_data.h"
@@ -322,6 +323,14 @@
 
 WebApp::ClientData::ClientData(const ClientData& client_data) = default;
 
+base::Value WebApp::ClientData::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetKey("system_web_app_data", system_web_app_data
+                                         ? system_web_app_data->AsDebugValue()
+                                         : base::Value());
+  return root;
+}
+
 WebApp::SyncFallbackData::SyncFallbackData() = default;
 
 WebApp::SyncFallbackData::~SyncFallbackData() = default;
@@ -332,208 +341,16 @@
 WebApp::SyncFallbackData& WebApp::SyncFallbackData::operator=(
     SyncFallbackData&& sync_fallback_data) = default;
 
-template <typename T>
-std::ostream& operator<<(std::ostream& out, const absl::optional<T>& optional) {
-  if (optional.has_value())
-    return out << optional.value();
-  return out << "nullopt";
-}
-
-template <typename T>
-std::string Indent(const T& value) {
-  std::stringstream ss;
-  ss << value;
-  std::vector<std::string> lines = base::SplitString(
-      ss.str(), "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-  for (std::string& line : lines)
-    line = "  " + line;
-  return base::JoinString(lines, "\n");
-}
-
-std::ostream& operator<<(std::ostream& out,
-                         const WebApp::SyncFallbackData& sync_fallback_data) {
-  out << "name: " << sync_fallback_data.name << std::endl;
-
-  out << "theme_color: " << ColorToString(sync_fallback_data.theme_color)
-      << std::endl;
-
-  out << "scope: " << sync_fallback_data.scope << std::endl;
-
-  out << "icon_infos:" << std::endl;
-  for (const WebApplicationIconInfo& icon : sync_fallback_data.icon_infos)
-    out << Indent(icon) << std::endl;
-
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const WebApp& app) {
-  out << "app_id: " << app.app_id_ << std::endl;
-
-  out << "unhashed app_id: "
-      << GenerateAppIdUnhashed(app.manifest_id_, app.start_url_) << std::endl;
-
-  out << "manifest_url: " << app.manifest_url_ << std::endl;
-
-  out << "manifest_id: " << app.manifest_id_ << std::endl;
-
-  out << "name: " << app.name_ << std::endl;
-
-  out << "start_url: " << app.start_url_ << std::endl;
-
-  out << "launch_query_params: " << app.launch_query_params_ << std::endl;
-
-  out << "scope: " << app.scope_ << std::endl;
-
-  out << "theme_color: " << ColorToString(app.theme_color_) << std::endl;
-
-  out << "background_color: " << ColorToString(app.background_color_)
-      << std::endl;
-
-  out << "display_mode: " << blink::DisplayModeToString(app.display_mode_)
-      << std::endl;
-
-  out << "display_override:";
-  for (const DisplayMode& mode : app.display_mode_override_)
-    out << " " << blink::DisplayModeToString(mode);
-  out << std::endl;
-
-  out << "user_display_mode: "
-      << blink::DisplayModeToString(app.user_display_mode_) << std::endl;
-
-  out << "user_page_ordinal: " << app.user_page_ordinal_.ToDebugString()
-      << std::endl;
-
-  out << "user_launch_ordinal: " << app.user_launch_ordinal_.ToDebugString()
-      << std::endl;
-
-  out << "sources:";
-  for (int i = Source::Type::kMinValue; i <= Source::Type::kMaxValue; ++i) {
-    if (app.sources_[i])
-      out << " " << static_cast<Source::Type>(i);
-  }
-  out << std::endl;
-
-  out << "is_locally_installed: " << app.is_locally_installed_ << std::endl;
-
-  out << "is_in_sync_install: " << app.is_in_sync_install_ << std::endl;
-
-  out << "is_uninstalling: " << app.is_uninstalling_ << std::endl;
-
-  out << "sync_fallback_data:" << std::endl
-      << Indent(app.sync_fallback_data_) << std::endl;
-
-  out << "description: " << app.description_ << std::endl;
-
-  out << "last_badging_time: " << app.last_badging_time_ << std::endl;
-
-  out << "last_launch_time: " << app.last_launch_time_ << std::endl;
-
-  out << "install_time: " << app.install_time_ << std::endl;
-
-  out << "is_generated_icon: " << app.is_generated_icon_ << std::endl;
-
-  out << "run_on_os_login_mode: "
-      << RunOnOsLoginModeToString(app.run_on_os_login_mode_) << std::endl;
-
-  out << "icon_infos:" << std::endl;
-  for (const WebApplicationIconInfo& icon : app.icon_infos_)
-    out << Indent(icon) << std::endl;
-
-  out << "downloaded_icon_sizes_any:";
-  for (SquareSizePx size : app.downloaded_icon_sizes_any_)
-    out << " " << size;
-  out << std::endl;
-
-  out << "downloaded_icon_sizes_monochrome:";
-  for (SquareSizePx size : app.downloaded_icon_sizes_monochrome_)
-    out << " " << size;
-  out << std::endl;
-
-  out << "downloaded_icon_sizes_maskable:";
-  for (SquareSizePx size : app.downloaded_icon_sizes_maskable_)
-    out << " " << size;
-  out << std::endl;
-
-  out << "shortcuts_menu_item_infos:" << std::endl;
-  for (const WebApplicationShortcutsMenuItemInfo& info :
-       app.shortcuts_menu_item_infos_) {
-    out << Indent(info) << std::endl;
-  }
-
-  out << "downloaded_shortcuts_menu_icons_sizes:" << std::endl;
-  for (size_t i = 0; i < app.downloaded_shortcuts_menu_icons_sizes_.size();
-       ++i) {
-    out << "  index: " << i << ":" << std::endl;
-    const IconSizes& icon_sizes = app.downloaded_shortcuts_menu_icons_sizes_[i];
-    out << "    any:";
-    for (SquareSizePx size : icon_sizes.any)
-      out << " " << size;
-    out << std::endl;
-
-    out << "    maskable:";
-    for (SquareSizePx size : icon_sizes.maskable)
-      out << " " << size;
-    out << std::endl;
-  }
-
-  out << "file_handlers:" << std::endl;
-  for (const apps::FileHandler& file_handler : app.file_handlers_)
-    out << Indent(file_handler) << std::endl;
-
-  out << "file_handler_permission_blocked:"
-      << app.file_handler_permission_blocked_ << std::endl;
-
-  out << "share_target:" << std::endl << Indent(app.share_target_) << std::endl;
-
-  out << "additional_search_terms:" << std::endl;
-  for (const std::string& additional_search_term : app.additional_search_terms_)
-    out << "  " << additional_search_term << std::endl;
-
-  out << "protocol_handlers:" << std::endl;
-  for (const apps::ProtocolHandlerInfo& protocol_handler :
-       app.protocol_handlers_) {
-    out << "  " << protocol_handler << std::endl;
-  }
-
-  out << "approved_launch_protocols:" << std::endl;
-  for (const std::string& approved_launch_protocols :
-       app.approved_launch_protocols_)
-    out << "  " << approved_launch_protocols << std::endl;
-
-  out << "url_handlers:" << std::endl;
-  for (const apps::UrlHandlerInfo& url_handler : app.url_handlers_)
-    out << Indent(url_handler) << std::endl;
-
-  out << "note_taking_new_note_url: " << app.note_taking_new_note_url_
-      << std::endl;
-
-  out << "capture_links: " << app.capture_links_ << std::endl;
-
-  out << "chromeos_data:" << std::endl
-      << Indent(app.chromeos_data_) << std::endl;
-
-  out << "system_web_app:" << std::endl
-      << Indent(app.client_data_.system_web_app_data) << std::endl;
-
-  out << "window_controls_overlay_enabled:" << std::endl
-      << Indent(app.window_controls_overlay_enabled_) << std::endl;
-
-  out << "is_storage_isolated: " << app.is_storage_isolated_ << std::endl;
-
-  return out;
-}
-
-bool operator==(const WebApp::SyncFallbackData& sync_fallback_data1,
-                const WebApp::SyncFallbackData& sync_fallback_data2) {
-  return std::tie(sync_fallback_data1.name, sync_fallback_data1.theme_color,
-                  sync_fallback_data1.scope, sync_fallback_data1.icon_infos) ==
-         std::tie(sync_fallback_data2.name, sync_fallback_data2.theme_color,
-                  sync_fallback_data2.scope, sync_fallback_data2.icon_infos);
-}
-
-bool operator!=(const WebApp::SyncFallbackData& sync_fallback_data1,
-                const WebApp::SyncFallbackData& sync_fallback_data2) {
-  return !(sync_fallback_data1 == sync_fallback_data2);
+base::Value WebApp::SyncFallbackData::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("name", name);
+  root.SetStringKey("theme_color", ColorToString(theme_color));
+  root.SetStringKey("scope", scope.spec());
+  base::Value& icon_infos_json =
+      *root.SetKey("icon_infos", base::Value(base::Value::Type::LIST));
+  for (const WebApplicationIconInfo& icon_info : icon_infos)
+    icon_infos_json.Append(icon_info.AsDebugValue());
+  return root;
 }
 
 bool WebApp::operator==(const WebApp& other) const {
@@ -596,4 +413,178 @@
   return !(*this == other);
 }
 
+base::Value WebApp::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  auto ConvertToString = [](const auto& value) {
+    std::stringstream ss;
+    ss << value;
+    return ss.str();
+  };
+
+  auto ConvertList = [](const auto& list) {
+    base::Value list_json(base::Value::Type::LIST);
+    for (const auto& item : list)
+      list_json.Append(item);
+    return list_json;
+  };
+
+  auto ConvertDebugValueList = [](const auto& list) {
+    base::Value list_json(base::Value::Type::LIST);
+    for (const auto& item : list)
+      list_json.Append(item.AsDebugValue());
+    return list_json;
+  };
+
+  auto ConvertOptional = [](const auto& value) {
+    return value ? base::Value(*value) : base::Value();
+  };
+
+  // Prefix with a ! so these fields appear at the top when serialized.
+  root.SetStringKey("!app_id", app_id_);
+
+  root.SetStringKey("!name", name_);
+
+  root.SetKey("additional_search_terms", ConvertList(additional_search_terms_));
+
+  root.SetStringKey("app_service_icon_url",
+                    base::StrCat({"chrome://app-icon/", app_id_, "/32"}));
+
+  root.SetKey("approved_launch_protocols",
+              ConvertList(approved_launch_protocols_));
+
+  root.SetStringKey("background_color", ColorToString(background_color_));
+
+  root.SetStringKey("capture_links", ConvertToString(capture_links_));
+
+  root.SetKey("chromeos_data",
+              chromeos_data_ ? chromeos_data_->AsDebugValue() : base::Value());
+
+  root.SetKey("client_data", client_data_.AsDebugValue());
+
+  root.SetStringKey("description", description_);
+
+  root.SetStringKey("display_mode", blink::DisplayModeToString(display_mode_));
+
+  base::Value& display_override =
+      *root.SetKey("display_override", base::Value(base::Value::Type::LIST));
+  for (const DisplayMode& mode : display_mode_override_)
+    display_override.Append(blink::DisplayModeToString(mode));
+
+  base::Value& downloaded_icon_sizes_json = *root.SetKey(
+      "downloaded_icon_sizes", base::Value(base::Value::Type::DICTIONARY));
+  for (IconPurpose purpose : kIconPurposes) {
+    downloaded_icon_sizes_json.SetKey(
+        ConvertToString(purpose), ConvertList(downloaded_icon_sizes(purpose)));
+  }
+
+  base::Value& downloaded_shortcuts_menu_icons_sizes =
+      *root.SetKey("downloaded_shortcuts_menu_icons_sizes",
+                   base::Value(base::Value::Type::LIST));
+  for (size_t i = 0; i < downloaded_shortcuts_menu_icons_sizes_.size(); ++i) {
+    const IconSizes& icon_sizes = downloaded_shortcuts_menu_icons_sizes_[i];
+    base::Value entry(base::Value::Type::DICTIONARY);
+    entry.SetIntKey("index", i);
+    for (IconPurpose purpose : kIconPurposes) {
+      entry.SetKey(ConvertToString(purpose),
+                   ConvertList(icon_sizes.GetSizesForPurpose(purpose)));
+    }
+    downloaded_shortcuts_menu_icons_sizes.Append(std::move(entry));
+  }
+
+  root.SetBoolKey("file_handler_permission_blocked",
+                  file_handler_permission_blocked_);
+
+  root.SetKey("file_handlers", ConvertDebugValueList(file_handlers_));
+
+  root.SetKey("icon_infos", ConvertDebugValueList(icon_infos_));
+
+  root.SetStringKey("install_time", ConvertToString(install_time_));
+
+  root.SetBoolKey("is_generated_icon", is_generated_icon_);
+
+  root.SetBoolKey("is_in_sync_install", is_in_sync_install_);
+
+  root.SetBoolKey("is_locally_installed", is_locally_installed_);
+
+  root.SetBoolKey("is_storage_isolated", is_storage_isolated_);
+
+  root.SetBoolKey("is_uninstalling", is_uninstalling_);
+
+  root.SetStringKey("last_badging_time", ConvertToString(last_badging_time_));
+
+  root.SetStringKey("last_launch_time", ConvertToString(last_launch_time_));
+
+  root.SetKey("launch_query_params", ConvertOptional(launch_query_params_));
+
+  root.SetKey("manifest_id", ConvertOptional(manifest_id_));
+
+  root.SetStringKey("manifest_url", ConvertToString(manifest_url_));
+
+  root.SetStringKey("note_taking_new_note_url",
+                    ConvertToString(note_taking_new_note_url_));
+
+  root.SetKey("protocol_handlers", ConvertDebugValueList(protocol_handlers_));
+
+  root.SetStringKey("run_on_os_login_mode",
+                    RunOnOsLoginModeToString(run_on_os_login_mode_));
+
+  root.SetStringKey("scope", ConvertToString(scope_));
+
+  root.SetKey("share_target",
+              share_target_ ? share_target_->AsDebugValue() : base::Value());
+
+  root.SetKey("shortcuts_menu_item_infos",
+              ConvertDebugValueList(shortcuts_menu_item_infos_));
+
+  base::Value& sources =
+      *root.SetKey("sources", base::Value(base::Value::Type::LIST));
+  for (int i = Source::Type::kMinValue; i <= Source::Type::kMaxValue; ++i) {
+    if (sources_[i])
+      sources.Append(ConvertToString(static_cast<Source::Type>(i)));
+  }
+
+  root.SetStringKey("start_url", ConvertToString(start_url_));
+
+  root.SetKey("sync_fallback_data",
+              base::Value(sync_fallback_data_.AsDebugValue()));
+
+  root.SetStringKey("theme_color", ColorToString(theme_color_));
+
+  root.SetStringKey("unhashed_app_id",
+                    GenerateAppIdUnhashed(manifest_id_, start_url_));
+
+  root.SetKey("url_handlers", ConvertDebugValueList(url_handlers_));
+
+  root.SetStringKey("user_display_mode",
+                    blink::DisplayModeToString(user_display_mode_));
+
+  root.SetStringKey("user_launch_ordinal",
+                    user_launch_ordinal_.ToDebugString());
+
+  root.SetStringKey("user_page_ordinal", user_page_ordinal_.ToDebugString());
+
+  root.SetBoolKey("window_controls_overlay_enabled",
+                  window_controls_overlay_enabled_);
+
+  return root;
+}
+
+std::ostream& operator<<(std::ostream& out, const WebApp& app) {
+  return out << app.AsDebugValue();
+}
+
+bool operator==(const WebApp::SyncFallbackData& sync_fallback_data1,
+                const WebApp::SyncFallbackData& sync_fallback_data2) {
+  return std::tie(sync_fallback_data1.name, sync_fallback_data1.theme_color,
+                  sync_fallback_data1.scope, sync_fallback_data1.icon_infos) ==
+         std::tie(sync_fallback_data2.name, sync_fallback_data2.theme_color,
+                  sync_fallback_data2.scope, sync_fallback_data2.icon_infos);
+}
+
+bool operator!=(const WebApp::SyncFallbackData& sync_fallback_data1,
+                const WebApp::SyncFallbackData& sync_fallback_data2) {
+  return !(sync_fallback_data1 == sync_fallback_data2);
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index 9d8e66e..4acbe3c 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "base/values.h"
 #include "chrome/browser/web_applications/components/web_app_chromeos_data.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
@@ -80,6 +81,8 @@
     ClientData();
     ~ClientData();
     ClientData(const ClientData& client_data);
+    base::Value AsDebugValue() const;
+
     absl::optional<WebAppSystemWebAppData> system_web_app_data;
   };
 
@@ -173,6 +176,8 @@
     SyncFallbackData(const SyncFallbackData& sync_fallback_data);
     SyncFallbackData& operator=(SyncFallbackData&& sync_fallback_data);
 
+    base::Value AsDebugValue() const;
+
     std::string name;
     absl::optional<SkColor> theme_color;
     GURL scope;
@@ -270,6 +275,7 @@
   // For logging and debug purposes.
   bool operator==(const WebApp&) const;
   bool operator!=(const WebApp&) const;
+  base::Value AsDebugValue() const;
 
  private:
   using Sources = std::bitset<Source::kMaxValue + 1>;
@@ -332,7 +338,7 @@
   bool is_storage_isolated_ = false;
   // New fields must be added to:
   //  - |operator==|
-  //  - |operator<<|
+  //  - AsDebugValue()
   //  - WebAppDatabase::CreateWebApp()
   //  - WebAppDatabase::CreateWebAppProto()
   //  - CreateRandomWebApp()
@@ -340,8 +346,6 @@
 };
 
 // For logging and debug purposes.
-std::ostream& operator<<(std::ostream& out,
-                         const WebApp::SyncFallbackData& sync_fallback_data);
 std::ostream& operator<<(std::ostream& out, const WebApp& app);
 
 bool operator==(const WebApp::SyncFallbackData& sync_fallback_data1,
diff --git a/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc b/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc
index 4fd01437..10bd4a7 100644
--- a/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
+#include "chrome/browser/web_applications/web_app_tab_helper.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
@@ -78,8 +78,7 @@
 
   const base::UnguessableToken& GetAudioFocusGroupId(
       content::WebContents* web_contents) {
-    WebAppTabHelperBase* helper =
-        WebAppTabHelperBase::FromWebContents(web_contents);
+    WebAppTabHelper* helper = WebAppTabHelper::FromWebContents(web_contents);
     return helper->GetAudioFocusGroupIdForTesting();
   }
 
diff --git a/chrome/browser/web_applications/web_app_icon_manager.h b/chrome/browser/web_applications/web_app_icon_manager.h
index 89c7a46f..d7cdf17 100644
--- a/chrome/browser/web_applications/web_app_icon_manager.h
+++ b/chrome/browser/web_applications/web_app_icon_manager.h
@@ -120,7 +120,7 @@
   void SetFaviconMonochromeReadCallbackForTesting(FaviconReadCallback callback);
 
   // Collects icon read/write errors (unbounded) if the |kRecordWebAppDebugInfo|
-  // flag is enabled to be used by: chrome://internals/web-app
+  // flag is enabled to be used by: chrome://web-app-internals
   const std::vector<std::string>* error_log() const { return error_log_.get(); }
   std::vector<std::string>* error_log() { return error_log_.get(); }
 
diff --git a/chrome/browser/web_applications/web_app_tab_helper.cc b/chrome/browser/web_applications/web_app_tab_helper.cc
index 2cbf5c11..46bf977 100644
--- a/chrome/browser/web_applications/web_app_tab_helper.cc
+++ b/chrome/browser/web_applications/web_app_tab_helper.cc
@@ -206,4 +206,6 @@
   return provider_->registrar().FindAppWithUrlInScope(url).value_or(AppId());
 }
 
+WEB_CONTENTS_USER_DATA_KEY_IMPL(WebAppTabHelper)
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_tab_helper.h b/chrome/browser/web_applications/web_app_tab_helper.h
index a64dd7d6..1a8879d 100644
--- a/chrome/browser/web_applications/web_app_tab_helper.h
+++ b/chrome/browser/web_applications/web_app_tab_helper.h
@@ -10,8 +10,8 @@
 #include "chrome/browser/web_applications/components/app_registrar.h"
 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
 #include "chrome/browser/web_applications/components/web_app_id.h"
-#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
 #include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
 
 namespace content {
 class WebContents;
@@ -23,7 +23,7 @@
 
 // Per-tab web app helper. Allows to associate a tab (web page) with a web app
 // (or legacy bookmark app).
-class WebAppTabHelper : public WebAppTabHelperBase,
+class WebAppTabHelper : public content::WebContentsUserData<WebAppTabHelper>,
                         public content::WebContentsObserver,
                         public AppRegistrarObserver {
  public:
@@ -34,11 +34,10 @@
   WebAppTabHelper& operator=(const WebAppTabHelper&) = delete;
   ~WebAppTabHelper() override;
 
-  // WebAppTabHelperBase:
-  const AppId& GetAppId() const override;
-  void SetAppId(const AppId& app_id) override;
-  const base::UnguessableToken& GetAudioFocusGroupIdForTesting() const override;
-  bool HasLoadedNonAboutBlankPage() const override;
+  const AppId& GetAppId() const;
+  void SetAppId(const AppId& app_id);
+  const base::UnguessableToken& GetAudioFocusGroupIdForTesting() const;
+  bool HasLoadedNonAboutBlankPage() const;
 
   // content::WebContentsObserver:
   void ReadyToCommitNavigation(
@@ -95,6 +94,7 @@
       this};
   WebAppProviderBase* provider_ = nullptr;
 
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index 2778042..6013df65e 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -6,29 +6,21 @@
 
 #include <string>
 
+#include "base/json/json_reader.h"
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/re2/src/re2/re2.h"
 #include "url/gurl.h"
 
 namespace web_app {
 
 namespace {
 
-// Presubmits and IDEs don't like whitespace at the end of lines.
-std::string RemoveTrailingWhitespace(std::string str) {
-  RE2::GlobalReplace(&str, "\\s+\\n", "\n");
-  return str;
-}
-
-std::string WebAppToPlatformAgnosticString(std::unique_ptr<WebApp> web_app) {
+base::Value WebAppToPlatformAgnosticJson(std::unique_ptr<WebApp> web_app) {
   // Force this to be nullopt to avoid platform specific differences.
   web_app->SetWebAppChromeOsData(absl::nullopt);
-  std::stringstream ss;
-  ss << *web_app;
-  return RemoveTrailingWhitespace(ss.str());
+  return web_app->AsDebugValue();
 }
 
 }  // namespace
@@ -152,240 +144,290 @@
   EXPECT_FALSE(app.IsPreinstalledApp());
 }
 
-TEST(WebAppTest, EmptyAppToDebugString) {
-  std::string debug_string =
-      WebAppToPlatformAgnosticString(std::make_unique<WebApp>("empty_app"));
-  EXPECT_EQ(debug_string,
-            R"(app_id: empty_app
-unhashed app_id:
-manifest_url:
-manifest_id: nullopt
-name:
-start_url:
-launch_query_params: nullopt
-scope:
-theme_color: none
-background_color: none
-display_mode:
-display_override:
-user_display_mode:
-user_page_ordinal: INVALID[]
-user_launch_ordinal: INVALID[]
-sources:
-is_locally_installed: 1
-is_in_sync_install: 0
-is_uninstalling: 0
-sync_fallback_data:
-  name:
-  theme_color: none
-  scope:
-  icon_infos:
-description:
-last_badging_time: 1601-01-01 00:00:00.000 UTC
-last_launch_time: 1601-01-01 00:00:00.000 UTC
-install_time: 1601-01-01 00:00:00.000 UTC
-is_generated_icon: 0
-run_on_os_login_mode: not run
-icon_infos:
-downloaded_icon_sizes_any:
-downloaded_icon_sizes_monochrome:
-downloaded_icon_sizes_maskable:
-shortcuts_menu_item_infos:
-downloaded_shortcuts_menu_icons_sizes:
-file_handlers:
-file_handler_permission_blocked:0
-share_target:
-  nullopt
-additional_search_terms:
-protocol_handlers:
-approved_launch_protocols:
-url_handlers:
-note_taking_new_note_url:
-capture_links: kUndefined
-chromeos_data:
-  nullopt
-system_web_app:
-  nullopt
-window_controls_overlay_enabled:
-  0
-is_storage_isolated: 0
-)") << "Copypastable expectation: \n"
-    << debug_string;
+TEST(WebAppTest, EmptyAppAsDebugValue) {
+  EXPECT_EQ(
+      base::JSONReader::Read(R"({
+   "!app_id": "empty_app",
+   "!name": "",
+   "additional_search_terms": [  ],
+   "app_service_icon_url": "chrome://app-icon/empty_app/32",
+   "approved_launch_protocols": [  ],
+   "background_color": "none",
+   "capture_links": "kUndefined",
+   "chromeos_data": null,
+   "client_data": {
+      "system_web_app_data": null
+   },
+   "description": "",
+   "display_mode": "",
+   "display_override": [  ],
+   "downloaded_icon_sizes": {
+      "ANY": [  ],
+      "MASKABLE": [  ],
+      "MONOCHROME": [  ]
+   },
+   "downloaded_shortcuts_menu_icons_sizes": [  ],
+   "file_handler_permission_blocked": false,
+   "file_handlers": [  ],
+   "icon_infos": [  ],
+   "install_time": "1601-01-01 00:00:00.000 UTC",
+   "is_generated_icon": false,
+   "is_in_sync_install": false,
+   "is_locally_installed": true,
+   "is_storage_isolated": false,
+   "is_uninstalling": false,
+   "last_badging_time": "1601-01-01 00:00:00.000 UTC",
+   "last_launch_time": "1601-01-01 00:00:00.000 UTC",
+   "launch_query_params": null,
+   "manifest_id": null,
+   "manifest_url": "",
+   "note_taking_new_note_url": "",
+   "protocol_handlers": [  ],
+   "run_on_os_login_mode": "not run",
+   "scope": "",
+   "share_target": null,
+   "shortcuts_menu_item_infos": [  ],
+   "sources": [  ],
+   "start_url": "",
+   "sync_fallback_data": {
+      "icon_infos": [  ],
+      "name": "",
+      "scope": "",
+      "theme_color": "none"
+   },
+   "theme_color": "none",
+   "unhashed_app_id": "",
+   "url_handlers": [  ],
+   "user_display_mode": "",
+   "user_launch_ordinal": "INVALID[]",
+   "user_page_ordinal": "INVALID[]",
+   "window_controls_overlay_enabled": false
+})")
+          .value_or(base::Value("Failed to parse")),
+      WebAppToPlatformAgnosticJson(std::make_unique<WebApp>("empty_app")));
 }
 
-TEST(WebAppTest, SampleAppToDebugString) {
-  std::string debug_string = WebAppToPlatformAgnosticString(
-      test::CreateRandomWebApp(GURL("https://example.com/"), /*seed=*/1234));
-  EXPECT_EQ(debug_string,
-            R"(app_id: eajjdjobhihlgobdfaehiiheinneagde
-unhashed app_id: https://example.com/scope1234/start1234
-manifest_url: https://example.com/manifest1234.json
-manifest_id: nullopt
-name: Name1234
-start_url: https://example.com/scope1234/start1234
-launch_query_params: 3248422070
-scope: https://example.com/scope1234/
-theme_color: rgba(151,34,83,0.8823529411764706)
-background_color: rgba(77,188,194,0.9686274509803922)
-display_mode: fullscreen
-display_override:
-user_display_mode: standalone
-user_page_ordinal: INVALID[]
-user_launch_ordinal: INVALID[]
-sources: WebAppStore Sync Default
-is_locally_installed: 1
-is_in_sync_install: 0
-is_uninstalling: 0
-sync_fallback_data:
-  name: SyncName1234
-  theme_color: rgba(61,127,69,0.8431372549019608)
-  scope: https://example.com/scope1234/
-  icon_infos:
-    url: https://example.com/icon1783899413
-      square_size_px: none
-      purpose: ANY
-    url: https://example.com/icon3011162902
-      square_size_px: none
-      purpose: ANY
-description: Description1234
-last_badging_time: 1970-01-12 14:48:29.918 UTC
-last_launch_time: 1970-01-02 16:03:30.110 UTC
-install_time: 1970-01-09 06:11:52.363 UTC
-is_generated_icon: 0
-run_on_os_login_mode: minimized
-icon_infos:
-  url: https://example.com/icon1783899413
-    square_size_px: none
-    purpose: ANY
-  url: https://example.com/icon3011162902
-    square_size_px: none
-    purpose: ANY
-downloaded_icon_sizes_any: 256
-downloaded_icon_sizes_monochrome: 256
-downloaded_icon_sizes_maskable:
-shortcuts_menu_item_infos:
-  name: shortcut29001084322
-    url: https://example.com/scope1234/shortcut29001084322
-    icons:
-      any:
-      maskable:
-        url: https://example.com/shortcuts/icon290010843223
-        square_size_px: 30
-        url: https://example.com/shortcuts/icon290010843221
-        square_size_px: 15
-      monochrome:
-        url: https://example.com/shortcuts/icon290010843222
-        square_size_px: 23
-        url: https://example.com/shortcuts/icon290010843220
-        square_size_px: 8
-  name: shortcut29001084321
-    url: https://example.com/scope1234/shortcut29001084321
-    icons:
-      any:
-        url: https://example.com/shortcuts/icon290010843210
-        square_size_px: 4
-      maskable:
-        url: https://example.com/shortcuts/icon290010843212
-        square_size_px: 24
-        url: https://example.com/shortcuts/icon290010843211
-        square_size_px: 19
-      monochrome:
-  name: shortcut29001084320
-    url: https://example.com/scope1234/shortcut29001084320
-    icons:
-      any:
-        url: https://example.com/shortcuts/icon290010843200
-        square_size_px: 0
-      maskable:
-      monochrome:
-        url: https://example.com/shortcuts/icon290010843202
-        square_size_px: 23
-        url: https://example.com/shortcuts/icon290010843201
-        square_size_px: 16
-downloaded_shortcuts_menu_icons_sizes:
-  index: 0:
-    any:
-    maskable:
-  index: 1:
-    any: 118
-    maskable: 38
-  index: 2:
-    any: 80 47
-    maskable: 240 164
-file_handlers:
-  action: https://example.com/open-13087720410
-    accept:
-      mime_type: application/13087720410+foo
-      file_extensions: .13087720410a .13087720410b
-    accept:
-      mime_type: application/13087720410+bar
-      file_extensions: .13087720410a .13087720410b
-  action: https://example.com/open-13087720411
-    accept:
-      mime_type: application/13087720411+foo
-      file_extensions: .13087720411a .13087720411b
-    accept:
-      mime_type: application/13087720411+bar
-      file_extensions: .13087720411a .13087720411b
-  action: https://example.com/open-13087720412
-    accept:
-      mime_type: application/13087720412+foo
-      file_extensions: .13087720412a .13087720412b
-    accept:
-      mime_type: application/13087720412+bar
-      file_extensions: .13087720412a .13087720412b
-  action: https://example.com/open-13087720413
-    accept:
-      mime_type: application/13087720413+foo
-      file_extensions: .13087720413a .13087720413b
-    accept:
-      mime_type: application/13087720413+bar
-      file_extensions: .13087720413a .13087720413b
-  action: https://example.com/open-13087720414
-    accept:
-      mime_type: application/13087720414+foo
-      file_extensions: .13087720414a .13087720414b
-    accept:
-      mime_type: application/13087720414+bar
-      file_extensions: .13087720414a .13087720414b
-file_handler_permission_blocked:0
-share_target:
-  nullopt
-additional_search_terms:
-  Foo_1234_0
-protocol_handlers:
-  protocol: web+test244307310 url: https://example.com/244307310
-  protocol: web+test244307311 url: https://example.com/244307311
-  protocol: web+test244307312 url: https://example.com/244307312
-  protocol: web+test244307313 url: https://example.com/244307313
-  protocol: web+test244307314 url: https://example.com/244307314
-approved_launch_protocols:
-  web+test_1234_0
-  web+test_1234_1
-url_handlers:
-  origin: https://app-9974471690.com
-    has_origin_wildcard: true
-    paths:
-    exclude_paths:
-  origin: https://app-9974471691.com
-    has_origin_wildcard: true
-    paths:
-    exclude_paths:
-  origin: https://app-9974471692.com
-    has_origin_wildcard: true
-    paths:
-    exclude_paths:
-note_taking_new_note_url:
-capture_links: kNewClient
-chromeos_data:
-  nullopt
-system_web_app:
-  nullopt
-window_controls_overlay_enabled:
-  0
-is_storage_isolated: 0
-)") << "Copypastable expectation: \n"
-    << debug_string;
+TEST(WebAppTest, SampleAppAsDebugValue) {
+  EXPECT_EQ(base::JSONReader::Read(R"JSON({
+   "!app_id": "eajjdjobhihlgobdfaehiiheinneagde",
+   "!name": "Name1234",
+   "additional_search_terms": [ "Foo_1234_0" ],
+   "app_service_icon_url": "chrome://app-icon/eajjdjobhihlgobdfaehiiheinneagde/32",
+   "approved_launch_protocols": [ "web+test_1234_0", "web+test_1234_1" ],
+   "background_color": "rgba(77,188,194,0.9686274509803922)",
+   "capture_links": "kNewClient",
+   "chromeos_data": null,
+   "client_data": {
+      "system_web_app_data": null
+   },
+   "description": "Description1234",
+   "display_mode": "fullscreen",
+   "display_override": [  ],
+   "downloaded_icon_sizes": {
+      "ANY": [ 256 ],
+      "MASKABLE": [  ],
+      "MONOCHROME": [ 256 ]
+   },
+   "downloaded_shortcuts_menu_icons_sizes": [ {
+      "ANY": [  ],
+      "MASKABLE": [  ],
+      "MONOCHROME": [  ],
+      "index": 0
+   }, {
+      "ANY": [ 118 ],
+      "MASKABLE": [ 38 ],
+      "MONOCHROME": [ 228 ],
+      "index": 1
+   }, {
+      "ANY": [ 80, 47 ],
+      "MASKABLE": [ 240, 164 ],
+      "MONOCHROME": [ 138, 107 ],
+      "index": 2
+   } ],
+   "file_handler_permission_blocked": false,
+   "file_handlers": [ {
+      "accept": [ {
+         "file_extensions": [ ".13087720410a", ".13087720410b" ],
+         "mime_type": "application/13087720410+foo"
+      }, {
+         "file_extensions": [ ".13087720410a", ".13087720410b" ],
+         "mime_type": "application/13087720410+bar"
+      } ],
+      "action": "https://example.com/open-13087720410"
+   }, {
+      "accept": [ {
+         "file_extensions": [ ".13087720411a", ".13087720411b" ],
+         "mime_type": "application/13087720411+foo"
+      }, {
+         "file_extensions": [ ".13087720411a", ".13087720411b" ],
+         "mime_type": "application/13087720411+bar"
+      } ],
+      "action": "https://example.com/open-13087720411"
+   }, {
+      "accept": [ {
+         "file_extensions": [ ".13087720412a", ".13087720412b" ],
+         "mime_type": "application/13087720412+foo"
+      }, {
+         "file_extensions": [ ".13087720412a", ".13087720412b" ],
+         "mime_type": "application/13087720412+bar"
+      } ],
+      "action": "https://example.com/open-13087720412"
+   }, {
+      "accept": [ {
+         "file_extensions": [ ".13087720413a", ".13087720413b" ],
+         "mime_type": "application/13087720413+foo"
+      }, {
+         "file_extensions": [ ".13087720413a", ".13087720413b" ],
+         "mime_type": "application/13087720413+bar"
+      } ],
+      "action": "https://example.com/open-13087720413"
+   }, {
+      "accept": [ {
+         "file_extensions": [ ".13087720414a", ".13087720414b" ],
+         "mime_type": "application/13087720414+foo"
+      }, {
+         "file_extensions": [ ".13087720414a", ".13087720414b" ],
+         "mime_type": "application/13087720414+bar"
+      } ],
+      "action": "https://example.com/open-13087720414"
+   } ],
+   "icon_infos": [ {
+      "purpose": "ANY",
+      "square_size_px": null,
+      "url": "https://example.com/icon1783899413"
+   }, {
+      "purpose": "ANY",
+      "square_size_px": null,
+      "url": "https://example.com/icon3011162902"
+   } ],
+   "install_time": "1970-01-09 06:11:52.363 UTC",
+   "is_generated_icon": false,
+   "is_in_sync_install": false,
+   "is_locally_installed": true,
+   "is_storage_isolated": false,
+   "is_uninstalling": false,
+   "last_badging_time": "1970-01-12 14:48:29.918 UTC",
+   "last_launch_time": "1970-01-02 16:03:30.110 UTC",
+   "launch_query_params": "3248422070",
+   "manifest_id": null,
+   "manifest_url": "https://example.com/manifest1234.json",
+   "note_taking_new_note_url": "",
+   "protocol_handlers": [ {
+      "protocol": "web+test244307310",
+      "url": "https://example.com/244307310"
+   }, {
+      "protocol": "web+test244307311",
+      "url": "https://example.com/244307311"
+   }, {
+      "protocol": "web+test244307312",
+      "url": "https://example.com/244307312"
+   }, {
+      "protocol": "web+test244307313",
+      "url": "https://example.com/244307313"
+   }, {
+      "protocol": "web+test244307314",
+      "url": "https://example.com/244307314"
+   } ],
+   "run_on_os_login_mode": "minimized",
+   "scope": "https://example.com/scope1234/",
+   "share_target": null,
+   "shortcuts_menu_item_infos": [ {
+      "icons": {
+         "ANY": [  ],
+         "MASKABLE": [ {
+            "square_size_px": 30,
+            "url": "https://example.com/shortcuts/icon290010843223"
+         }, {
+            "square_size_px": 15,
+            "url": "https://example.com/shortcuts/icon290010843221"
+         } ],
+         "MONOCHROME": [ {
+            "square_size_px": 23,
+            "url": "https://example.com/shortcuts/icon290010843222"
+         }, {
+            "square_size_px": 8,
+            "url": "https://example.com/shortcuts/icon290010843220"
+         } ]
+      },
+      "name": "shortcut29001084322",
+      "url": "https://example.com/scope1234/shortcut29001084322"
+   }, {
+      "icons": {
+         "ANY": [ {
+            "square_size_px": 4,
+            "url": "https://example.com/shortcuts/icon290010843210"
+         } ],
+         "MASKABLE": [ {
+            "square_size_px": 24,
+            "url": "https://example.com/shortcuts/icon290010843212"
+         }, {
+            "square_size_px": 19,
+            "url": "https://example.com/shortcuts/icon290010843211"
+         } ],
+         "MONOCHROME": [  ]
+      },
+      "name": "shortcut29001084321",
+      "url": "https://example.com/scope1234/shortcut29001084321"
+   }, {
+      "icons": {
+         "ANY": [ {
+            "square_size_px": 0,
+            "url": "https://example.com/shortcuts/icon290010843200"
+         } ],
+         "MASKABLE": [  ],
+         "MONOCHROME": [ {
+            "square_size_px": 23,
+            "url": "https://example.com/shortcuts/icon290010843202"
+         }, {
+            "square_size_px": 16,
+            "url": "https://example.com/shortcuts/icon290010843201"
+         } ]
+      },
+      "name": "shortcut29001084320",
+      "url": "https://example.com/scope1234/shortcut29001084320"
+   } ],
+   "sources": [ "WebAppStore", "Sync", "Default" ],
+   "start_url": "https://example.com/scope1234/start1234",
+   "sync_fallback_data": {
+      "icon_infos": [ {
+         "purpose": "ANY",
+         "square_size_px": null,
+         "url": "https://example.com/icon1783899413"
+      }, {
+         "purpose": "ANY",
+         "square_size_px": null,
+         "url": "https://example.com/icon3011162902"
+      } ],
+      "name": "SyncName1234",
+      "scope": "https://example.com/scope1234/",
+      "theme_color": "rgba(61,127,69,0.8431372549019608)"
+   },
+   "theme_color": "rgba(151,34,83,0.8823529411764706)",
+   "unhashed_app_id": "https://example.com/scope1234/start1234",
+   "url_handlers": [ {
+      "exclude_paths": [  ],
+      "has_origin_wildcard": true,
+      "origin": "https://app-9974471690.com",
+      "paths": [  ]
+   }, {
+      "exclude_paths": [  ],
+      "has_origin_wildcard": true,
+      "origin": "https://app-9974471691.com",
+      "paths": [  ]
+   }, {
+      "exclude_paths": [  ],
+      "has_origin_wildcard": true,
+      "origin": "https://app-9974471692.com",
+      "paths": [  ]
+   } ],
+   "user_display_mode": "standalone",
+   "user_launch_ordinal": "INVALID[]",
+   "user_page_ordinal": "INVALID[]",
+   "window_controls_overlay_enabled": false
+})JSON")
+                .value_or(base::Value("Failed to parse")),
+            WebAppToPlatformAgnosticJson(test::CreateRandomWebApp(
+                GURL("https://example.com/"), /*seed=*/1234)));
 }
 
 }  // namespace web_app
diff --git a/chrome/browser/webshare/win/show_share_ui_for_window_operation.h b/chrome/browser/webshare/win/show_share_ui_for_window_operation.h
index 0452dfd..1b7a4308 100644
--- a/chrome/browser/webshare/win/show_share_ui_for_window_operation.h
+++ b/chrome/browser/webshare/win/show_share_ui_for_window_operation.h
@@ -9,6 +9,7 @@
 
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "base/win/core_winrt_util.h"
 
 namespace ABI {
diff --git a/chrome/browser/win/conflicts/third_party_conflicts_manager.cc b/chrome/browser/win/conflicts/third_party_conflicts_manager.cc
index e69f548..47210739 100644
--- a/chrome/browser/win/conflicts/third_party_conflicts_manager.cc
+++ b/chrome/browser/win/conflicts/third_party_conflicts_manager.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/win/conflicts/third_party_conflicts_manager.h"
 
+#include <windows.h>
+
 #include <string>
 #include <utility>
 
diff --git a/chrome/chrome_cleaner/engines/broker/interface_log_service.h b/chrome/chrome_cleaner/engines/broker/interface_log_service.h
index 87a47ca..add9e5d 100644
--- a/chrome/chrome_cleaner/engines/broker/interface_log_service.h
+++ b/chrome/chrome_cleaner/engines/broker/interface_log_service.h
@@ -14,6 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/lock.h"
+#include "base/time/time.h"
 #include "chrome/chrome_cleaner/engines/broker/interface_metadata_observer.h"
 #include "chrome/chrome_cleaner/logging/proto/interface_logger.pb.h"
 
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index cb9bd6aa..99cbe8a 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -48,6 +48,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Controls whether intent settings are available in App Management.
+// TODO(crbug/1226925): Do not enable flag unless this has been resolved.
 const base::Feature kAppManagementIntentSettings{
     "AppManagementIntentSettings", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -776,7 +777,7 @@
                                               base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables recording additional web app related debugging data to be displayed
-// in: chrome://internals/web-app
+// in: chrome://web-app-internals
 const base::Feature kRecordWebAppDebugInfo{"RecordWebAppDebugInfo",
                                            base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -972,6 +973,13 @@
     kTrustSafetySentimentSurveyPrivacySettingsTime{
         &kTrustSafetySentimentSurvey, "privacy-settings-time",
         base::TimeDelta::FromSeconds(20)};
+// The time the user must have the Trusted Surface bubble open to be considered.
+// Alternatively the user can interact with the bubble, in which case this time
+// is irrelevant.
+const base::FeatureParam<base::TimeDelta>
+    kTrustSafetySentimentSurveyTrustedSurfaceTime{
+        &kTrustSafetySentimentSurvey, "trusted-surface-time",
+        base::TimeDelta::FromSeconds(5)};
 
 #endif
 
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index c6607ee..87ba7507 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -653,6 +653,9 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::FeatureParam<base::TimeDelta>
     kTrustSafetySentimentSurveyPrivacySettingsTime;
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::FeatureParam<base::TimeDelta>
+    kTrustSafetySentimentSurveyTrustedSurfaceTime;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/common/chrome_paths_lacros.cc b/chrome/common/chrome_paths_lacros.cc
index 74bb19b4..f82406e 100644
--- a/chrome/common/chrome_paths_lacros.cc
+++ b/chrome/common/chrome_paths_lacros.cc
@@ -18,6 +18,8 @@
 struct DefaultPaths {
   base::FilePath documents_dir;
   base::FilePath downloads_dir;
+  // |drivefs| is empty if Drive is not enabled in Ash.
+  base::FilePath drivefs;
 };
 
 DefaultPaths& GetDefaultPaths() {
@@ -28,7 +30,8 @@
 }  // namespace
 
 void SetLacrosDefaultPaths(const base::FilePath& documents_dir,
-                           const base::FilePath& downloads_dir) {
+                           const base::FilePath& downloads_dir,
+                           const base::FilePath& drivefs) {
   DCHECK(!documents_dir.empty());
   DCHECK(documents_dir.IsAbsolute());
   GetDefaultPaths().documents_dir = documents_dir;
@@ -36,6 +39,8 @@
   DCHECK(!downloads_dir.empty());
   DCHECK(downloads_dir.IsAbsolute());
   GetDefaultPaths().downloads_dir = downloads_dir;
+
+  GetDefaultPaths().drivefs = drivefs;
 }
 
 bool GetDefaultUserDataDirectory(base::FilePath* result) {
@@ -96,4 +101,13 @@
   return true;
 }
 
+bool GetDriveFsMountPointPath(base::FilePath* result) {
+  // NOTE: Lacros overrides the path with a value from ash early in startup. See
+  // crosapi::mojom::LacrosInitParams.
+  if (GetDefaultPaths().drivefs.empty())
+    return false;
+  *result = GetDefaultPaths().drivefs;
+  return true;
+}
+
 }  // namespace chrome
diff --git a/chrome/common/chrome_paths_lacros.h b/chrome/common/chrome_paths_lacros.h
index 2622f1cf..bb77d52 100644
--- a/chrome/common/chrome_paths_lacros.h
+++ b/chrome/common/chrome_paths_lacros.h
@@ -11,10 +11,15 @@
 
 namespace chrome {
 
-// Sets the default paths for user documents and downloads. The paths are sent
-// by ash-chrome and are set early in lacros-chrome startup.
+// Sets the default paths for user documents, downloads and the mount point for
+// Drive. The paths are sent by ash-chrome and are set early in lacros-chrome
+// startup.
 void SetLacrosDefaultPaths(const base::FilePath& documents_dir,
-                           const base::FilePath& downloads_dir);
+                           const base::FilePath& downloads_dir,
+                           const base::FilePath& drivefs);
+
+// Returns false if Drive is not enabled in Ash.
+bool GetDriveFsMountPointPath(base::FilePath* result);
 
 }  // namespace chrome
 
diff --git a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc
index d6fbcdc5..cb3cbea 100644
--- a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc
+++ b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler.cc
@@ -169,7 +169,7 @@
   if (file_browser_handler->HasKey(keys::kFileAccessList)) {
     if (!file_browser_handler->GetList(keys::kFileAccessList,
                                        &access_list_value) ||
-        access_list_value->empty()) {
+        access_list_value->GetList().empty()) {
       *error = base::ASCIIToUTF16(errors::kInvalidFileAccessList);
       return nullptr;
     }
diff --git a/chrome/common/extensions/command_unittest.cc b/chrome/common/extensions/command_unittest.cc
index a185c34..c3331a9 100644
--- a/chrome/common/extensions/command_unittest.cc
+++ b/chrome/common/extensions/command_unittest.cc
@@ -246,29 +246,29 @@
   // Misspell a platform.
   key_dict->SetString("windosw", "Ctrl+M");
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
-  EXPECT_TRUE(key_dict->Remove("windosw", NULL));
+  EXPECT_TRUE(key_dict->RemoveKey("windosw"));
 
   // Now remove platform specific keys (leaving just "default") and make sure
   // every platform falls back to the default.
-  EXPECT_TRUE(key_dict->Remove("windows", NULL));
-  EXPECT_TRUE(key_dict->Remove("mac", NULL));
-  EXPECT_TRUE(key_dict->Remove("linux", NULL));
-  EXPECT_TRUE(key_dict->Remove("chromeos", NULL));
+  EXPECT_TRUE(key_dict->RemoveKey("windows"));
+  EXPECT_TRUE(key_dict->RemoveKey("mac"));
+  EXPECT_TRUE(key_dict->RemoveKey("linux"));
+  EXPECT_TRUE(key_dict->RemoveKey("chromeos"));
   EXPECT_TRUE(command.Parse(input.get(), command_name, 0, &error));
   EXPECT_EQ(ui::VKEY_D, command.accelerator().key_code());
 
   // Now remove "default", leaving no option but failure. Or, in the words of
   // the immortal Adam Savage: "Failure is always an option".
-  EXPECT_TRUE(key_dict->Remove("default", NULL));
+  EXPECT_TRUE(key_dict->RemoveKey("default"));
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
 
   // Make sure Command is not supported for non-Mac platforms.
   key_dict->SetString("default", "Command+M");
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
-  EXPECT_TRUE(key_dict->Remove("default", NULL));
+  EXPECT_TRUE(key_dict->RemoveKey("default"));
   key_dict->SetString("windows", "Command+M");
   EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error));
-  EXPECT_TRUE(key_dict->Remove("windows", NULL));
+  EXPECT_TRUE(key_dict->RemoveKey("windows"));
 
   // Now add only a valid platform that we are not running on to make sure devs
   // are notified of errors on other platforms.
diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc
index 32a5980..12177de2 100644
--- a/chrome/common/extensions/manifest_unittest.cc
+++ b/chrome/common/extensions/manifest_unittest.cc
@@ -59,7 +59,7 @@
     if (value)
       manifest_value->Set(key, std::move(value));
     else
-      manifest_value->Remove(key, nullptr);
+      manifest_value->RemovePath(key);
     ExtensionId extension_id = manifest->get()->extension_id();
     *manifest = std::make_unique<Manifest>(
         ManifestLocation::kInternal, std::move(manifest_value), extension_id);
diff --git a/chrome/common/extensions/sync_type_unittest.cc b/chrome/common/extensions/sync_type_unittest.cc
index 2a5b4cd..b08055338 100644
--- a/chrome/common/extensions/sync_type_unittest.cc
+++ b/chrome/common/extensions/sync_type_unittest.cc
@@ -177,7 +177,7 @@
   EXPECT_TRUE(app->ShouldDisplayInNewTabPage());
 
   // Value display_in_NTP = false only, overrides default = true.
-  manifest.Remove(keys::kDisplayInLauncher, NULL);
+  manifest.RemoveKey(keys::kDisplayInLauncher);
   manifest.SetBoolean(keys::kDisplayInNewTabPage, false);
   app = Extension::Create(base::FilePath(), mojom::ManifestLocation::kComponent,
                           manifest, 0, &error);
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 308a5d72..190cefe3 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1651,10 +1651,10 @@
 // to "1.0.0.0".
 const char kProfileCreatedByVersion[] = "profile.created_by_version";
 
-// A map of profile data directory to cached information. This cache can be
-// used to display information about profiles without actually having to load
+// A map of profile data directory to profile attributes. These attributes can
+// be used to display information about profiles without actually having to load
 // them.
-const char kProfileInfoCache[] = "profile.info_cache";
+const char kProfileAttributes[] = "profile.info_cache";
 
 // A list of profile paths that should be deleted on shutdown. The deletion does
 // not happen if the browser crashes, so we remove the profile on next start.
@@ -2829,6 +2829,8 @@
 #endif
 
 const char kBackgroundTracingLastUpload[] = "background_tracing.last_upload";
+const char kBackgroundTracingSessionState[] =
+    "background_tracing.session_state";
 
 const char kAllowDinosaurEasterEgg[] = "allow_dinosaur_easter_egg";
 
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 35956d3b..142a6a69 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -539,7 +539,7 @@
 extern const char kProfilesLastActive[];
 extern const char kProfilesNumCreated[];
 extern const char kGuestProfilesNumCreated[];
-extern const char kProfileInfoCache[];
+extern const char kProfileAttributes[];
 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 extern const char kLegacyProfileNamesMigrated[];
 #endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
@@ -965,6 +965,7 @@
 #endif
 
 extern const char kBackgroundTracingLastUpload[];
+extern const char kBackgroundTracingSessionState[];
 
 extern const char kAllowDinosaurEasterEgg[];
 
diff --git a/chrome/common/privacy_budget/privacy_budget_features.cc b/chrome/common/privacy_budget/privacy_budget_features.cc
index 9571caa..cb81633 100644
--- a/chrome/common/privacy_budget/privacy_budget_features.cc
+++ b/chrome/common/privacy_budget/privacy_budget_features.cc
@@ -30,4 +30,8 @@
 const base::FeatureParam<std::string> kIdentifiabilityStudyPerTypeSettings = {
     &kIdentifiabilityStudy, "TypeRate", ""};
 
+const base::FeatureParam<std::string>
+    kIdentifiabilityStudySurfaceEquivalenceClasses = {&kIdentifiabilityStudy,
+                                                      "Classes", ""};
+
 }  // namespace features
diff --git a/chrome/common/privacy_budget/privacy_budget_features.h b/chrome/common/privacy_budget/privacy_budget_features.h
index d71947d..dc7aecee 100644
--- a/chrome/common/privacy_budget/privacy_budget_features.h
+++ b/chrome/common/privacy_budget/privacy_budget_features.h
@@ -24,8 +24,7 @@
 // will be recorded or reported.
 //
 // Enabling the feature doesn't automatically make this client part of the study
-// either. See documentation for IdentifiabilityStudySettings for a full list of
-// the criteria that contributes to that decision.
+// either.
 extern const base::Feature kIdentifiabilityStudy;
 
 // Each time the key study parameters change, the study generation also
@@ -45,9 +44,15 @@
 // Parameter type: Comma separated list of decimal integers, each of which
 //     represents an IdentifiableSurface.
 //
+// When specifying these values on the command-line, the commas should be
+// escaped using URL encoding. I.e. '1,2' -> '1%2C2'.
+//
 // E.g.:
 //  * "258, 257" : Matches IdentifiableSurface::FromTypeAndToken(kWebFeature, 1)
 //                 and IdentifiableSurface::FromTypeAndToken(kWebFeature, 2)
+//
+// From 03/2021 the code no longer supports revoking a surface that was once
+// blocked either via "BlockedHashes" or "BlockedTypes".
 extern const base::FeatureParam<std::string>
     kIdentifiabilityStudyBlockedMetrics;
 
@@ -57,6 +62,9 @@
 // Parameter type: Comma separated list of decimal integers, each of which
 //                 represents an IdentifiableSurface::Type.
 //
+// When specifying these values on the command-line, the commas should be
+// escaped using URL encoding. I.e. '1,2' -> '1%2C2'.
+//
 // E.g.:
 //  * "1, 2" : Matches all surfaces with types kWebFeature and kCanvasReadback.
 extern const base::FeatureParam<std::string> kIdentifiabilityStudyBlockedTypes;
@@ -87,6 +95,30 @@
 // `kMaxIdentifiabilityStudyMaxSurfaces`.
 constexpr int kMaxIdentifiabilityStudyMaxSurfaces = 40;
 
+// Surface equivalence classes.
+//
+// Parameter name: "Classes"
+// Parameter type: Comma separated list of classes. Each class is a semicolon
+//                 separated list of surfaces. See examples below.
+//
+//                 NOTE: The first surface in the list is the representative
+//                 surface that forms the basis for determining the cost for
+//                 the entire class. I.e. the cost of the first surface in the
+//                 list is assumed to be the cost of _any subset_ of surfaces
+//                 in the set.
+//
+// Every surface in an equivalence class is assumed to be pairwise perfectly
+// correlated with all other surfaces in the set. For more details see
+// definition of SurfaceSetValuation::EquivalenceClassIdentifierMap.
+//
+// E.g.:
+//   * "1;2;3,4;5;6" : Defines two classes: {1,2,3} and {4,5,6}. The surface
+//     with ID 1 defines the cost of the entire class {1,2,3}. Similarly the
+//     surface with ID 4 defines the cost of the entire class {4,5,6}.
+//
+extern const base::FeatureParam<std::string>
+    kIdentifiabilityStudySurfaceEquivalenceClasses;
+
 // Selection rate for clusters of related surfaces.
 //
 // Parameter name: "HashRate"
@@ -98,7 +130,7 @@
 extern const base::FeatureParam<std::string>
     kIdentifiabilityStudyPerSurfaceSettings;
 
-// Selection rate for clusters of related surfaces.
+// Selection rate for clusters of related surface types.
 //
 // Parameter name: "TypeRate"
 // Parameter type: Comma separated list of <filter-string>;<rate> pairs.
diff --git a/chrome/common/privacy_budget/privacy_budget_settings_provider.cc b/chrome/common/privacy_budget/privacy_budget_settings_provider.cc
index 9d88ef5..c529b7c 100644
--- a/chrome/common/privacy_budget/privacy_budget_settings_provider.cc
+++ b/chrome/common/privacy_budget/privacy_budget_settings_provider.cc
@@ -19,7 +19,6 @@
       blocked_types_(
           DecodeIdentifiabilityFieldTrialParam<IdentifiableSurfaceTypeSet>(
               features::kIdentifiabilityStudyBlockedTypes.Get())),
-
       // In practice there's really no point in enabling the feature with a max
       // active surface count of 0.
       enabled_(base::FeatureList::IsEnabled(features::kIdentifiabilityStudy) &&
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc
index 3d92b507..6da3ee20 100644
--- a/chrome/common/privacy_budget/scoped_privacy_budget_config.cc
+++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.cc
@@ -4,8 +4,12 @@
 
 #include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
 
+#include "base/check.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/strings/string_number_conversions.h"
 #include "chrome/common/privacy_budget/field_trial_param_conversions.h"
 #include "chrome/common/privacy_budget/privacy_budget_features.h"
+#include "chrome/common/privacy_budget/types.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 
@@ -16,7 +20,11 @@
 ScopedPrivacyBudgetConfig::Parameters::Parameters(Parameters&&) = default;
 ScopedPrivacyBudgetConfig::Parameters::~Parameters() = default;
 
-ScopedPrivacyBudgetConfig::~ScopedPrivacyBudgetConfig() = default;
+ScopedPrivacyBudgetConfig::~ScopedPrivacyBudgetConfig() {
+  DCHECK(applied_) << "ScopedPrivacyBudgetConfig instance created but not "
+                      "applied. Did you forget to call Apply()?";
+}
+
 ScopedPrivacyBudgetConfig::ScopedPrivacyBudgetConfig() = default;
 
 ScopedPrivacyBudgetConfig::ScopedPrivacyBudgetConfig(
@@ -41,6 +49,8 @@
 
 void ScopedPrivacyBudgetConfig::Apply(const Parameters& parameters) {
   blink::IdentifiabilityStudySettings::ResetStateForTesting();
+  DCHECK(!applied_);
+  applied_ = true;
 
   if (!parameters.enabled) {
     scoped_feature_list_.InitAndDisableFeature(features::kIdentifiabilityStudy);
@@ -82,6 +92,11 @@
                 EncodeIdentifiabilityFieldTrialParam(
                     parameters.per_type_sampling_rate)});
   }
+  if (!parameters.equivalence_classes.empty()) {
+    ftp.insert(
+        {features::kIdentifiabilityStudySurfaceEquivalenceClasses.name,
+         EncodeIdentifiabilityFieldTrialParam(parameters.equivalence_classes)});
+  }
 
   scoped_feature_list_.InitAndEnableFeatureWithParameters(
       features::kIdentifiabilityStudy, ftp);
diff --git a/chrome/common/privacy_budget/scoped_privacy_budget_config.h b/chrome/common/privacy_budget/scoped_privacy_budget_config.h
index d84fd64..74a2fe5 100644
--- a/chrome/common/privacy_budget/scoped_privacy_budget_config.h
+++ b/chrome/common/privacy_budget/scoped_privacy_budget_config.h
@@ -11,6 +11,7 @@
 
 #include "base/macros.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/common/privacy_budget/types.h"
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 
 namespace test {
@@ -29,6 +30,14 @@
 //     reverts the configuration changes.
 class ScopedPrivacyBudgetConfig {
  public:
+  // The default generation is arbitrary. The only thing special about this
+  // number is that it is the default.
+  constexpr static int kDefaultGeneration = 17;
+
+  // An expected surface count of one implies that the probability of selecting
+  // a surface is 1/1.
+  constexpr static int kDefaultExpectedSurfaceCount = 1;
+
   // These fields correspond to the equivalent features described in
   // privacy_budget_features.h
   //
@@ -41,14 +50,15 @@
     ~Parameters();
 
     bool enabled = true;
-    int generation = 1;
+    int generation = kDefaultGeneration;
 
     std::vector<blink::IdentifiableSurface> blocked_surfaces;
     std::vector<blink::IdentifiableSurface::Type> blocked_types;
-    int surface_selection_rate = 1;
+    int surface_selection_rate = kDefaultExpectedSurfaceCount;
     int max_surfaces = std::numeric_limits<int>::max();
     std::map<blink::IdentifiableSurface, int> per_surface_sampling_rate;
     std::map<blink::IdentifiableSurface::Type, int> per_type_sampling_rate;
+    SurfaceSetEquivalentClassesList equivalence_classes;
   };
 
   enum Presets {
@@ -78,7 +88,7 @@
   ~ScopedPrivacyBudgetConfig();
 
   // Apply the configuration as described in `parameters`. Should only be called
-  // once.
+  // once per instance.
   void Apply(const Parameters& parameters);
 
   ScopedPrivacyBudgetConfig(const ScopedPrivacyBudgetConfig&) = delete;
@@ -87,6 +97,7 @@
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
+  bool applied_ = false;
 };
 
 }  // namespace test
diff --git a/chrome/common/search/instant_mojom_traits.h b/chrome/common/search/instant_mojom_traits.h
index c15629e..407641c 100644
--- a/chrome/common/search/instant_mojom_traits.h
+++ b/chrome/common/search/instant_mojom_traits.h
@@ -42,7 +42,6 @@
   IPC_STRUCT_TRAITS_MEMBER(title_source)
   IPC_STRUCT_TRAITS_MEMBER(visual_type)
   IPC_STRUCT_TRAITS_MEMBER(icon_type)
-  IPC_STRUCT_TRAITS_MEMBER(data_generation_time)
   IPC_STRUCT_TRAITS_MEMBER(url_for_rappor)
 IPC_STRUCT_TRAITS_END()
 
@@ -52,7 +51,6 @@
   IPC_STRUCT_TRAITS_MEMBER(favicon)
   IPC_STRUCT_TRAITS_MEMBER(title_source)
   IPC_STRUCT_TRAITS_MEMBER(source)
-  IPC_STRUCT_TRAITS_MEMBER(data_generation_time)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(InstantMostVisitedInfo)
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index 1463dad..e4ab013 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -104,7 +104,6 @@
 const char kChromeUIInspectURL[] = "chrome://inspect/";
 const char kChromeUIInternalsHost[] = "internals";
 const char kChromeUIInternalsQueryTilesPath[] = "query-tiles";
-const char kChromeUIInternalsWebAppPath[] = "web-app";
 const char kChromeUIInterstitialHost[] = "interstitials";
 const char kChromeUIInterstitialURL[] = "chrome://interstitials/";
 const char kChromeUIInvalidationsHost[] = "invalidations";
@@ -220,6 +219,7 @@
 const char kChromeUINearbyInternalsHost[] = "nearby-internals";
 const char kChromeUIReadLaterHost[] = "read-later.top-chrome";
 const char kChromeUIReadLaterURL[] = "chrome://read-later.top-chrome/";
+const char kChromeUIWebAppInternalsHost[] = "web-app-internals";
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -536,6 +536,9 @@
     kChromeUIUsbInternalsHost,
     kChromeUIUserActionsHost,
     kChromeUIVersionHost,
+#if !defined(OS_ANDROID)
+    kChromeUIWebAppInternalsHost,
+#endif
     content::kChromeUIAppCacheInternalsHost,
     content::kChromeUIBlobInternalsHost,
     content::kChromeUIConversionInternalsHost,
@@ -584,6 +587,7 @@
     kChromeUIOSCreditsHost,
     kChromeUIOSSettingsHost,
     kChromeUIPowerHost,
+    kChromeUISysInternalsHost,
     kChromeUIInternetConfigDialogHost,
     kChromeUIInternetDetailDialogHost,
     kChromeUIAssistantOptInHost,
@@ -623,8 +627,6 @@
 const char* const kChromeInternalsPathURLs[] = {
 #if defined(OS_ANDROID)
     kChromeUIInternalsQueryTilesPath,
-#else
-    kChromeUIInternalsWebAppPath,
 #endif  // defined(OS_ANDROID)
 #if BUILDFLAG(ENABLE_SESSION_SERVICE)
     kChromeUISessionServiceInternalsPath,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index cc614ab2..7dfb0ed7e2 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -104,7 +104,6 @@
 extern const char kChromeUIInspectURL[];
 extern const char kChromeUIInternalsHost[];
 extern const char kChromeUIInternalsQueryTilesPath[];
-extern const char kChromeUIInternalsWebAppPath[];
 extern const char kChromeUIInterstitialHost[];
 extern const char kChromeUIInterstitialURL[];
 extern const char kChromeUIInvalidationsHost[];
@@ -213,6 +212,7 @@
 extern const char kChromeUINearbyInternalsHost[];
 extern const char kChromeUIReadLaterHost[];
 extern const char kChromeUIReadLaterURL[];
+extern const char kChromeUIWebAppInternalsHost[];
 #endif  // defined(OS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/credential_provider/gaiacp/win_http_url_fetcher.cc b/chrome/credential_provider/gaiacp/win_http_url_fetcher.cc
index cb08151..2310f8d 100644
--- a/chrome/credential_provider/gaiacp/win_http_url_fetcher.cc
+++ b/chrome/credential_provider/gaiacp/win_http_url_fetcher.cc
@@ -20,6 +20,7 @@
 #include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
 #include "chrome/credential_provider/gaiacp/logging.h"
 
 namespace {
diff --git a/chrome/credential_provider/gaiacp/win_http_url_fetcher.h b/chrome/credential_provider/gaiacp/win_http_url_fetcher.h
index 58e368d..071c68c 100644
--- a/chrome/credential_provider/gaiacp/win_http_url_fetcher.h
+++ b/chrome/credential_provider/gaiacp/win_http_url_fetcher.h
@@ -14,6 +14,10 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
+namespace base {
+class TimeDelta;
+}
+
 namespace credential_provider {
 
 class FakeWinHttpUrlFetcherFactory;
diff --git a/chrome/renderer/searchbox/searchbox_extension.cc b/chrome/renderer/searchbox/searchbox_extension.cc
index d77808c3..dc94b7f 100644
--- a/chrome/renderer/searchbox/searchbox_extension.cc
+++ b/chrome/renderer/searchbox/searchbox_extension.cc
@@ -148,13 +148,7 @@
       .Set("title", title)
       .Set("domain", mv_item.url.host())
       .Set("direction", base::StringPiece(direction))
-      .Set("url", mv_item.url.spec())
-      .Set("dataGenerationTime",
-           mv_item.data_generation_time.is_null()
-               ? v8::Local<v8::Value>(v8::Null(isolate))
-               : v8::Date::New(isolate->GetCurrentContext(),
-                               mv_item.data_generation_time.ToJsTime())
-                     .ToLocalChecked());
+      .Set("url", mv_item.url.spec());
 
   // If the suggestion already has a favicon, we populate the element with it.
   if (!mv_item.favicon.spec().empty())
@@ -163,14 +157,6 @@
   return builder.Build();
 }
 
-base::Time ConvertDateValueToTime(v8::Value* value) {
-  DCHECK(value);
-  if (value->IsNull() || !value->IsDate())
-    return base::Time();
-
-  return base::Time::FromJsTime(v8::Date::Cast(value)->ValueOf());
-}
-
 absl::optional<int> CoerceToInt(v8::Isolate* isolate, v8::Value* value) {
   DCHECK(value);
   v8::MaybeLocal<v8::Int32> maybe_int =
@@ -613,18 +599,14 @@
                                                      int rid);
   static void LogEvent(int event);
   static void LogSuggestionEventWithValue(int event, int data);
-  static void LogMostVisitedImpression(
-      int position,
-      int tile_title_source,
-      int tile_source,
-      int tile_type,
-      v8::Local<v8::Value> data_generation_time);
-  static void LogMostVisitedNavigation(
-      int position,
-      int tile_title_source,
-      int tile_source,
-      int tile_type,
-      v8::Local<v8::Value> data_generation_time);
+  static void LogMostVisitedImpression(int position,
+                                       int tile_title_source,
+                                       int tile_source,
+                                       int tile_type);
+  static void LogMostVisitedNavigation(int position,
+                                       int tile_title_source,
+                                       int tile_source,
+                                       int tile_type);
   static void ResetCustomBackgroundInfo();
   static void SetCustomBackgroundInfo(const std::string& background_url,
                                       const std::string& attribution_line_1,
@@ -868,12 +850,10 @@
 }
 
 // static
-void NewTabPageBindings::LogMostVisitedImpression(
-    int position,
-    int tile_title_source,
-    int tile_source,
-    int tile_type,
-    v8::Local<v8::Value> data_generation_time) {
+void NewTabPageBindings::LogMostVisitedImpression(int position,
+                                                  int tile_title_source,
+                                                  int tile_source,
+                                                  int tile_type) {
   SearchBox* search_box = GetSearchBoxForCurrentContext();
   if (!search_box || !HasOrigin(GURL(chrome::kChromeSearchMostVisitedUrl)))
     return;
@@ -886,19 +866,16 @@
         static_cast<ntp_tiles::TileTitleSource>(tile_title_source),
         static_cast<ntp_tiles::TileVisualType>(tile_type),
         favicon_base::IconType::kInvalid,
-        ConvertDateValueToTime(*data_generation_time),
         /*url_for_rappor=*/GURL());
     search_box->LogMostVisitedImpression(impression);
   }
 }
 
 // static
-void NewTabPageBindings::LogMostVisitedNavigation(
-    int position,
-    int tile_title_source,
-    int tile_source,
-    int tile_type,
-    v8::Local<v8::Value> data_generation_time) {
+void NewTabPageBindings::LogMostVisitedNavigation(int position,
+                                                  int tile_title_source,
+                                                  int tile_source,
+                                                  int tile_type) {
   SearchBox* search_box = GetSearchBoxForCurrentContext();
   if (!search_box || !HasOrigin(GURL(chrome::kChromeSearchMostVisitedUrl)))
     return;
@@ -911,7 +888,6 @@
         static_cast<ntp_tiles::TileTitleSource>(tile_title_source),
         static_cast<ntp_tiles::TileVisualType>(tile_type),
         favicon_base::IconType::kInvalid,
-        ConvertDateValueToTime(*data_generation_time),
         /*url_for_rappor=*/GURL());
     search_box->LogMostVisitedNavigation(impression);
   }
diff --git a/chrome/service/service_process_prefs.cc b/chrome/service/service_process_prefs.cc
index e6d50a91..2813fb8 100644
--- a/chrome/service/service_process_prefs.cc
+++ b/chrome/service/service_process_prefs.cc
@@ -60,11 +60,10 @@
 int ServiceProcessPrefs::GetInt(const std::string& key,
                                 int default_value) const {
   const base::Value* value;
-  int result = default_value;
-  if (!prefs_->GetValue(key, &value) || !value->GetAsInteger(&result))
+  if (!prefs_->GetValue(key, &value))
     return default_value;
 
-  return result;
+  return value->GetIfInt().value_or(default_value);
 }
 
 void ServiceProcessPrefs::SetInt(const std::string& key, int value) {
diff --git a/chrome/services/file_util/public/cpp/zip_file_creator.cc b/chrome/services/file_util/public/cpp/zip_file_creator.cc
index e9bbd56..3f26374 100644
--- a/chrome/services/file_util/public/cpp/zip_file_creator.cc
+++ b/chrome/services/file_util/public/cpp/zip_file_creator.cc
@@ -8,6 +8,8 @@
 
 #include "base/bind.h"
 #include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/strings/strcat.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
 #include "components/services/filesystem/directory_impl.h"
@@ -16,6 +18,14 @@
 
 namespace {
 
+std::string Redact(const std::string& s) {
+  return LOG_IS_ON(INFO) ? base::StrCat({"'", s, "'"}) : "(redacted)";
+}
+
+std::string Redact(const base::FilePath& path) {
+  return Redact(path.value());
+}
+
 // Creates the destination zip file only if it does not already exist.
 base::File OpenFileHandleAsync(const base::FilePath& zip_path) {
   return base::File(zip_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
@@ -61,7 +71,7 @@
   DCHECK(!remote_zip_file_creator_);
 
   if (!file.IsValid()) {
-    LOG(ERROR) << "Cannot create ZIP file '" << dest_file_ << "'";
+    LOG(ERROR) << "Cannot create ZIP file " << Redact(dest_file_);
     ReportDone(false);
     return;
   }
diff --git a/chrome/services/file_util/zip_file_creator.cc b/chrome/services/file_util/zip_file_creator.cc
index dee1e219..3a5f4d05 100644
--- a/chrome/services/file_util/zip_file_creator.cc
+++ b/chrome/services/file_util/zip_file_creator.cc
@@ -10,12 +10,21 @@
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/strings/strcat.h"
 #include "components/services/filesystem/public/mojom/types.mojom.h"
 #include "third_party/zlib/google/zip.h"
 
 namespace chrome {
 namespace {
 
+std::string Redact(const std::string& s) {
+  return LOG_IS_ON(INFO) ? base::StrCat({"'", s, "'"}) : "(redacted)";
+}
+
+std::string Redact(const base::FilePath& path) {
+  return Redact(path.value());
+}
+
 // A zip::FileAccessor that talks to a file system through the Mojo
 // filesystem::mojom::Directory.
 class MojoFileAccessor : public zip::FileAccessor {
@@ -45,7 +54,7 @@
 
     std::vector<filesystem::mojom::FileOpenResultPtr> results;
     if (!src_dir_->OpenFileHandles(std::move(details), &results)) {
-      LOG(ERROR) << "Cannot open '" << paths.front() << "' and "
+      LOG(ERROR) << "Cannot open " << Redact(paths.front()) << " and "
                  << (paths.size() - 1) << " other files";
       return false;
     }
@@ -77,7 +86,7 @@
           path.value(), dir_remote.BindNewPipeAndPassReceiver(),
           filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen, &error);
       if (error != base::File::Error::FILE_OK) {
-        LOG(ERROR) << "Cannot open '" << path << "': Error " << error;
+        LOG(ERROR) << "Cannot open " << Redact(path) << ": Error " << error;
         return false;
       }
       dir = dir_remote.get();
@@ -87,7 +96,8 @@
     base::File::Error error;
     dir->Read(&error, &contents);
     if (error != base::File::Error::FILE_OK) {
-      LOG(ERROR) << "Cannot list content of '" << path << "': Error " << error;
+      LOG(ERROR) << "Cannot list content of " << Redact(path) << ": Error "
+                 << error;
       return false;
     }
 
@@ -111,7 +121,8 @@
     filesystem::mojom::FileInformationPtr file_info;
     src_dir_->StatFile(path.value(), &error, &file_info);
     if (error != base::File::Error::FILE_OK) {
-      LOG(ERROR) << "Cannot get info of '" << path << "': Error " << error;
+      LOG(ERROR) << "Cannot get info of " << Redact(path) << ": Error "
+                 << error;
       return false;
     }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ace5f35..0c285fd 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -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("//build/cipd/cipd.gni")
 import("//build/config/buildflags_paint_preview.gni")
 import("//build/config/chrome_build.gni")
 import("//build/config/chromeos/ui_mode.gni")
@@ -438,6 +439,10 @@
     libs = [ "runtimeobject.lib" ]
   }
 
+  if (is_chromeos_ash || is_chromeos_lacros) {
+    deps += [ "//chromeos/dbus/constants" ]
+  }
+
   if (is_chromeos_ash) {
     sources += [
       "../browser/ash/accessibility/speech_monitor.cc",
@@ -1150,6 +1155,7 @@
       "//components/signin/core/browser",
       "//components/signin/public/base:signin_buildflags",
       "//components/signin/public/identity_manager",
+      "//components/signin/public/identity_manager:test_support",
       "//components/site_engagement/content",
       "//components/site_isolation",
       "//components/soda",
@@ -1583,6 +1589,7 @@
       "../browser/net/samesite_cookies_policy_browsertest.cc",
       "../browser/net/storage_test_utils.cc",
       "../browser/net/storage_test_utils.h",
+      "../browser/net/stub_resolver_config_reader_browsertest.cc",
       "../browser/net/system_network_context_manager_browsertest.cc",
       "../browser/net/trust_token_usecounter_browsertest.cc",
       "../browser/net/websocket_browsertest.cc",
@@ -1841,6 +1848,7 @@
       "../browser/ui/find_bar/find_bar_controller_browsertest.cc",
       "../browser/ui/find_bar/find_bar_host_browsertest.cc",
       "../browser/ui/hats/hats_service_browsertest.cc",
+      "../browser/ui/hats/trust_safety_sentiment_service_browsertest.cc",
       "../browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc",
       "../browser/ui/login/login_handler_browsertest.cc",
       "../browser/ui/managed_ui_browsertest.cc",
@@ -6760,7 +6768,6 @@
       "../browser/printing/cloud_print/gcd_api_flow_unittest.cc",
       "../browser/printing/cloud_print/privet_confirm_api_flow_unittest.cc",
       "../browser/printing/cloud_print/privet_http_unittest.cc",
-      "../browser/printing/cloud_print/privet_notifications_unittest.cc",
       "../browser/printing/cloud_print/privet_url_loader_unittest.cc",
     ]
 
@@ -6782,7 +6789,6 @@
     sources += [
       "../browser/safe_browsing/certificate_reporting_service_unittest.cc",
       "../browser/safe_browsing/chrome_password_protection_service_unittest.cc",
-      "../browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc",
       "../browser/safe_browsing/threat_details_unittest.cc",
       "../browser/safe_browsing/ui_manager_unittest.cc",
       "../browser/safe_browsing/user_population_unittest.cc",
@@ -9219,3 +9225,20 @@
     }
   }
 }
+
+# This target is for Lacros version skew testing.
+if (is_chromeos_ash) {
+  cipd_package_definition_by_file("gen_linux_ash_chromium_cipd_yaml") {
+    testonly = true
+    buildtype = "dev"
+    arch = "64bit"
+    files_file = "//chrome/tools/build/chromeos/FILES.cfg"
+    package = "chromium/testing/linux-ash-chromium/x86_64/ash.zip"
+    description = "Prebuilt test binary."
+    install_mode = "copy"
+    deps = [
+      ":test_ash_chrome",
+      "//chrome",
+    ]
+  }
+}
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 14f871c1..74e81789 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -264,6 +264,7 @@
     "//base:base_java_test_support",
     "//chrome/android:base_module_java",
     "//chrome/android:chrome_java",
+    "//chrome/browser/android/browserservices/constants:java",
     "//chrome/browser/android/browserservices/intents:java",
     "//chrome/browser/flags:java",
     "//chrome/browser/language/android:java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
index 2810851..5731708 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/tab/MockTab.java
@@ -92,4 +92,9 @@
     public void setIsInitialized(boolean isInitialized) {
         mIsInitialized = isInitialized;
     }
+
+    @Override
+    public boolean isCustomTab() {
+        return false;
+    }
 }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
index 102a846..64aafed 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
@@ -19,7 +19,6 @@
 import org.chromium.url.GURL;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -52,28 +51,28 @@
         List<SiteSuggestion> siteSuggestions = new ArrayList<>();
         siteSuggestions.add(new SiteSuggestion("0 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#0"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("1 ALLOWLIST",
                 new GURL(testServer.getURL(TEST_PAGE) + "#1"), "/test.png", TileTitleSource.UNKNOWN,
-                TileSource.ALLOWLIST, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.ALLOWLIST, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("2 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#2"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("3 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#3"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("4 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#4"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("5 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#5"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("6 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#6"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         siteSuggestions.add(new SiteSuggestion("7 TOP_SITES",
                 new GURL(testServer.getURL(TEST_PAGE) + "#7"), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date()));
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED));
         return siteSuggestions;
     }
 }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/mostvisited/FakeMostVisitedSites.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/mostvisited/FakeMostVisitedSites.java
index 2f4d2f6..749bdbd 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/mostvisited/FakeMostVisitedSites.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/mostvisited/FakeMostVisitedSites.java
@@ -16,7 +16,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -118,7 +117,7 @@
 
     public static SiteSuggestion createSiteSuggestion(String title, String url) {
         return new SiteSuggestion(title, new GURL(url), "", TileTitleSource.TITLE_TAG,
-                TileSource.TOP_SITES, TileSectionType.PERSONALIZED, new Date());
+                TileSource.TOP_SITES, TileSectionType.PERSONALIZED);
     }
 
     private void notifyTileSuggestionsAvailable() {
diff --git a/chrome/test/base/chrome_test_suite.cc b/chrome/test/base/chrome_test_suite.cc
index 8883ff5..91362ca 100644
--- a/chrome/test/base/chrome_test_suite.cc
+++ b/chrome/test/base/chrome_test_suite.cc
@@ -114,7 +114,8 @@
   CHECK(scoped_temp_dir_.CreateUniqueTempDir());
   base::FilePath temp_path = scoped_temp_dir_.GetPath();
   chrome::SetLacrosDefaultPaths(/*documents_dir=*/temp_path,
-                                /*downloads_dir=*/temp_path);
+                                /*downloads_dir=*/temp_path,
+                                /*drivefs=*/base::FilePath());
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 }
 
diff --git a/chrome/test/base/chrome_unit_test_suite.cc b/chrome/test/base/chrome_unit_test_suite.cc
index 08994e03..1fd60bf 100644
--- a/chrome/test/base/chrome_unit_test_suite.cc
+++ b/chrome/test/base/chrome_unit_test_suite.cc
@@ -36,10 +36,13 @@
 #include "ui/base/ui_base_paths.h"
 #include "ui/gl/test/gl_surface_test_support.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/dbus/constants/dbus_paths.h"
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_paths.h"
 #include "chrome/browser/ash/arc/arc_util.h"
-#include "chromeos/dbus/constants/dbus_paths.h"
 #endif
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -178,6 +181,9 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::RegisterPathProvider();
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
   chromeos::dbus_paths::RegisterPathProvider();
 #endif
 
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index 3be7189c..28b0e8d 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -239,12 +239,18 @@
   return nullptr;
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+views::Button* TestBrowserWindow::GetSharingHubIconButton() {
+  return nullptr;
+}
+#else
 sharing_hub::SharingHubBubbleView* TestBrowserWindow::ShowSharingHubBubble(
     content::WebContents* contents,
     sharing_hub::SharingHubBubbleController* controller,
     bool is_user_gesture) {
   return nullptr;
 }
+#endif
 
 bool TestBrowserWindow::IsDownloadShelfVisible() const {
   return false;
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 4f138d1..8a49177b 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -155,10 +155,14 @@
       content::WebContents* contents,
       send_tab_to_self::SendTabToSelfBubbleController* controller,
       bool is_user_gesture) override;
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  views::Button* GetSharingHubIconButton() override;
+#else
   sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents,
       sharing_hub::SharingHubBubbleController* controller,
       bool is_user_gesture) override;
+#endif
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index a2588a5..a3285683 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -192,11 +192,9 @@
     std::unique_ptr<ProfileManager> profile_manager) {
 #if BUILDFLAG(ENABLE_CHROME_NOTIFICATIONS)
   // NotificationUIManager can contain references to elements in the current
-  // ProfileManager (for example, the MessageCenterSettingsController maintains
-  // a pointer to the ProfileInfoCache). So when we change the ProfileManager
-  // (typically during test shutdown) make sure to reset any objects that might
-  // maintain references to it. See SetLocalState() for a description of a
-  // similar situation.
+  // ProfileManager. So when we change the ProfileManager (typically during test
+  // shutdown) make sure to reset any objects that might maintain references to
+  // it. See SetLocalState() for a description of a similar situation.
   notification_ui_manager_.reset();
 #endif
   profile_manager_ = std::move(profile_manager);
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index 6cb52fc7..fc7b531 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/browser_features.h"
 #include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
-#include "chrome/browser/profiles/profile_info_cache.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
@@ -144,7 +143,8 @@
   builder.SetGuestSession();
   builder.SetPath(ProfileManager::GetGuestProfilePath());
 
-  // Add the guest profile to the profile manager, but not to the info cache.
+  // Add the guest profile to the profile manager, but not to the attributes
+  // storage.
   std::unique_ptr<TestingProfile> profile = builder.Build();
   TestingProfile* profile_ptr = profile.get();
   profile_ptr->set_profile_name(kGuestProfileName);
@@ -170,7 +170,8 @@
   TestingProfile::Builder builder;
   builder.SetPath(ProfileManager::GetSystemProfilePath());
 
-  // Add the system profile to the profile manager, but not to the info cache.
+  // Add the system profile to the profile manager, but not to the attributes
+  // storage.
   std::unique_ptr<TestingProfile> profile = builder.Build();
   TestingProfile* profile_ptr = profile.get();
   profile_ptr->set_profile_name(kSystemProfileName);
@@ -237,8 +238,8 @@
       ProfileManager::GetSystemProfilePath());
 }
 
-void TestingProfileManager::DeleteProfileInfoCache() {
-  profile_manager_->profile_info_cache_.reset(NULL);
+void TestingProfileManager::DeleteProfileAttributesStorage() {
+  profile_manager_->profile_attributes_storage_.reset(nullptr);
 }
 
 void TestingProfileManager::UpdateLastUser(Profile* last_active) {
@@ -257,13 +258,9 @@
   return profile_manager_;
 }
 
-ProfileInfoCache* TestingProfileManager::profile_info_cache() {
-  DCHECK(called_set_up_);
-  return &profile_manager_->GetProfileInfoCache();
-}
-
 ProfileAttributesStorage* TestingProfileManager::profile_attributes_storage() {
-  return profile_info_cache();
+  DCHECK(called_set_up_);
+  return &profile_manager_->GetProfileAttributesStorage();
 }
 
 void TestingProfileManager::OnProfileWillBeDestroyed(Profile* profile) {
@@ -289,7 +286,7 @@
   profile_manager_ = profile_manager_unique.get();
   browser_process_->SetProfileManager(std::move(profile_manager_unique));
 
-  profile_manager_->GetProfileInfoCache().
-      set_disable_avatar_download_for_testing(true);
+  profile_manager_->GetProfileAttributesStorage()
+      .set_disable_avatar_download_for_testing(true);
   called_set_up_ = true;
 }
diff --git a/chrome/test/base/testing_profile_manager.h b/chrome/test/base/testing_profile_manager.h
index c401e9f..b032d751 100644
--- a/chrome/test/base/testing_profile_manager.h
+++ b/chrome/test/base/testing_profile_manager.h
@@ -18,7 +18,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/policy/core/common/policy_service.h"
 
-class ProfileInfoCache;
 class ProfileAttributesStorage;
 class ProfileManager;
 class TestingBrowserProcess;
@@ -58,9 +57,9 @@
   // |prefs| is the PrefService used by the profile. If it is NULL, the profile
   // creates a PrefService on demand.
   // |user_name|, |avatar_id| and |supervised_user_id| are passed along to the
-  // ProfileInfoCache and provide the user-visible profile metadata. This will
-  // register the TestingProfile with the profile subsystem as well. The
-  // subsystem owns the Profile and returns a weak pointer.
+  // ProfileAttributesStorage and provide the user-visible profile metadata.
+  // This will register the TestingProfile with the profile subsystem as well.
+  // The subsystem owns the Profile and returns a weak pointer.
   // |factories| contains BCKSs to use with the newly created profile.
   TestingProfile* CreateTestingProfile(
       const std::string& profile_name,
@@ -81,14 +80,14 @@
 
   // Creates a new guest TestingProfile whose data lives in the guest profile
   // test environment directory, as specified by the profile manager.
-  // This profile will not be added to the ProfileInfoCache. This will
+  // This profile will not be added to the ProfileAttributesStorage. This will
   // register the TestingProfile with the profile subsystem as well.
   // The subsystem owns the Profile and returns a weak pointer.
   TestingProfile* CreateGuestProfile();
 
   // Creates a new system TestingProfile whose data lives in the system profile
   // test environment directory, as specified by the profile manager.
-  // This profile will not be added to the ProfileInfoCache. This will
+  // This profile will not be added to the ProfileAttributesStorage. This will
   // register the TestingProfile with the profile subsystem as well.
   // The subsystem owns the Profile and returns a weak pointer.
   TestingProfile* CreateSystemProfile();
@@ -106,9 +105,9 @@
   // Deletes a system TestingProfile from the profile manager.
   void DeleteSystemProfile();
 
-  // Deletes the cache instance. This is useful for testing that the cache is
-  // properly persisting data.
-  void DeleteProfileInfoCache();
+  // Deletes the storage instance. This is useful for testing that the storage
+  // is properly persisting data.
+  void DeleteProfileAttributesStorage();
 
   // Sets the last used profile; also sets the active time to now.
   void UpdateLastUser(Profile* last_active);
@@ -124,7 +123,6 @@
 
  private:
   friend class ProfileAttributesStorageTest;
-  friend class ProfileInfoCacheTest;
   friend class ProfileNameVerifierObserver;
 
   typedef std::map<std::string, TestingProfile*> TestingProfilesMap;
@@ -134,9 +132,6 @@
   // returned in the public SetUp.
   void SetUpInternal(const base::FilePath& profiles_path);
 
-  // Deprecated helper accessor. Use profile_attributes_storage() instead.
-  ProfileInfoCache* profile_info_cache();
-
   // Whether SetUp() was called to put the object in a valid state.
   bool called_set_up_;
 
diff --git a/chrome/test/chromedriver/util.cc b/chrome/test/chromedriver/util.cc
index dacd6b6..3151e11c 100644
--- a/chrome/test/chromedriver/util.cc
+++ b/chrome/test/chromedriver/util.cc
@@ -444,12 +444,14 @@
 
 namespace {
 
+// Deprecated. Please use GetOptionalValue.
+// See crbug.com/1187001 for the migration details.
 template <typename T>
-bool GetOptionalValue(const base::DictionaryValue* dict,
-                      base::StringPiece path,
-                      T* out_value,
-                      bool* has_value,
-                      bool (base::Value::*getter)(T*) const) {
+bool GetOptionalValueDeprecated(const base::DictionaryValue* dict,
+                                base::StringPiece path,
+                                T* out_value,
+                                bool* has_value,
+                                bool (base::Value::*getter)(T*) const) {
   if (has_value != nullptr)
     *has_value = false;
   const base::Value* value;
@@ -463,14 +465,39 @@
   return false;
 }
 
+template <typename T>
+bool GetOptionalValue(const base::Value* dict,
+                      base::StringPiece path,
+                      T* out_value,
+                      bool* has_value,
+                      absl::optional<T> (base::Value::*getter)() const) {
+  if (has_value != nullptr)
+    *has_value = false;
+
+  if (!dict->is_dict())
+    return false;
+
+  const base::Value* value = dict->FindPath(path);
+  if (!value)
+    return true;
+  absl::optional<T> maybe_value = (value->*getter)();
+  if (maybe_value.has_value()) {
+    *out_value = maybe_value.value();
+    if (has_value != nullptr)
+      *has_value = true;
+    return true;
+  }
+  return false;
+}
+
 }  // namespace
 
 bool GetOptionalBool(const base::DictionaryValue* dict,
                      base::StringPiece path,
                      bool* out_value,
                      bool* has_value) {
-  return GetOptionalValue(dict, path, out_value, has_value,
-                          &base::Value::GetAsBoolean);
+  return GetOptionalValueDeprecated(dict, path, out_value, has_value,
+                                    &base::Value::GetAsBoolean);
 }
 
 bool GetOptionalInt(const base::DictionaryValue* dict,
@@ -478,7 +505,7 @@
                     int* out_value,
                     bool* has_value) {
   if (GetOptionalValue(dict, path, out_value, has_value,
-                       &base::Value::GetAsInteger)) {
+                       &base::Value::GetIfInt)) {
     return true;
   }
   // See if we have a double that contains an int value.
@@ -500,32 +527,32 @@
                        double* out_value,
                        bool* has_value) {
   // base::Value::GetAsDouble already converts int to double if needed.
-  return GetOptionalValue(dict, path, out_value, has_value,
-                          &base::Value::GetAsDouble);
+  return GetOptionalValueDeprecated(dict, path, out_value, has_value,
+                                    &base::Value::GetAsDouble);
 }
 
 bool GetOptionalString(const base::DictionaryValue* dict,
                        base::StringPiece path,
                        std::string* out_value,
                        bool* has_value) {
-  return GetOptionalValue(dict, path, out_value, has_value,
-                          &base::Value::GetAsString);
+  return GetOptionalValueDeprecated(dict, path, out_value, has_value,
+                                    &base::Value::GetAsString);
 }
 
 bool GetOptionalDictionary(const base::DictionaryValue* dict,
                            base::StringPiece path,
                            const base::DictionaryValue** out_value,
                            bool* has_value) {
-  return GetOptionalValue(dict, path, out_value, has_value,
-                          &base::Value::GetAsDictionary);
+  return GetOptionalValueDeprecated(dict, path, out_value, has_value,
+                                    &base::Value::GetAsDictionary);
 }
 
 bool GetOptionalList(const base::DictionaryValue* dict,
                      base::StringPiece path,
                      const base::ListValue** out_value,
                      bool* has_value) {
-  return GetOptionalValue(dict, path, out_value, has_value,
-                          &base::Value::GetAsList);
+  return GetOptionalValueDeprecated(dict, path, out_value, has_value,
+                                    &base::Value::GetAsList);
 }
 
 bool GetOptionalSafeInt(const base::DictionaryValue* dict,
@@ -535,8 +562,8 @@
   // Check if we have a normal int, which is always a safe int.
   int temp_int;
   bool temp_has_value;
-  if (GetOptionalValue(dict, path, &temp_int, &temp_has_value,
-                       &base::Value::GetAsInteger)) {
+  if (GetOptionalValueDeprecated(dict, path, &temp_int, &temp_has_value,
+                                 &base::Value::GetAsInteger)) {
     if (has_value != nullptr)
       *has_value = temp_has_value;
     if (temp_has_value)
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 9682fecf..ef53759 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -861,15 +861,15 @@
         "      XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;"
         "}";
     std::string xpath = "(/html/body//iframe|/html/frameset//frame)";
-    std::string id_string;
-    int id_int;
-    if (id->GetAsString(&id_string)) {
+    if (id->is_string()) {
+      std::string id_string = id->GetString();
       if (session->w3c_compliant)
         return Status(kInvalidArgument, "'id' can not be string");
       else
         xpath += base::StringPrintf(
           "[@name=\"%s\" or @id=\"%s\"]", id_string.c_str(), id_string.c_str());
-    } else if (id->GetAsInteger(&id_int)) {
+    } else if (id->is_int()) {
+      int id_int = id->GetInt();
       const int max_range = 65535; // 2^16 - 1
       if (id_int < 0 || id_int > max_range)
         return Status(kInvalidArgument, "'id' out of range");
@@ -2603,30 +2603,37 @@
 
   bool has_x = params.Get("x", &temp) && !temp->is_none();
   if (has_x) {
-    if (!temp->GetAsDouble(&x))
+    if (!temp->is_double() && !temp->is_int())
       return Status(kInvalidArgument, "'x' must be a number");
+    x = temp->GetDouble();
     if (x > max_range || x < min_range)
       return Status(kInvalidArgument, "'x' out of range");
   }
+
   bool has_y = params.Get("y", &temp) && !temp->is_none();
   if (has_y) {
-    if (!temp->GetAsDouble(&y))
+    if (!temp->is_double() && !temp->is_int())
       return Status(kInvalidArgument, "'y' must be a number");
-    if (y > max_range || y < min_range )
+    y = temp->GetDouble();
+    if (y > max_range || y < min_range)
       return Status(kInvalidArgument, "'y' out of range");
   }
+
   bool has_width = params.Get("width", &temp) && !temp->is_none();
   if (has_width) {
-    if (!temp->GetAsDouble(&width))
+    if (!temp->is_double() && !temp->is_int())
       return Status(kInvalidArgument, "'width' must be a number");
-    if (width > max_range || width < 0 )
+    width = temp->GetDouble();
+    if (width > max_range || width < 0)
       return Status(kInvalidArgument, "'width' out of range");
   }
+
   bool has_height = params.Get("height", &temp) && !temp->is_none();
   if (has_height) {
-    if (!temp->GetAsDouble(&height))
+    if (!temp->is_double() && !temp->is_int())
       return Status(kInvalidArgument, "'height' must be a number");
-    if (height > max_range || height < 0 )
+    height = temp->GetDouble();
+    if (height > max_range || height < 0)
       return Status(kInvalidArgument, "'height' out of range");
   }
 
diff --git a/chrome/test/data/extensions/back_forward_cache/active_tab/background.js b/chrome/test/data/extensions/back_forward_cache/active_tab/background.js
new file mode 100644
index 0000000..96d4b44
--- /dev/null
+++ b/chrome/test/data/extensions/back_forward_cache/active_tab/background.js
@@ -0,0 +1,3 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
diff --git a/chrome/test/data/extensions/back_forward_cache/active_tab/manifest.json b/chrome/test/data/extensions/back_forward_cache/active_tab/manifest.json
new file mode 100644
index 0000000..d6bf2bc0
--- /dev/null
+++ b/chrome/test/data/extensions/back_forward_cache/active_tab/manifest.json
@@ -0,0 +1,13 @@
+{
+  "name": "bfcache test activetab",
+  "version": "0.1",
+  "manifest_version": 2,
+  "description": "Checks that activeTab permission plays nice with back forward cache.",
+  "permissions": ["activeTab"],
+  "background": {
+    "scripts": ["background.js"]
+  },
+  "browser_action": {
+    "default_title": "activeTab test"
+  }
+}
diff --git a/chrome/test/data/extensions/back_forward_cache/correct_origin/background.js b/chrome/test/data/extensions/back_forward_cache/correct_origin/background.js
new file mode 100644
index 0000000..96d4b44
--- /dev/null
+++ b/chrome/test/data/extensions/back_forward_cache/correct_origin/background.js
@@ -0,0 +1,3 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
diff --git a/chrome/test/data/extensions/back_forward_cache/correct_origin/manifest.json b/chrome/test/data/extensions/back_forward_cache/correct_origin/manifest.json
new file mode 100644
index 0000000..b7ee9fd
--- /dev/null
+++ b/chrome/test/data/extensions/back_forward_cache/correct_origin/manifest.json
@@ -0,0 +1,11 @@
+{
+  "name": "no caching",
+  "version": "0.1",
+  "manifest_version": 2,
+  "description": "Checks that extension permission is scoped to correct origin even in presence of the back forward cache.",
+  "permissions": ["http://a.com/*"],
+  "background": {
+    "scripts": ["background.js"],
+    "persistent": false
+  }
+}
diff --git a/chrome/test/data/iframe_blob.html b/chrome/test/data/iframe_blob.html
new file mode 100644
index 0000000..390c18f47
--- /dev/null
+++ b/chrome/test/data/iframe_blob.html
@@ -0,0 +1,10 @@
+<html><head><title>Blob iframe test</title></head>
+<body>
+<script>
+  let f = document.createElement("iframe");
+  f.name = "blob_iframe";
+  document.body.appendChild(f);
+  let blob = new Blob(['foo'], {type : 'text/html'});
+  f.src = URL.createObjectURL(blob);
+</script>
+</body></html>
diff --git a/chrome/test/data/iframe_srcdoc.html b/chrome/test/data/iframe_srcdoc.html
new file mode 100644
index 0000000..a9a9c59
--- /dev/null
+++ b/chrome/test/data/iframe_srcdoc.html
@@ -0,0 +1,4 @@
+<html><head><title>Srcdoc iframe test</title></head>
+<body>
+<iframe srcdoc="<p>Hello World!</p>" name="srcdoc_iframe"></iframe>
+</body></html>
diff --git a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
index d6ce1c5..87a18a6 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/system_page_test.js
@@ -289,11 +289,11 @@
     let routineSection;
     /** @type {!Array<!RoutineType>} */
     const routines = [
-      chromeos.diagnostics.mojom.RoutineType.kCpuCache,
+      ash.diagnostics.mojom.RoutineType.kCpuCache,
     ];
     routineController.setFakeStandardRoutineResult(
-        chromeos.diagnostics.mojom.RoutineType.kCpuCache,
-        chromeos.diagnostics.mojom.StandardRoutineResult.kTestPassed);
+        ash.diagnostics.mojom.RoutineType.kCpuCache,
+        ash.diagnostics.mojom.StandardRoutineResult.kTestPassed);
     return initializeSystemPage(
                fakeSystemInfo, fakeBatteryChargeStatus, fakeBatteryHealth,
                fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage)
diff --git a/chrome/test/data/webui/cr_components/most_visited_focus_test.js b/chrome/test/data/webui/cr_components/most_visited_focus_test.js
index 77bfebf..668ccc7 100644
--- a/chrome/test/data/webui/cr_components/most_visited_focus_test.js
+++ b/chrome/test/data/webui/cr_components/most_visited_focus_test.js
@@ -40,7 +40,6 @@
         url: {url: `https://${char}/`},
         source: i,
         titleSource: i,
-        dataGenerationTime: {internalValue: 0},
       };
     });
     const tilesRendered = eventToPromise('dom-change', mostVisited.$.tiles);
diff --git a/chrome/test/data/webui/cr_components/most_visited_test.js b/chrome/test/data/webui/cr_components/most_visited_test.js
index 4eeb61b42..ff99921 100644
--- a/chrome/test/data/webui/cr_components/most_visited_test.js
+++ b/chrome/test/data/webui/cr_components/most_visited_test.js
@@ -83,7 +83,6 @@
       source: i,
       titleSource: i,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     };
   });
   const tilesRendered = eventToPromise('dom-change', mostVisited.$.tiles);
@@ -419,7 +418,6 @@
       source: 0,
       titleSource: 0,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     });
     assertDeepEquals(tiles[1], {
       title: 'b',
@@ -428,7 +426,6 @@
       source: 1,
       titleSource: 1,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     });
   });
 
@@ -453,7 +450,6 @@
       source: 0,
       titleSource: 0,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     });
   });
 
@@ -799,7 +795,6 @@
       source: 0,
       titleSource: 0,
       isQueryTile: true,
-      dataGenerationTime: {internalValue: BigInt(0)},
     }]);
     const actionMenuButton = queryTiles()[0].querySelector('#actionMenuButton');
     assertFalse(actionMenu.open);
@@ -837,7 +832,6 @@
           source: 0,
           titleSource: 0,
           isQueryTile: true,
-          dataGenerationTime: {internalValue: BigInt(0)},
         }],
         /* customLinksEnabled */ false);
     const removeButton = queryTiles()[0].querySelector('#removeButton');
@@ -1051,7 +1045,6 @@
       source: 0,
       titleSource: 0,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     }]);
     const [tile] = queryTiles();
     const titleElement = tile.querySelector('.tile-title');
@@ -1066,7 +1059,6 @@
       source: 0,
       titleSource: 0,
       isQueryTile: false,
-      dataGenerationTime: {internalValue: BigInt(0)},
     }]);
     const [tile] = queryTiles();
     const titleElement = tile.querySelector('.tile-title');
diff --git a/chrome/test/data/webui/new_tab_page/customize_modules_test.js b/chrome/test/data/webui/new_tab_page/customize_modules_test.js
index b0f5de89..969336a 100644
--- a/chrome/test/data/webui/new_tab_page/customize_modules_test.js
+++ b/chrome/test/data/webui/new_tab_page/customize_modules_test.js
@@ -289,4 +289,48 @@
     assertFalse(toggleRows[0].querySelector('cr-toggle').checked);
     assertFalse(isVisible(subToggleRows[0]));
   });
+
+  test('record disable discount', async () => {
+    // Arrange.
+    loadTimeData.overrideValues({ruleBasedDiscountEnabled: true});
+    cartTestProxy.handler.setResultFor(
+        'getDiscountEnabled', Promise.resolve({enabled: true}));
+    const customizeModules = await createCustomizeModules(false, [
+      {id: 'chrome_cart', name: 'foo name', disabled: false},
+    ]);
+    const subToggleRows = queryAll(customizeModules, '.discount-toggle-row');
+
+    assertEquals(0, metrics.count('NewTabPage.Carts.DisableDiscount'));
+
+    // Act.
+    subToggleRows[0].querySelector('cr-toggle').click();
+    customizeModules.apply();
+
+    // Assert.
+    assertDeepEquals(
+        false, cartTestProxy.handler.getArgs('setDiscountEnabled')[0]);
+    assertEquals(1, metrics.count('NewTabPage.Carts.DisableDiscount'));
+  });
+
+  test('record enable discount', async () => {
+    // Arrange.
+    loadTimeData.overrideValues({ruleBasedDiscountEnabled: true});
+    cartTestProxy.handler.setResultFor(
+        'getDiscountEnabled', Promise.resolve({enabled: false}));
+    const customizeModules = await createCustomizeModules(false, [
+      {id: 'chrome_cart', name: 'foo name', disabled: false},
+    ]);
+    const subToggleRows = queryAll(customizeModules, '.discount-toggle-row');
+
+    assertEquals(0, metrics.count('NewTabPage.Carts.DisableDiscount'));
+
+    // Act.
+    subToggleRows[0].querySelector('cr-toggle').click();
+    customizeModules.apply();
+
+    // Assert.
+    assertDeepEquals(
+        true, cartTestProxy.handler.getArgs('setDiscountEnabled')[0]);
+    assertEquals(1, metrics.count('NewTabPage.Carts.EnableDiscount'));
+  });
 });
diff --git a/chrome/test/data/webui/new_tab_page/modules/cart/module_test.js b/chrome/test/data/webui/new_tab_page/modules/cart/module_test.js
index f329893..717672aa 100644
--- a/chrome/test/data/webui/new_tab_page/modules/cart/module_test.js
+++ b/chrome/test/data/webui/new_tab_page/modules/cart/module_test.js
@@ -714,6 +714,7 @@
       assertEquals(
           loadTimeData.getString('modulesCartDiscountConsentAccept'),
           consentCard.querySelector('#actionButton').innerText);
+      assertEquals(0, metrics.count('NewTabPage.Carts.RejectDiscountConsent'));
 
       // Act.
       consentCard.querySelector('#cancelButton').click();
@@ -726,6 +727,7 @@
           'Reject confirmation!',
           consentToast.querySelector('#confirmDiscountConsentMessage')
               .innerText);
+      assertEquals(1, metrics.count('NewTabPage.Carts.RejectDiscountConsent'));
 
       // Act.
       consentToast.querySelector('#confirmDiscountConsentButton').click();
@@ -740,6 +742,7 @@
 
       // Assert.
       assertEquals(true, isVisible(consentCard));
+      assertEquals(0, metrics.count('NewTabPage.Carts.AcceptDiscountConsent'));
 
       // Act.
       consentCard.querySelector('#actionButton').click();
@@ -759,6 +762,7 @@
       // Assert.
       assertEquals(false, consentToast.open);
       assertEquals(false, isVisible(consentCard));
+      assertEquals(1, metrics.count('NewTabPage.Carts.AcceptDiscountConsent'));
     });
 
     test('scroll with consent card', async () => {
@@ -1024,5 +1028,66 @@
           'https://www.foo.com/',
           moduleElement.shadowRoot.querySelectorAll('.cart-item')[index].href);
     }
+
+    test('record discount consent show', async () => {
+      // Arrange.
+      const carts = [
+        {
+          merchant: 'Foo',
+          cartUrl: {url: 'https://foo.com'},
+          productImageUrls: [],
+        },
+      ];
+      testProxy.handler.setResultFor(
+          'getMerchantCarts', Promise.resolve({carts}));
+      testProxy.handler.setResultFor(
+          'getDiscountConsentCardVisible',
+          Promise.resolve({consentVisible: true}));
+
+      assertEquals(0, metrics.count('NewTabPage.Carts.DiscountConsentShow', 1));
+
+      // Act.
+      const moduleElement = await chromeCartDescriptor.initialize();
+
+      // Assert.
+      assertEquals(1, metrics.count('NewTabPage.Carts.DiscountConsentShow', 1));
+    });
+
+    test('record discount carts count and index', async () => {
+      // Arrange.
+      const carts = [
+        {
+          merchant: 'Boo',
+          cartUrl: {url: 'https://Boo.com'},
+          productImageUrls: [],
+          discountText: '5% off'
+        },
+        {
+          merchant: 'Foo',
+          cartUrl: {url: 'https://foo.com'},
+          productImageUrls: [],
+        },
+        {
+          merchant: 'Koo',
+          cartUrl: {url: 'https://Koo.com'},
+          productImageUrls: [],
+          discountText: '10% off'
+        },
+      ];
+      testProxy.handler.setResultFor(
+          'getMerchantCarts', Promise.resolve({carts}));
+
+      assertEquals(0, metrics.count('NewTabPage.Carts.DiscountCountAtLoad', 2));
+      assertEquals(0, metrics.count('NewTabPage.Carts.DiscountAt', 0));
+      assertEquals(0, metrics.count('NewTabPage.Carts.DiscountAt', 2));
+
+      // Act.
+      const moduleElement = await chromeCartDescriptor.initialize();
+
+      // Assert.
+      assertEquals(1, metrics.count('NewTabPage.Carts.DiscountCountAtLoad', 2));
+      assertEquals(1, metrics.count('NewTabPage.Carts.DiscountAt', 0));
+      assertEquals(1, metrics.count('NewTabPage.Carts.DiscountAt', 2));
+    });
   });
 });
diff --git a/chrome/test/data/webui/settings/chooser_exception_list_entry_tests.js b/chrome/test/data/webui/settings/chooser_exception_list_entry_tests.js
index 6bbaa7f..4ea0cae 100644
--- a/chrome/test/data/webui/settings/chooser_exception_list_entry_tests.js
+++ b/chrome/test/data/webui/settings/chooser_exception_list_entry_tests.js
@@ -73,21 +73,25 @@
         // Flush the container to ensure that the container is populated.
         flush();
 
-        const siteListEntry = testElement.$$('site-list-entry');
+        const siteListEntry =
+            testElement.shadowRoot.querySelector('site-list-entry');
         assertTrue(!!siteListEntry);
 
         // Ensure that the action menu button container is hidden.
-        const dotsMenu = siteListEntry.$$('#actionMenuButton');
+        const dotsMenu =
+            siteListEntry.shadowRoot.querySelector('#actionMenuButton');
         assertTrue(!!dotsMenu);
         assertTrue(dotsMenu.hidden);
 
         // Ensure that the reset button is not hidden.
-        const resetButton = siteListEntry.$$('#resetSite');
+        const resetButton =
+            siteListEntry.shadowRoot.querySelector('#resetSite');
         assertTrue(!!resetButton);
         assertFalse(resetButton.hidden);
 
         // Ensure that the policy enforced indicator is hidden.
-        const policyIndicator = siteListEntry.$$('cr-policy-pref-indicator');
+        const policyIndicator =
+            siteListEntry.shadowRoot.querySelector('cr-policy-pref-indicator');
         assertFalse(!!policyIndicator);
       });
 
@@ -106,21 +110,25 @@
         // Flush the container to ensure that the container is populated.
         flush();
 
-        const siteListEntry = testElement.$$('site-list-entry');
+        const siteListEntry =
+            testElement.shadowRoot.querySelector('site-list-entry');
         assertTrue(!!siteListEntry);
 
         // Ensure that the action menu button container is hidden.
-        const dotsMenu = siteListEntry.$$('#actionMenuButton');
+        const dotsMenu =
+            siteListEntry.shadowRoot.querySelector('#actionMenuButton');
         assertTrue(!!dotsMenu);
         assertTrue(dotsMenu.hidden);
 
         // Ensure that the reset button is hidden.
-        const resetButton = siteListEntry.$$('#resetSite');
+        const resetButton =
+            siteListEntry.shadowRoot.querySelector('#resetSite');
         assertTrue(!!resetButton);
         assertTrue(resetButton.hidden);
 
         // Ensure that the policy enforced indicator is not hidden.
-        const policyIndicator = siteListEntry.$$('cr-policy-pref-indicator');
+        const policyIndicator =
+            siteListEntry.shadowRoot.querySelector('cr-policy-pref-indicator');
         assertTrue(!!policyIndicator);
       });
 
@@ -147,29 +155,35 @@
         assertEquals(siteListEntries.length, 2);
 
         // The first entry should be policy enforced.
-        const firstDotsMenu = siteListEntries[0].$$('#actionMenuButton');
+        const firstDotsMenu =
+            siteListEntries[0].shadowRoot.querySelector('#actionMenuButton');
         assertTrue(!!firstDotsMenu);
         assertTrue(firstDotsMenu.hidden);
 
-        const firstResetButton = siteListEntries[0].$$('#resetSite');
+        const firstResetButton =
+            siteListEntries[0].shadowRoot.querySelector('#resetSite');
         assertTrue(!!firstResetButton);
         assertTrue(firstResetButton.hidden);
 
         const firstPolicyIndicator =
-            siteListEntries[0].$$('cr-policy-pref-indicator');
+            siteListEntries[0].shadowRoot.querySelector(
+                'cr-policy-pref-indicator');
         assertTrue(!!firstPolicyIndicator);
 
         // The second entry should be user granted.
-        const secondDotsMenu = siteListEntries[1].$$('#actionMenuButton');
+        const secondDotsMenu =
+            siteListEntries[1].shadowRoot.querySelector('#actionMenuButton');
         assertTrue(!!secondDotsMenu);
         assertTrue(secondDotsMenu.hidden);
 
-        const secondResetButton = siteListEntries[1].$$('#resetSite');
+        const secondResetButton =
+            siteListEntries[1].shadowRoot.querySelector('#resetSite');
         assertTrue(!!secondResetButton);
         assertFalse(secondResetButton.hidden);
 
         const secondPolicyIndicator =
-            siteListEntries[1].$$('cr-policy-pref-indicator');
+            siteListEntries[1].shadowRoot.querySelector(
+                'cr-policy-pref-indicator');
         assertFalse(!!secondPolicyIndicator);
       });
 
@@ -187,16 +201,19 @@
         // Flush the container to ensure that the container is populated.
         flush();
 
-        const siteListEntry = testElement.$$('site-list-entry');
+        const siteListEntry =
+            testElement.shadowRoot.querySelector('site-list-entry');
         assertTrue(!!siteListEntry);
 
-        const policyIndicator = siteListEntry.$$('cr-policy-pref-indicator');
+        const policyIndicator =
+            siteListEntry.shadowRoot.querySelector('cr-policy-pref-indicator');
         assertTrue(!!policyIndicator);
 
-        const icon = policyIndicator.$$('cr-tooltip-icon');
+        const icon =
+            policyIndicator.shadowRoot.querySelector('cr-tooltip-icon');
         assertTrue(!!icon);
 
-        const paperTooltip = icon.$$('paper-tooltip');
+        const paperTooltip = icon.shadowRoot.querySelector('paper-tooltip');
         assertTrue(!!paperTooltip);
 
         // This tooltip is never shown since a common tooltip will be used.
@@ -226,16 +243,19 @@
         // Flush the container to ensure that the container is populated.
         flush();
 
-        const siteListEntry = testElement.$$('site-list-entry');
+        const siteListEntry =
+            testElement.shadowRoot.querySelector('site-list-entry');
         assertTrue(!!siteListEntry);
 
         // Ensure that the action menu button is hidden.
-        const dotsMenu = siteListEntry.$$('#actionMenuButton');
+        const dotsMenu =
+            siteListEntry.shadowRoot.querySelector('#actionMenuButton');
         assertTrue(!!dotsMenu);
         assertTrue(dotsMenu.hidden);
 
         // Ensure that the reset button is not hidden.
-        const resetButton = siteListEntry.$$('#resetSite');
+        const resetButton =
+            siteListEntry.shadowRoot.querySelector('#resetSite');
         assertTrue(!!resetButton);
         assertFalse(resetButton.hidden);
 
diff --git a/chrome/test/data/webui/settings/chooser_exception_list_tests.js b/chrome/test/data/webui/settings/chooser_exception_list_tests.js
index 33df91d0..7bcc49c 100644
--- a/chrome/test/data/webui/settings/chooser_exception_list_tests.js
+++ b/chrome/test/data/webui/settings/chooser_exception_list_tests.js
@@ -214,26 +214,30 @@
               flush();
 
               const chooserExceptionListEntry =
-                  testElement.$$('chooser-exception-list-entry');
+                  testElement.shadowRoot.querySelector(
+                      'chooser-exception-list-entry');
               assertTrue(!!chooserExceptionListEntry);
 
               const siteListEntry =
-                  chooserExceptionListEntry.$$('site-list-entry');
+                  chooserExceptionListEntry.shadowRoot.querySelector(
+                      'site-list-entry');
               assertTrue(!!siteListEntry);
 
               // Ensure that the action menu container is hidden.
-              const dotsMenu = siteListEntry.$$('#actionMenuButton');
+              const dotsMenu =
+                  siteListEntry.shadowRoot.querySelector('#actionMenuButton');
               assertTrue(!!dotsMenu);
               assertTrue(dotsMenu.hidden);
 
               // Ensure that the reset button is not hidden.
-              const resetButton = siteListEntry.$$('#resetSite');
+              const resetButton =
+                  siteListEntry.shadowRoot.querySelector('#resetSite');
               assertTrue(!!resetButton);
               assertFalse(resetButton.hidden);
 
               // Ensure that the policy enforced indicator is hidden.
-              const policyIndicator =
-                  siteListEntry.$$('cr-policy-pref-indicator');
+              const policyIndicator = siteListEntry.shadowRoot.querySelector(
+                  'cr-policy-pref-indicator');
               assertFalse(!!policyIndicator);
             });
       });
@@ -252,26 +256,30 @@
               flush();
 
               const chooserExceptionListEntry =
-                  testElement.$$('chooser-exception-list-entry');
+                  testElement.shadowRoot.querySelector(
+                      'chooser-exception-list-entry');
               assertTrue(!!chooserExceptionListEntry);
 
               const siteListEntry =
-                  chooserExceptionListEntry.$$('site-list-entry');
+                  chooserExceptionListEntry.shadowRoot.querySelector(
+                      'site-list-entry');
               assertTrue(!!siteListEntry);
 
               // Ensure that the action menu container is hidden.
-              const dotsMenu = siteListEntry.$$('#actionMenuButton');
+              const dotsMenu =
+                  siteListEntry.shadowRoot.querySelector('#actionMenuButton');
               assertTrue(!!dotsMenu);
               assertTrue(dotsMenu.hidden);
 
               // Ensure that the reset button is hidden.
-              const resetButton = siteListEntry.$$('#resetSite');
+              const resetButton =
+                  siteListEntry.shadowRoot.querySelector('#resetSite');
               assertTrue(!!resetButton);
               assertTrue(resetButton.hidden);
 
               // Ensure that the policy enforced indicator not is hidden.
-              const policyIndicator =
-                  siteListEntry.$$('cr-policy-pref-indicator');
+              const policyIndicator = siteListEntry.shadowRoot.querySelector(
+                  'cr-policy-pref-indicator');
               assertTrue(!!policyIndicator);
             });
       });
@@ -303,33 +311,37 @@
               // The first site exception is a policy provided exception, so
               // only the policy indicator should be visible;
               const policyProvidedDotsMenu =
-                  siteListEntries[0].$$('#actionMenuButton');
+                  siteListEntries[0].shadowRoot.querySelector(
+                      '#actionMenuButton');
               assertTrue(!!policyProvidedDotsMenu);
               assertTrue(policyProvidedDotsMenu.hidden);
 
               const policyProvidedResetButton =
-                  siteListEntries[0].$$('#resetSite');
+                  siteListEntries[0].shadowRoot.querySelector('#resetSite');
               assertTrue(!!policyProvidedResetButton);
               assertTrue(policyProvidedResetButton.hidden);
 
               const policyProvidedPolicyIndicator =
-                  siteListEntries[0].$$('cr-policy-pref-indicator');
+                  siteListEntries[0].shadowRoot.querySelector(
+                      'cr-policy-pref-indicator');
               assertTrue(!!policyProvidedPolicyIndicator);
 
               // The second site exception is a user provided exception, so only
               // the reset button should be visible.
               const userProvidedDotsMenu =
-                  siteListEntries[1].$$('#actionMenuButton');
+                  siteListEntries[1].shadowRoot.querySelector(
+                      '#actionMenuButton');
               assertTrue(!!userProvidedDotsMenu);
               assertTrue(userProvidedDotsMenu.hidden);
 
               const userProvidedResetButton =
-                  siteListEntries[1].$$('#resetSite');
+                  siteListEntries[1].shadowRoot.querySelector('#resetSite');
               assertTrue(!!userProvidedResetButton);
               assertFalse(userProvidedResetButton.hidden);
 
               const userProvidedPolicyIndicator =
-                  siteListEntries[1].$$('cr-policy-pref-indicator');
+                  siteListEntries[1].shadowRoot.querySelector(
+                      'cr-policy-pref-indicator');
               assertFalse(!!userProvidedPolicyIndicator);
             });
       });
@@ -343,7 +355,8 @@
         .then(function(chooserType) {
           assertEquals(ChooserType.USB_DEVICES, chooserType);
           assertEquals(0, testElement.chooserExceptions.length);
-          const emptyListMessage = testElement.$$('#empty-list-message');
+          const emptyListMessage =
+              testElement.shadowRoot.querySelector('#empty-list-message');
           assertFalse(emptyListMessage.hidden);
           assertEquals(
               'No USB devices found', emptyListMessage.textContent.trim());
@@ -370,19 +383,24 @@
           flush();
 
           const chooserExceptionListEntry =
-              testElement.$$('chooser-exception-list-entry');
+              testElement.shadowRoot.querySelector(
+                  'chooser-exception-list-entry');
           assertTrue(!!chooserExceptionListEntry);
 
-          const siteListEntry = chooserExceptionListEntry.$$('site-list-entry');
+          const siteListEntry =
+              chooserExceptionListEntry.shadowRoot.querySelector(
+                  'site-list-entry');
           assertTrue(!!siteListEntry);
 
           // Assert that the action button is hidden.
-          const dotsMenu = siteListEntry.$$('#actionMenuButton');
+          const dotsMenu =
+              siteListEntry.shadowRoot.querySelector('#actionMenuButton');
           assertTrue(!!dotsMenu);
           assertTrue(dotsMenu.hidden);
 
           // Assert that the reset button is visible.
-          const resetButton = siteListEntry.$$('#resetSite');
+          const resetButton =
+              siteListEntry.shadowRoot.querySelector('#resetSite');
           assertTrue(!!resetButton);
           assertFalse(resetButton.hidden);
 
@@ -420,11 +438,13 @@
               flush();
 
               const chooserExceptionListEntry =
-                  testElement.$$('chooser-exception-list-entry');
+                  testElement.shadowRoot.querySelector(
+                      'chooser-exception-list-entry');
               assertTrue(!!chooserExceptionListEntry);
 
               const siteListEntry =
-                  chooserExceptionListEntry.$$('site-list-entry');
+                  chooserExceptionListEntry.shadowRoot.querySelector(
+                      'site-list-entry');
               assertTrue(!!siteListEntry);
 
               const tooltip = testElement.$.tooltip;
@@ -516,14 +536,17 @@
               flush();
 
               const chooserExceptionListEntry =
-                  testElement.$$('chooser-exception-list-entry');
+                  testElement.shadowRoot.querySelector(
+                      'chooser-exception-list-entry');
               assertTrue(!!chooserExceptionListEntry);
 
               const siteListEntry =
-                  chooserExceptionListEntry.$$('site-list-entry');
+                  chooserExceptionListEntry.shadowRoot.querySelector(
+                      'site-list-entry');
               assertTrue(!!siteListEntry);
               // Ensure that the incognito tooltip is hidden.
-              const incognitoTooltip = siteListEntry.$$('#incognitoTooltip');
+              const incognitoTooltip =
+                  siteListEntry.shadowRoot.querySelector('#incognitoTooltip');
               assertFalse(!!incognitoTooltip);
 
               // Simulate an incognito session being created.
@@ -536,7 +559,8 @@
               flush();
 
               const chooserExceptionListEntry =
-                  testElement.$$('chooser-exception-list-entry');
+                  testElement.shadowRoot.querySelector(
+                      'chooser-exception-list-entry');
               assertTrue(!!chooserExceptionListEntry);
               assertTrue(chooserExceptionListEntry.$.listContainer
                              .querySelector('iron-list')
@@ -559,7 +583,8 @@
               Array.from(siteListEntries)
                   .filter(entry => entry.model.incognito)
                   .forEach(entry => {
-                    const incognitoTooltip = entry.$$('#incognitoTooltip');
+                    const incognitoTooltip =
+                        entry.shadowRoot.querySelector('#incognitoTooltip');
                     // Make sure it is not hidden if it is an incognito
                     // exception
                     assertTrue(!!incognitoTooltip);
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index 34b576cd..067201dc 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -42,6 +42,7 @@
     "app_management/app_management_page_tests.js",
     "app_management/chrome_app_detail_view_test.js",
     "app_management/arc_detail_view_test.js",
+    "app_management/borealis_detail_view_test.js",
     "app_management/dom_switch_test.js",
     "app_management/main_view_test.js",
     "app_management/pwa_detail_view_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js
new file mode 100644
index 0000000..7ab59da3
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/app_management/borealis_detail_view_test.js
@@ -0,0 +1,114 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// clang-format off
+// #import 'chrome://os-settings/chromeos/os_settings.js';
+
+// #import {BorealisPermissionType, createPermission, PermissionValueType, Bool, AppManagementStore, updateSelectedAppId, getPermissionValueBool, convertOptionalBoolToBool} from 'chrome://os-settings/chromeos/os_settings.js';
+// #import {setupFakeHandler, replaceStore, replaceBody, getPermissionCrToggleByType, getPermissionToggleByType} from './test_util.m.js';
+// clang-format on
+
+'use strict';
+
+suite('<app-management-borealis-detail-view>', function() {
+  let BorealisDetailView;
+  let fakeHandler;
+
+  const kBorealisMainAppId = 'epfhbkiklgmlkhfpbcdleadnhcfdjfmo';
+
+  function getPermissionBoolByType(permissionType) {
+    return app_management.util.getPermissionValueBool(
+        BorealisDetailView.app_, permissionType);
+  }
+
+  async function clickToggle(permissionType) {
+    getPermissionToggleByType(BorealisDetailView, permissionType).click();
+    await fakeHandler.flushPipesForTesting();
+  }
+
+  function getSelectedAppFromStore() {
+    const storeData = app_management.AppManagementStore.getInstance().data;
+    return storeData.apps[storeData.selectedAppId];
+  }
+
+  setup(async function() {
+    fakeHandler = setupFakeHandler();
+    replaceStore();
+
+    const permissions = {};
+    const permissionIds = [BorealisPermissionType.MICROPHONE];
+    for (const permissionId of permissionIds) {
+      permissions[permissionId] = app_management.util.createPermission(
+          permissionId, PermissionValueType.kBool, Bool.kTrue,
+          false /*is_managed*/);
+    }
+
+    // Add an app, and make it the currently selected app.
+    const options = {
+      type: apps.mojom.AppType.kBorealis,
+      permissions: permissions
+    };
+    const app = await fakeHandler.addApp(kBorealisMainAppId, options);
+    app_management.AppManagementStore.getInstance().dispatch(
+        app_management.actions.updateSelectedAppId(app.id));
+
+    BorealisDetailView =
+        document.createElement('app-management-borealis-detail-view');
+    replaceBody(BorealisDetailView);
+  });
+
+  test('App is rendered correctly', function() {
+    assertEquals(
+        app_management.AppManagementStore.getInstance().data.selectedAppId,
+        BorealisDetailView.app_.id);
+  });
+
+  test('Toggle permissions', async function() {
+    const checkToggle = async (permissionType) => {
+      assertTrue(getPermissionBoolByType(permissionType));
+      assertTrue(getPermissionCrToggleByType(BorealisDetailView, permissionType)
+                     .checked);
+
+      // Toggle off.
+      await clickToggle(permissionType);
+      assertFalse(getPermissionBoolByType(permissionType));
+      assertFalse(
+          getPermissionCrToggleByType(BorealisDetailView, permissionType)
+              .checked);
+
+      // Toggle on.
+      await clickToggle(permissionType);
+      assertTrue(getPermissionBoolByType(permissionType));
+      assertTrue(getPermissionCrToggleByType(BorealisDetailView, permissionType)
+                     .checked);
+    };
+
+    await checkToggle('MICROPHONE');
+  });
+
+  test('Pin to shelf toggle', async function() {
+    const pinToShelfItem = BorealisDetailView.$['pin-to-shelf-setting'];
+    const toggle = pinToShelfItem.$['toggle-row'].$.toggle;
+
+    assertFalse(toggle.checked);
+    assertEquals(
+        toggle.checked,
+        app_management.util.convertOptionalBoolToBool(
+            getSelectedAppFromStore().isPinned));
+    pinToShelfItem.click();
+    await fakeHandler.flushPipesForTesting();
+    assertTrue(toggle.checked);
+    assertEquals(
+        toggle.checked,
+        app_management.util.convertOptionalBoolToBool(
+            getSelectedAppFromStore().isPinned));
+    pinToShelfItem.click();
+    await fakeHandler.flushPipesForTesting();
+    assertFalse(toggle.checked);
+    assertEquals(
+        toggle.checked,
+        app_management.util.convertOptionalBoolToBool(
+            getSelectedAppFromStore().isPinned));
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
index 9785f72..83d062cb 100644
--- a/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
+++ b/chrome/test/data/webui/settings/chromeos/app_management/supported_links_item_test.js
@@ -130,6 +130,36 @@
     fakeHandler.flushPipesForTesting();
     test_util.flushTasks();
 
-    assertFalse(!!supportedLinksItem.$$('app-management-supported-links-item'));
+    assertFalse(!!supportedLinksItem.$$('permission-section-header'));
+    assertFalse(!!supportedLinksItem.$$('list-frame'));
+  });
+
+  test('Window/tab mode', async function() {
+    const options = {
+      type: apps.mojom.AppType.kWeb,
+      isPreferredApp: true,
+      windowMode: apps.mojom.WindowMode.kBrowser,
+      supportedLinks: ['google.com'],
+    };
+
+    // Add PWA app, and make it the currently selected app.
+    const app = await fakeHandler.addApp('app1', options);
+
+    app_management.AppManagementStore.getInstance().dispatch(
+        app_management.actions.updateSelectedAppId(app.id));
+
+    await fakeHandler.flushPipesForTesting();
+
+    assertTrue(
+        !!app_management.AppManagementStore.getInstance().data.apps[app.id]);
+
+    supportedLinksItem.app = app;
+
+    replaceBody(supportedLinksItem);
+    fakeHandler.flushPipesForTesting();
+    test_util.flushTasks();
+
+    assertTrue(!!supportedLinksItem.$$('#tabModeText'));
+    assertTrue(!!supportedLinksItem.$$('#isSupportedRadioGroup').disabled);
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
index 98443e3..8009299 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -276,6 +276,7 @@
  ['AppManagementAppDetailView', 'app_detail_view_test.m.js'],
  ['AppManagementAppItem', 'app_item_test.m.js'],
  ['AppManagementArcDetailView', 'arc_detail_view_test.m.js'],
+ ['AppManagementBorealisDetailView', 'borealis_detail_view_test.m.js'],
  ['AppManagementChromeAppDetailView', 'chrome_app_detail_view_test.m.js'],
  ['AppManagementDomSwitch', 'dom_switch_test.m.js'],
  ['AppManagementMainView', 'main_view_test.m.js'],
@@ -321,7 +322,8 @@
  ['KeyboardShortcutBanner', 'keyboard_shortcut_banner_test.m.js'],
  ['LocalizedLink', 'localized_link_test.m.js'],
  ['ManageAccessibilityPage', 'manage_accessibility_page_tests.m.js'],
- ['MultideviceFeatureItem', 'multidevice_feature_item_tests.m.js'],
+ // TODO(crbug.com/1227116): Re-enable once flakiness is fixed.
+ //  ['MultideviceFeatureItem', 'multidevice_feature_item_tests.m.js'],
  ['MultideviceFeatureToggle', 'multidevice_feature_toggle_tests.m.js'],
  [
    'MultideviceNotificationAccessSetupDialog',
diff --git a/chrome/test/data/webui/settings/cookies_page_test.js b/chrome/test/data/webui/settings/cookies_page_test.js
index 1b493c58..80eddae8 100644
--- a/chrome/test/data/webui/settings/cookies_page_test.js
+++ b/chrome/test/data/webui/settings/cookies_page_test.js
@@ -5,7 +5,7 @@
 // clang-format off
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {ContentSetting, ContentSettingsTypes, CookieControlsMode, SettingsCookiesPageElement, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
+import {ContentSetting, ContentSettingsTypes, CookieControlsMode, SettingsCookiesPageElement, SiteListElement, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
 import {MetricsBrowserProxyImpl, PrivacyElementInteractions, Router, routes} from 'chrome://settings/settings.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 1abb1b9..ccd5c1e3 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -120,6 +120,10 @@
   }
 };
 
+TEST_F('CrSettingsLanguagesPageV3Test', 'LanguageSettings', function() {
+  mocha.grep(languages_page_tests.TestNames.LanguageSettings).run();
+});
+
 TEST_F('CrSettingsLanguagesPageV3Test', 'Spellcheck', function() {
   mocha.grep(languages_page_tests.TestNames.Spellcheck).run();
 });
diff --git a/chrome/test/data/webui/settings/languages_page_tests.js b/chrome/test/data/webui/settings/languages_page_tests.js
index 92e6bc6..783ef71d 100644
--- a/chrome/test/data/webui/settings/languages_page_tests.js
+++ b/chrome/test/data/webui/settings/languages_page_tests.js
@@ -18,6 +18,7 @@
 
 /** @enum {string} */
 window.languages_page_tests.TestNames = {
+  LanguageSettings: 'language_settings',
   Spellcheck: 'spellcheck_all',
   SpellcheckOfficialBuild: 'spellcheck_official',
   ChromeOSLanguagesSettingsUpdate: 'chromeos settings update',
@@ -87,6 +88,20 @@
     PolymerTest.clearBody();
   });
 
+  suite(languages_page_tests.TestNames.LanguageSettings, function() {
+    test('decoupled language subtitle', function() {
+      const secondaryText = languagesPage.shadowRoot.querySelector(
+          '#languageSectionSecondaryText');
+      if (isChromeOS || isWindows) {
+        // Set to English from FakeLanguageSettingsPrivate.
+        assertEquals(
+            secondaryText.textContent.trim(), 'English (United States)');
+      } else {
+        assertEquals(secondaryText, null);
+      }
+    });
+  });
+
   suite(languages_page_tests.TestNames.Spellcheck, function() {
     test('structure', function() {
       const spellCheckCollapse =
diff --git a/chrome/test/data/webui/settings/recent_site_permissions_test.js b/chrome/test/data/webui/settings/recent_site_permissions_test.js
index ac9334c..c082bca 100644
--- a/chrome/test/data/webui/settings/recent_site_permissions_test.js
+++ b/chrome/test/data/webui/settings/recent_site_permissions_test.js
@@ -4,7 +4,7 @@
 
 // clang-format off
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {ContentSetting, ContentSettingsTypes, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
+import {ContentSetting, ContentSettingsTypes, SettingsRecentSitePermissionsElement, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
 import {Router, routes} from 'chrome://settings/settings.js';
 
 import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
diff --git a/chrome/test/data/webui/settings/site_list_tests.js b/chrome/test/data/webui/settings/site_list_tests.js
index 848cd2bb..1b8a019 100644
--- a/chrome/test/data/webui/settings/site_list_tests.js
+++ b/chrome/test/data/webui/settings/site_list_tests.js
@@ -8,7 +8,7 @@
 import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {AddSiteDialogElement, ContentSetting, ContentSettingsTypes, kControlledByLookup, SettingsEditExceptionDialogElement, SITE_EXCEPTION_WILDCARD, SiteException, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
+import {AddSiteDialogElement, ContentSetting, ContentSettingsTypes, kControlledByLookup, SettingsEditExceptionDialogElement, SITE_EXCEPTION_WILDCARD, SiteException, SiteListElement, SiteSettingSource, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
 import {CrSettingsPrefs,Router} from 'chrome://settings/settings.js';
 
 import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../chai_assert.js';
@@ -327,12 +327,6 @@
   function setUpCategory(category, subtype, prefs) {
     browserProxy.setPrefs(prefs);
     testElement.categorySubtype = subtype;
-    // Some route is needed, but the actual route doesn't matter.
-    testElement.currentRoute = {
-      page: 'dummy',
-      section: 'privacy',
-      subpage: ['site-settings', 'site-settings-category-location'],
-    };
     testElement.category = category;
   }
 
@@ -459,12 +453,6 @@
   function setUpCategory(category, subtype, prefs) {
     browserProxy.setPrefs(prefs);
     testElement.categorySubtype = subtype;
-    // Some route is needed, but the actual route doesn't matter.
-    testElement.currentRoute = {
-      page: 'dummy',
-      section: 'privacy',
-      subpage: ['site-settings', 'site-settings-category-location'],
-    };
     testElement.category = category;
   }
 
diff --git a/chrome/test/data/webui/settings/site_settings_page_test.js b/chrome/test/data/webui/settings/site_settings_page_test.js
index b749087..15e4ad0 100644
--- a/chrome/test/data/webui/settings/site_settings_page_test.js
+++ b/chrome/test/data/webui/settings/site_settings_page_test.js
@@ -6,7 +6,7 @@
 import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {ContentSetting, defaultSettingLabel, NotificationSetting, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
+import {ContentSetting, defaultSettingLabel, NotificationSetting, SettingsSiteSettingsPageElement, SiteSettingsPrefsBrowserProxyImpl} from 'chrome://settings/lazy_load.js';
 import {CrLinkRowElement} from 'chrome://settings/settings.js';
 
 import {assertEquals, assertTrue} from '../chai_assert.js';
@@ -73,7 +73,8 @@
     await siteSettingsBrowserProxy.whenCalled('getCookieSettingDescription');
     flush();
     const cookiesLinkRow = /** @type {!CrLinkRowElement} */ (
-        page.$$('#basicContentList').$$('#cookies'));
+        page.shadowRoot.querySelector('#basicContentList')
+            .shadowRoot.querySelector('#cookies'));
     assertEquals(testLabels[0], cookiesLinkRow.subLabel);
 
     webUIListenerCallback('cookieSettingDescriptionChanged', testLabels[1]);
@@ -86,7 +87,8 @@
     });
 
     const notificationsLinkRow = /** @type {!CrLinkRowElement} */ (
-        page.$$('#basicPermissionsList').$$('#notifications'));
+        page.shadowRoot.querySelector('#basicPermissionsList')
+            .shadowRoot.querySelector('#notifications'));
 
     page.set('prefs.generated.notification.value', NotificationSetting.BLOCK);
     await flushTasks();
@@ -115,7 +117,8 @@
     });
 
     const notificationsLinkRow = /** @type {!CrLinkRowElement} */ (
-        page.$$('#basicPermissionsList').$$('#notifications'));
+        page.shadowRoot.querySelector('#basicPermissionsList')
+            .shadowRoot.querySelector('#notifications'));
 
     page.set('prefs.generated.notification.value', NotificationSetting.BLOCK);
     await flushTasks();
@@ -140,10 +143,11 @@
 
   test('ProtectedContentRow', function() {
     setupPage();
-    page.$$('#expandContent').click();
+    page.shadowRoot.querySelector('#expandContent').click();
     flush();
     assertTrue(isChildVisible(
-        /** @type {!HTMLElement} */ (page.$$('#advancedContentList')),
+        /** @type {!HTMLElement} */ (
+            page.shadowRoot.querySelector('#advancedContentList')),
         '#protected-content'));
   });
 });
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
index a3beef28..c0dbb55 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
@@ -46,9 +46,9 @@
 #include <stddef.h>
 #include <unicode/uidna.h>
 
+#include "base/cxx17_backports.h"
 #include "base/i18n/number_formatting.h"
 #include "base/lazy_instance.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp b/chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp
index 9e2b58f..ef2bd414 100644
--- a/chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp
@@ -39,7 +39,7 @@
 
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
diff --git a/chrome/tools/build/chromeos/FILES.cfg b/chrome/tools/build/chromeos/FILES.cfg
index b6835bf..6e346a4 100644
--- a/chrome/tools/build/chromeos/FILES.cfg
+++ b/chrome/tools/build/chromeos/FILES.cfg
@@ -26,6 +26,11 @@
 
 FILES = [
   {
+    'filename': 'test_ash_chrome',
+    'buildtype': ['dev'],
+    'optional': ['dev'],
+  },
+  {
     'filename': 'chrome',
     'buildtype': ['dev', 'official'],
   },
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index 4c4a88b..b3f869f5 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -13,6 +13,7 @@
 #include "base/logging.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/task/single_thread_task_executor.h"
+#include "base/threading/platform_thread.h"
 #include "build/build_config.h"
 #include "chrome/updater/app/app.h"
 #include "chrome/updater/app/app_install.h"
diff --git a/chrome/utility/importer/safari_importer_unittest.mm b/chrome/utility/importer/safari_importer_unittest.mm
index 6cf229e..6ca2bed 100644
--- a/chrome/utility/importer/safari_importer_unittest.mm
+++ b/chrome/utility/importer/safari_importer_unittest.mm
@@ -9,11 +9,11 @@
 
 #include <string>
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
-#include "base/stl_util.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
diff --git a/chromecast/browser/webview/webview_browsertest.cc b/chromecast/browser/webview/webview_browsertest.cc
index c97e4a5e..46f8db9 100644
--- a/chromecast/browser/webview/webview_browsertest.cc
+++ b/chromecast/browser/webview/webview_browsertest.cc
@@ -780,7 +780,9 @@
                                            ui::ET_TOUCH_PRESSED, 300, 300));
         SubmitWebviewRequest(&webview, GenerateTouchInputRequest(
                                            ui::ET_TOUCH_RELEASED, 300, 300));
-      });
+      })
+      .WillRepeatedly(
+          [](std::unique_ptr<webview::WebviewResponse> response) {});
 
   auto input_focus_none_check =
       [](const std::unique_ptr<webview::WebviewResponse>& response) {
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc
index ea10192..dd29ac63 100644
--- a/chromecast/common/cast_content_client.cc
+++ b/chromecast/common/cast_content_client.cc
@@ -206,7 +206,7 @@
 
 base::StringPiece CastContentClient::GetDataResource(
     int resource_id,
-    ui::ScaleFactor scale_factor) {
+    ui::ResourceScaleFactor scale_factor) {
   return ui::ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
       resource_id, scale_factor);
 }
diff --git a/chromecast/common/cast_content_client.h b/chromecast/common/cast_content_client.h
index ca62e0f..eca825f 100644
--- a/chromecast/common/cast_content_client.h
+++ b/chromecast/common/cast_content_client.h
@@ -24,8 +24,9 @@
   void SetActiveURL(const GURL& url, std::string top_origin) override;
   void AddAdditionalSchemes(Schemes* schemes) override;
   std::u16string GetLocalizedString(int message_id) override;
-  base::StringPiece GetDataResource(int resource_id,
-                                    ui::ScaleFactor scale_factor) override;
+  base::StringPiece GetDataResource(
+      int resource_id,
+      ui::ResourceScaleFactor scale_factor) override;
   base::RefCountedMemory* GetDataResourceBytes(int resource_id) override;
   gfx::Image& GetNativeImageNamed(int resource_id) override;
 #if defined(OS_ANDROID)
diff --git a/chromecast/common/cast_resource_delegate.cc b/chromecast/common/cast_resource_delegate.cc
index 3dc0afd..e11c092 100644
--- a/chromecast/common/cast_resource_delegate.cc
+++ b/chromecast/common/cast_resource_delegate.cc
@@ -35,7 +35,7 @@
 
 base::FilePath CastResourceDelegate::GetPathForResourcePack(
     const base::FilePath& pack_path,
-    ui::ScaleFactor scale_factor) {
+    ui::ResourceScaleFactor scale_factor) {
   return pack_path;
 }
 
@@ -62,7 +62,7 @@
 
 base::RefCountedStaticMemory* CastResourceDelegate::LoadDataResourceBytes(
     int resource_id,
-    ui::ScaleFactor scale_factor) {
+    ui::ResourceScaleFactor scale_factor) {
   return NULL;
 }
 
@@ -71,9 +71,10 @@
   return absl::nullopt;
 }
 
-bool CastResourceDelegate::GetRawDataResource(int resource_id,
-                                              ui::ScaleFactor scale_factor,
-                                              base::StringPiece* value) const {
+bool CastResourceDelegate::GetRawDataResource(
+    int resource_id,
+    ui::ResourceScaleFactor scale_factor,
+    base::StringPiece* value) const {
   return false;
 }
 
diff --git a/chromecast/common/cast_resource_delegate.h b/chromecast/common/cast_resource_delegate.h
index ccbad02..47fafed3 100644
--- a/chromecast/common/cast_resource_delegate.h
+++ b/chromecast/common/cast_resource_delegate.h
@@ -36,7 +36,7 @@
   // ui:ResourceBundle::Delegate implementation:
   base::FilePath GetPathForResourcePack(
       const base::FilePath& pack_path,
-      ui::ScaleFactor scale_factor) override;
+      ui::ResourceScaleFactor scale_factor) override;
   base::FilePath GetPathForLocalePack(
       const base::FilePath& pack_path,
       const std::string& locale) override;
@@ -44,10 +44,10 @@
   gfx::Image GetNativeImageNamed(int resource_id) override;
   base::RefCountedStaticMemory* LoadDataResourceBytes(
       int resource_id,
-      ui::ScaleFactor scale_factor) override;
+      ui::ResourceScaleFactor scale_factor) override;
   absl::optional<std::string> LoadDataResourceString(int resource_id) override;
   bool GetRawDataResource(int resource_id,
-                          ui::ScaleFactor scale_factor,
+                          ui::ResourceScaleFactor scale_factor,
                           base::StringPiece* value) const override;
   bool GetLocalizedString(int message_id, std::u16string* value) const override;
 
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 0fc3aea..3129064 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -30,7 +30,10 @@
 
 component("chromeos") {
   public_deps = []
-  deps = [ "//chromeos/crosapi/mojom" ]
+  deps = [
+    "//chromeos/crosapi/mojom",
+    "//chromeos/dbus/constants",
+  ]
   sources = []
 
   if (is_chromeos_ash) {
@@ -48,7 +51,6 @@
       "//base",
       "//base:i18n",
       "//chromeos/dbus",
-      "//chromeos/dbus/constants",
       "//google_apis",
       "//services/network/public/cpp:cpp",
       "//third_party/protobuf:protobuf_lite",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index bc42de2..e29e5b8 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-14075.0.0
\ No newline at end of file
+14077.0.0
\ No newline at end of file
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 0ef0bbb..67a500e 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -918,6 +918,10 @@
         Connectivity
       </message>
 
+      <message name="IDS_DIAGNOSTICS_SETTINGS_LINK_TEXT" desc="The text contains a link to the settings page, allowing a user to set up a new connection.">
+        To set up a new connection, go to <ph name="BEGIN_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Settings<ph name="END_LINK">&lt;/a&gt;</ph>.
+      </message>
+
       <message name="IDS_ECHE_APP_DEFAULT_DEVICE_NAME" desc="The default device name used to display on Android endpoint of Eche app.">
         <ph name="GIVEN_NAME">$1<ex>Josh</ex></ph>'s <ph name="DEVICE_TYPE">$2<ex>Chromebook</ex></ph>
       </message>
@@ -1000,7 +1004,7 @@
         Connected
       </message>
       <message name="IDS_ONC_CONNECTING" desc="Settings > Internet, text in network summary when a network is connecting.">
-        Connecting
+        Connecting...
       </message>
       <message name="IDS_ONC_PORTAL_STATE" desc="Settings > Internet, label in network details page for the captive portal state.">
         Portal State
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SETTINGS_LINK_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SETTINGS_LINK_TEXT.png.sha1
new file mode 100644
index 0000000..9402c23
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SETTINGS_LINK_TEXT.png.sha1
@@ -0,0 +1 @@
+5f8bcd15881f054c39ac8fe610944829da50eb94
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_ONC_CONNECTING.png.sha1 b/chromeos/chromeos_strings_grd/IDS_ONC_CONNECTING.png.sha1
index 2b1c927..a7e6d49 100644
--- a/chromeos/chromeos_strings_grd/IDS_ONC_CONNECTING.png.sha1
+++ b/chromeos/chromeos_strings_grd/IDS_ONC_CONNECTING.png.sha1
@@ -1 +1 @@
-f46694f24e422c4f45784ce98da9868f86da3528
\ No newline at end of file
+98c1c8d49286ce963dcca24332c925007a57fd8b
\ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/js/mojo/util.js b/chromeos/components/camera_app_ui/resources/js/mojo/util.js
index 47f522c..fc33a03 100644
--- a/chromeos/components/camera_app_ui/resources/js/mojo/util.js
+++ b/chromeos/components/camera_app_ui/resources/js/mojo/util.js
@@ -20,7 +20,7 @@
  *     to happen.
  */
 async function wrapMojoResponse(call) {
-  const result = await Promise.race([call, windowUnload.wait()]);
+  const result = await Promise.race([windowUnload.wait(), call]);
   if (windowUnload.isSignaled()) {
     return new Promise(() => {});
   }
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_af.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_af.xtb
index 180b600..857f06e 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_af.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_af.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Foto</translation>
 <translation id="4649291346448517080">Kan nie die lêer stoor nie</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Multistroom-video-opname</translation>
 <translation id="5057360777601936059">Jou kamera is tans nie beskikbaar nie.
         Kyk asseblief of die kamera behoorlik gekoppel is.</translation>
 <translation id="5152121255775685072">Gaan na galery toe</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_bs.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_bs.xtb
index d7390f5c..96b78ca 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_bs.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_bs.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Fotografija</translation>
 <translation id="4649291346448517080">Nije moguće sačuvati fajl</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Emitiraj videosnimku na više kanala</translation>
 <translation id="5057360777601936059">Kamera je trenutno nedostupna.
         Provjerite je li kamera pravilno povezana.</translation>
 <translation id="5152121255775685072">Idi u galeriju</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_et.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_et.xtb
index b5f9035c..4369bbc 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_et.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_et.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Foto</translation>
 <translation id="4649291346448517080">Faili salvestamine ebaõnnestus</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Mitmevooline videosalvestus</translation>
 <translation id="5057360777601936059">Teie kaamera pole praegu saadaval.
         Kontrollige, kas kaamera on korralikult ühendatud.</translation>
 <translation id="5152121255775685072">Ava galerii</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_hr.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_hr.xtb
index ccbcce8..84e4820 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_hr.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_hr.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Fotografija</translation>
 <translation id="4649291346448517080">Spremanje datoteke nije uspjelo</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Emitiraj videosnimku na više kanala</translation>
 <translation id="5057360777601936059">Vaš fotoaparat trenutačno nije dostupan.
         Provjerite je li fotoaparat pravilno povezan.</translation>
 <translation id="5152121255775685072">Otvori galeriju</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_mn.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_mn.xtb
index 5e87686..346ef90 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_mn.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_mn.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Зураг</translation>
 <translation id="4649291346448517080">Файлыг хадгалах боломжгүй байна</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Олон дамжуулалттай видео бичлэг</translation>
 <translation id="5057360777601936059">Tаны камер одоогоор боломжгүй байна.
         Камераа зөв залгасан эсэхээ шалгана уу.</translation>
 <translation id="5152121255775685072">Галлерей руу очих</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_nl.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_nl.xtb
index 3b33c79..f8abd61 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_nl.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_nl.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Foto</translation>
 <translation id="4649291346448517080">Kan het bestand niet opslaan</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Multistream-video opnemen</translation>
 <translation id="5057360777601936059">Je camera is momenteel niet beschikbaar.
         Controleer of de camera correct is aangesloten.</translation>
 <translation id="5152121255775685072">Naar galerij</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_si.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_si.xtb
index ce0a6fe..e79f522b 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_si.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_si.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">ඡායාරූපය</translation>
 <translation id="4649291346448517080">ගොනුව සුරැකිය නොහැක</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">බහුප්‍රවාහ වීඩියෝ පටිගත කිරීම</translation>
 <translation id="5057360777601936059">ඔබේ කැමරාව දැනට නොලැබේ.
         කැමරාව නිසියාකාරව සම්බන්ධ වී ඇති දැයි පරීක්‍ෂා කරන්න.</translation>
 <translation id="5152121255775685072">ගැලරියට යන්න</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_uz.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_uz.xtb
index 76d82c29..364f199 100644
--- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_uz.xtb
+++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_uz.xtb
@@ -57,6 +57,7 @@
 <translation id="4628948037717959914">Rasm</translation>
 <translation id="4649291346448517080">Fayl saqlanmadi</translation>
 <translation id="4890010094662541459">3 x 3</translation>
+<translation id="491895758387112773">Multistrim video yozib olinishi</translation>
 <translation id="5057360777601936059">Kamera hozirda ishlamayapti.
         Kamera bexato ulanganini tekshiring.</translation>
 <translation id="5152121255775685072">Galereyani ochish</translation>
diff --git a/chromeos/components/eche_app_ui/eche_notification_click_handler.cc b/chromeos/components/eche_app_ui/eche_notification_click_handler.cc
index 6691d7d..3683fbdf 100644
--- a/chromeos/components/eche_app_ui/eche_notification_click_handler.cc
+++ b/chromeos/components/eche_app_ui/eche_notification_click_handler.cc
@@ -44,7 +44,7 @@
 void EcheNotificationClickHandler::HandleNotificationClick(
     int64_t notification_id,
     const phonehub::Notification::AppMetadata& app_metadata) {
-  launch_eche_app_function_.Run(notification_id);
+  launch_eche_app_function_.Run(notification_id, app_metadata.package_name);
 }
 
 void EcheNotificationClickHandler::OnFeatureStatusChanged() {
diff --git a/chromeos/components/eche_app_ui/eche_notification_click_handler.h b/chromeos/components/eche_app_ui/eche_notification_click_handler.h
index f81632a..7350b565 100644
--- a/chromeos/components/eche_app_ui/eche_notification_click_handler.h
+++ b/chromeos/components/eche_app_ui/eche_notification_click_handler.h
@@ -5,6 +5,8 @@
 #ifndef CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_NOTIFICATION_CLICK_HANDLER_H_
 #define CHROMEOS_COMPONENTS_ECHE_APP_UI_ECHE_NOTIFICATION_CLICK_HANDLER_H_
 
+#include <string>
+
 #include "base/callback.h"
 #include "chromeos/components/eche_app_ui/feature_status_provider.h"
 #include "chromeos/components/phonehub/notification.h"
@@ -23,7 +25,8 @@
 class EcheNotificationClickHandler : public phonehub::NotificationClickHandler,
                                      FeatureStatusProvider::Observer {
  public:
-  using LaunchEcheAppFunction = base::RepeatingCallback<void(int64_t)>;
+  using LaunchEcheAppFunction =
+      base::RepeatingCallback<void(int64_t, std::string)>;
   using CloseEcheAppFunction = base::RepeatingCallback<void()>;
 
   EcheNotificationClickHandler(phonehub::PhoneHubManager*,
diff --git a/chromeos/components/eche_app_ui/eche_notification_click_handler_unittest.cc b/chromeos/components/eche_app_ui/eche_notification_click_handler_unittest.cc
index 848d7796..9cabf0e 100644
--- a/chromeos/components/eche_app_ui/eche_notification_click_handler_unittest.cc
+++ b/chromeos/components/eche_app_ui/eche_notification_click_handler_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chromeos/components/eche_app_ui/eche_notification_click_handler.h"
 
+#include <string>
+
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/test/scoped_feature_list.h"
@@ -39,7 +41,8 @@
             base::Unretained(this)));
   }
 
-  void FakeLaunchEcheAppFunction(int64_t notification_id) {
+  void FakeLaunchEcheAppFunction(int64_t notification_id,
+                                 std::string package_name) {
     // Do nothing.
   }
 
diff --git a/chromeos/components/help_app_ui/resources/browser_proxy.js b/chromeos/components/help_app_ui/resources/browser_proxy.js
index a71d1f00..c75a3f8 100644
--- a/chromeos/components/help_app_ui/resources/browser_proxy.js
+++ b/chromeos/components/help_app_ui/resources/browser_proxy.js
@@ -140,9 +140,11 @@
       if (!(await isLssEnabled)) {
         return {results: null};
       }
+      const dataFromApp =
+          /** @type {{query: string, maxResults:(number|undefined)}} */
+          (message);
       const response = await indexRemote.find(
-          toString16((/** @type {{query: string}} */ (message)).query),
-          /*max_results=*/ 100);
+          toString16(dataFromApp.query), dataFromApp.maxResults || 50);
 
       // Record the search status in the trusted frame.
       chrome.metricsPrivate.recordEnumerationValue(
@@ -242,15 +244,18 @@
       const dataFromApp =
           /** @type {!Array<!helpApp.LauncherSearchableItem>} */ (message);
       /** @type {!Array<!chromeos.helpApp.mojom.SearchConcept>} */
-      const dataToSend = dataFromApp.map(searchableItem => ({
-        id: truncate(searchableItem.id),
-        title: toString16(searchableItem.title),
-        mainCategory: toString16(searchableItem.mainCategoryName),
-        tags: searchableItem.tags.map(tag => toString16(tag))
-          .filter(tag => tag.data.length > 0),
-        urlPathWithParameters: truncate(searchableItem.urlPathWithParameters),
-        locale: truncate(searchableItem.locale),
-      }));
+      const dataToSend = dataFromApp.map(
+          searchableItem => ({
+            id: truncate(searchableItem.id),
+            title: toString16(searchableItem.title),
+            mainCategory: toString16(searchableItem.mainCategoryName),
+            tags: searchableItem.tags.map(tag => toString16(tag))
+                      .filter(tag => tag.data.length > 0),
+            tagLocale: searchableItem.tagLocale || '',
+            urlPathWithParameters:
+                truncate(searchableItem.urlPathWithParameters),
+            locale: truncate(searchableItem.locale),
+          }));
       // Filter out invalid items. No field can be empty except locale.
       const dataFiltered = dataToSend.filter(item => {
         const valid = item.id && item.title && item.mainCategory
diff --git a/chromeos/components/help_app_ui/resources/help_app.externs.js b/chromeos/components/help_app_ui/resources/help_app.externs.js
index e7f6f18..8050f71 100644
--- a/chromeos/components/help_app_ui/resources/help_app.externs.js
+++ b/chromeos/components/help_app_ui/resources/help_app.externs.js
@@ -52,7 +52,9 @@
  */
 helpApp.SearchableItem.prototype.subheadings;
 /**
- * The locale that this content is localized in.
+ * The locale that this content is localized in. Empty string means system
+ *     locale. The format is language[-country] (e.g., en-US) where the language
+ *     is the 2 or 3 letter code from ISO-639.
  * @type {string}
  */
 helpApp.SearchableItem.prototype.locale;
@@ -87,6 +89,12 @@
  */
 helpApp.LauncherSearchableItem.prototype.tags;
 /**
+ * The locale of the tags. This could be different from the locale of the other
+ * fields. Empty string means system locale. Same format as the locale field.
+ * @type {string}
+ */
+helpApp.LauncherSearchableItem.prototype.tagLocale;
+/**
  * The URL path containing the relevant content, which may or may not contain
  *     URL parameters. For example, if the help content is at
  *     chrome://help-app/help/sub/3399763/id/1282338#install-user, then the
@@ -96,7 +104,8 @@
 helpApp.LauncherSearchableItem.prototype.urlPathWithParameters;
 /**
  * The locale that this content is localized in. Empty string means system
- *     locale.
+ *     locale. The format is language[-country] (e.g., en-US) where the language
+ *     is the 2 or 3 letter code from ISO-639.
  * @type {string}
  */
 helpApp.LauncherSearchableItem.prototype.locale;
@@ -191,9 +200,11 @@
 /**
  * Search the search index for content that matches the given query.
  * @param {string} query
+ * @param {number=} maxResults Maximum number of search results. Default 50.
  * @return {!Promise<!helpApp.FindResponse>}
  */
-helpApp.ClientApiDelegate.prototype.findInSearchIndex = function(query) {};
+helpApp.ClientApiDelegate.prototype.findInSearchIndex = function(
+    query, maxResults) {};
 
 /**
  * Close the app. Works if the app is open in the background page.
diff --git a/chromeos/components/help_app_ui/resources/receiver.js b/chromeos/components/help_app_ui/resources/receiver.js
index b5253791..62fb2049 100644
--- a/chromeos/components/help_app_ui/resources/receiver.js
+++ b/chromeos/components/help_app_ui/resources/receiver.js
@@ -38,11 +38,13 @@
   /**
    * @override
    * @param {string} query
+   * @param {number=} maxResults Maximum number of search results. Default 50.
    * @return {!Promise<!helpApp.FindResponse>}
    */
-  findInSearchIndex(query) {
+  findInSearchIndex(query, maxResults) {
     return /** @type {!Promise<!helpApp.FindResponse>} */ (
-        parentMessagePipe.sendMessage(Message.FIND_IN_SEARCH_INDEX, {query}));
+        parentMessagePipe.sendMessage(
+            Message.FIND_IN_SEARCH_INDEX, {query, maxResults}));
   },
   closeBackgroundPage() {
     parentMessagePipe.sendMessage(Message.CLOSE_BACKGROUND_PAGE);
diff --git a/chromeos/components/help_app_ui/search/search.mojom b/chromeos/components/help_app_ui/search/search.mojom
index e1359e1..70ef961 100644
--- a/chromeos/components/help_app_ui/search/search.mojom
+++ b/chromeos/components/help_app_ui/search/search.mojom
@@ -48,6 +48,11 @@
   // List of localized tags used to make the search concept searchable.
   array<mojo_base.mojom.String16> tags;
 
+  // The locale of the tags. This could be different from the locale of the
+  // other fields. Empty string means system locale. Same format as the locale
+  // field.
+  string tag_locale;
+
   // The URL path containing the relevant content, which may or may not contain
   // URL parameters. For example, if the help content is at
   // chrome://help-app/help/sub/3399763/id/1282338#install-user, then the field
@@ -55,7 +60,8 @@
   string url_path_with_parameters;
 
   // Locale code. Leave unset for the system configured locale. The format is
-  // language[-country] (e.g., en-US).
+  // language[-country] (e.g., en-US) where the language is the 2 or 3 letter
+  // code from ISO-639.
   string locale;
 };
 
diff --git a/chromeos/components/help_app_ui/search/search_handler_unittest.cc b/chromeos/components/help_app_ui/search/search_handler_unittest.cc
index 2d0fa35..c34a6d1 100644
--- a/chromeos/components/help_app_ui/search/search_handler_unittest.cc
+++ b/chromeos/components/help_app_ui/search/search_handler_unittest.cc
@@ -73,6 +73,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Tag 2"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_2 = mojom::SearchConcept::New(
@@ -80,6 +81,7 @@
       /*title=*/u"Title 2",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Another test tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
@@ -121,6 +123,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Printing"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
@@ -151,6 +154,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"less relevant concept"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_2 = mojom::SearchConcept::New(
@@ -158,6 +162,7 @@
       /*title=*/u"Title 2",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"more relevant tag", u"Tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
@@ -220,6 +225,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Printing"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
@@ -269,6 +275,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Printing"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   search_concepts.push_back(std::move(new_concept_1));
diff --git a/chromeos/components/help_app_ui/search/search_tag_registry.cc b/chromeos/components/help_app_ui/search/search_tag_registry.cc
index 03ac616e..4e4ac7b 100644
--- a/chromeos/components/help_app_ui/search/search_tag_registry.cc
+++ b/chromeos/components/help_app_ui/search/search_tag_registry.cc
@@ -32,7 +32,8 @@
       ++tag_num;
     }
 
-    data_list.emplace_back(concept->id, std::move(content_list));
+    data_list.emplace_back(concept->id, std::move(content_list),
+                           concept->tag_locale);
   }
   return data_list;
 }
diff --git a/chromeos/components/help_app_ui/search/search_tag_registry_unittest.cc b/chromeos/components/help_app_ui/search/search_tag_registry_unittest.cc
index d2b027c4..0372e0e 100644
--- a/chromeos/components/help_app_ui/search/search_tag_registry_unittest.cc
+++ b/chromeos/components/help_app_ui/search/search_tag_registry_unittest.cc
@@ -86,6 +86,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Tag 2"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_2 = mojom::SearchConcept::New(
@@ -93,6 +94,7 @@
       /*title=*/u"Title 2",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Another test tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   to_add.push_back(std::move(new_concept_1));
@@ -125,6 +127,7 @@
       /*title=*/u"Title 1",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag", u"Tag 2"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_2 = mojom::SearchConcept::New(
@@ -132,6 +135,7 @@
       /*title=*/u"Title 2",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Another test tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   to_add.push_back(std::move(new_concept_1));
@@ -150,6 +154,7 @@
       /*title=*/u"Title 3",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Test tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   mojom::SearchConceptPtr new_concept_4 = mojom::SearchConcept::New(
@@ -157,6 +162,7 @@
       /*title=*/u"Title 4",
       /*main_category=*/u"Help",
       /*tags=*/std::vector<std::u16string>{u"Another test tag"},
+      /*tag_locale=*/"en",
       /*url_path_with_parameters=*/"help",
       /*locale=*/"");
   to_add_2.push_back(std::move(new_concept_3));
diff --git a/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js b/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js
index c3e51ff1..2d9ec4a 100644
--- a/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js
+++ b/chromeos/components/help_app_ui/test/help_app_guest_ui_browsertest.js
@@ -163,6 +163,45 @@
     ]);
 });
 
+// Test that the number of search results is reduced when maxResults is
+// provided.
+GUEST_TEST('GuestCanLimitMaxSearchResults', async () => {
+  const delegate = await waitForInitialIndexUpdate();
+
+  await delegate.addOrUpdateSearchIndex([{
+    // Main category match. No subcategories.
+    id: 'test-id-1',
+    title: 'Title with of article',
+    body: 'Body text',
+    mainCategoryName: 'Verycomplicatedsearchtoken',
+    locale: 'en-US',
+  },{
+    // Subcategory match.
+    id: 'test-id-2',
+    title: 'Title 2',
+    subcategoryNames: [
+      'Subcategory 1', 'verycomplicatedsearchtoken in subcategory.'
+    ],
+    body: 'Body text',
+    mainCategoryName: 'Help',
+    locale: 'en-US',
+  }]);
+
+  // Limit to 1 result. This search query was chosen because it is unlikely to
+  // show any search results for the real app's data.
+  const res = await delegate.findInSearchIndex('verycomplicatedsearchtoken', 1);
+
+  chai.expect(res.results).to.have.deep.members([
+      {
+        id: 'test-id-1',
+        titlePositions: [],
+        subheadingIndex: null,
+        subheadingPositions: null,
+        bodyPositions: [],
+      },
+    ]);
+});
+
 // Test that the guest frame can clear the search index.
 GUEST_TEST('GuestCanClearSearchIndex', async () => {
   const delegate = await waitForInitialIndexUpdate();
diff --git a/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js b/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js
index 53be207..ef17b60 100644
--- a/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js
+++ b/chromeos/components/help_app_ui/test/help_app_ui_browsertest.js
@@ -89,6 +89,11 @@
   testDone();
 });
 
+TEST_F('HelpAppUIBrowserTest', 'GuestCanLimitMaxSearchResults', async () => {
+  await runTestInGuest('GuestCanLimitMaxSearchResults');
+  testDone();
+});
+
 TEST_F('HelpAppUIBrowserTest', 'GuestCanClearSearchIndex', async () => {
   await runTestInGuest('GuestCanClearSearchIndex');
   testDone();
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index 763dfd7..e78ddee 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -334,6 +334,12 @@
   // compatibility, to avoid assumptions about where on disk the directory is
   // located.
   mojo_base.mojom.FilePath downloads@1;
+
+  // The (non-configurable) path of the mount point for drive in ChromeOS. For
+  // example, /media/fuse/drivefs-<hash>. We send the full path for future
+  // compatibility, to avoid assumptions about where on disk the directory is
+  // located.
+  [MinVersion=23] mojo_base.mojom.FilePath? drivefs@2;
 };
 
 // The device specific data needed in Lacros.
@@ -412,7 +418,7 @@
 // If ash-chrome is newer than the browser, then some fields may not be
 // processed by the browser.
 //
-// Next version: 23
+// Next version: 24
 // Next id: 23
 [Stable, RenamedFrom="crosapi.mojom.LacrosInitParams"]
 struct BrowserInitParams {
diff --git a/chromeos/dbus/audio/cras_audio_client.h b/chromeos/dbus/audio/cras_audio_client.h
index d666995c..b30582c0 100644
--- a/chromeos/dbus/audio/cras_audio_client.h
+++ b/chromeos/dbus/audio/cras_audio_client.h
@@ -239,4 +239,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::CrasAudioClient;
+}
+
 #endif  // CHROMEOS_DBUS_AUDIO_CRAS_AUDIO_CLIENT_H_
diff --git a/chromeos/dbus/biod/biod_client.h b/chromeos/dbus/biod/biod_client.h
index 8f2ec070..040e05a 100644
--- a/chromeos/dbus/biod/biod_client.h
+++ b/chromeos/dbus/biod/biod_client.h
@@ -160,4 +160,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::BiodClient;
+}
+
 #endif  // CHROMEOS_DBUS_BIOD_BIOD_CLIENT_H_
diff --git a/chromeos/dbus/concierge/concierge_client.h b/chromeos/dbus/concierge/concierge_client.h
index 5eff960..3254ef46 100644
--- a/chromeos/dbus/concierge/concierge_client.h
+++ b/chromeos/dbus/concierge/concierge_client.h
@@ -297,4 +297,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ConciergeClient;
+}
+
 #endif  // CHROMEOS_DBUS_CONCIERGE_CONCIERGE_CLIENT_H_
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
index 8f8f033..86b91697 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_client.h
@@ -145,4 +145,11 @@
 }  // namespace cros_healthd
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace cros_healthd {
+using ::chromeos::cros_healthd::FakeCrosHealthdClient;
+}  // namespace cros_healthd
+}  // namespace ash
+
 #endif  // CHROMEOS_DBUS_CROS_HEALTHD_FAKE_CROS_HEALTHD_CLIENT_H_
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
index 938bae36..8ea1e99 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
@@ -305,4 +305,11 @@
 }  // namespace cros_healthd
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace cros_healthd {
+using ::chromeos::cros_healthd::FakeCrosHealthdService;
+}  // namespace cros_healthd
+}  // namespace ash
+
 #endif  // CHROMEOS_DBUS_CROS_HEALTHD_FAKE_CROS_HEALTHD_SERVICE_H_
diff --git a/chromeos/dbus/session_manager/fake_session_manager_client.h b/chromeos/dbus/session_manager/fake_session_manager_client.h
index 1a22ee66..565ffdb 100644
--- a/chromeos/dbus/session_manager/fake_session_manager_client.h
+++ b/chromeos/dbus/session_manager/fake_session_manager_client.h
@@ -91,6 +91,9 @@
   void RequestLockScreen() override;
   void NotifyLockScreenShown() override;
   void NotifyLockScreenDismissed() override;
+  void RequestBrowserDataMigration(
+      const cryptohome::AccountIdentifier& cryptohome_id,
+      VoidDBusMethodCallback callback) override {}
   void RetrieveActiveSessions(ActiveSessionsCallback callback) override;
   void RetrieveDevicePolicy(RetrievePolicyCallback callback) override;
   RetrievePolicyResponseType BlockingRetrieveDevicePolicy(
diff --git a/chromeos/dbus/session_manager/session_manager_client.cc b/chromeos/dbus/session_manager/session_manager_client.cc
index 6d8f86d9..690540a 100644
--- a/chromeos/dbus/session_manager/session_manager_client.cc
+++ b/chromeos/dbus/session_manager/session_manager_client.cc
@@ -394,6 +394,20 @@
         login_manager::kSessionManagerHandleLockScreenDismissed);
   }
 
+  void RequestBrowserDataMigration(
+      const cryptohome::AccountIdentifier& cryptohome_id,
+      VoidDBusMethodCallback callback) override {
+    dbus::MethodCall method_call(
+        login_manager::kSessionManagerInterface,
+        login_manager::kSessionManagerStartBrowserDataMigration);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(cryptohome_id.account_id());
+    session_manager_proxy_->CallMethod(
+        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::BindOnce(&SessionManagerClientImpl::OnVoidMethod,
+                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  }
+
   void RetrieveActiveSessions(ActiveSessionsCallback callback) override {
     dbus::MethodCall method_call(
         login_manager::kSessionManagerInterface,
diff --git a/chromeos/dbus/session_manager/session_manager_client.h b/chromeos/dbus/session_manager/session_manager_client.h
index ed30315..1d99e3a 100644
--- a/chromeos/dbus/session_manager/session_manager_client.h
+++ b/chromeos/dbus/session_manager/session_manager_client.h
@@ -251,6 +251,12 @@
   // Notifies session_manager that Chrome has hidden the lock screen.
   virtual void NotifyLockScreenDismissed() = 0;
 
+  // Tells session_manager to restart ash-chrome to carry out browser data
+  // migration.
+  virtual void RequestBrowserDataMigration(
+      const cryptohome::AccountIdentifier& cryptohome_id,
+      VoidDBusMethodCallback callback) = 0;
+
   // Map that is used to describe the set of active user sessions where |key|
   // is cryptohome id and |value| is user_id_hash.
   using ActiveSessionsMap = std::map<std::string, std::string>;
diff --git a/chromeos/dbus/shill/fake_shill_manager_client.cc b/chromeos/dbus/shill/fake_shill_manager_client.cc
index acb5a70..1104463c 100644
--- a/chromeos/dbus/shill/fake_shill_manager_client.cc
+++ b/chromeos/dbus/shill/fake_shill_manager_client.cc
@@ -1158,7 +1158,7 @@
 }
 
 void FakeShillManagerClient::ClearProfiles() {
-  if (GetListProperty(shill::kProfilesProperty)->empty()) {
+  if (GetListProperty(shill::kProfilesProperty)->GetList().empty()) {
     return;
   }
   GetListProperty(shill::kProfilesProperty)->ClearList();
diff --git a/chromeos/lacros/BUILD.gn b/chromeos/lacros/BUILD.gn
index 5c374a2..44227aa 100644
--- a/chromeos/lacros/BUILD.gn
+++ b/chromeos/lacros/BUILD.gn
@@ -21,8 +21,12 @@
     "//build:chromeos_buildflags",
     "//chromeos/crosapi/cpp",
     "//chromeos/crosapi/mojom",
+    "//chromeos/dbus/constants",
+    "//chromeos/dbus/init",
+    "//chromeos/dbus/permission_broker",
     "//chromeos/process_proxy",
     "//chromeos/startup",
+    "//dbus",
     "//mojo/public/cpp/bindings",
     "//ui/native_theme",
   ]
@@ -31,6 +35,10 @@
     "lacros_chrome_service_impl.h",
     "lacros_chrome_service_impl_never_blocking_state.cc",
     "lacros_chrome_service_impl_never_blocking_state.h",
+    "lacros_dbus_helper.cc",
+    "lacros_dbus_helper.h",
+    "lacros_dbus_thread_manager.cc",
+    "lacros_dbus_thread_manager.h",
     "lacros_service.h",
     "native_theme_cache.cc",
     "native_theme_cache.h",
diff --git a/chromeos/lacros/DEPS b/chromeos/lacros/DEPS
index c18b110..235c5679 100644
--- a/chromeos/lacros/DEPS
+++ b/chromeos/lacros/DEPS
@@ -5,5 +5,6 @@
   "-chrome",
   "-content",
 
+  "+dbus",
   "+ui/native_theme",
 ]
diff --git a/chromeos/lacros/lacros_dbus_helper.cc b/chromeos/lacros/lacros_dbus_helper.cc
new file mode 100644
index 0000000..3b0a63a
--- /dev/null
+++ b/chromeos/lacros/lacros_dbus_helper.cc
@@ -0,0 +1,33 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/lacros/lacros_dbus_helper.h"
+
+#include "chromeos/dbus/init/initialize_dbus_client.h"
+#include "chromeos/dbus/permission_broker/permission_broker_client.h"
+#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+
+namespace chromeos {
+
+void LacrosInitializeDBus() {
+  // Unlike Ash, Lacros has no services that need paths, and therefore needs
+  // not override paths like Ash does.
+
+  // Initialize LacrosDBusThreadManager for the browser.
+  LacrosDBusThreadManager::Initialize();
+
+  // Initialize Chrome D-Bus clients.
+  dbus::Bus* bus = LacrosDBusThreadManager::Get()->GetSystemBus();
+
+  InitializeDBusClient<PermissionBrokerClient>(bus);
+}
+
+void LacrosShutdownDBus() {
+  // Shut down D-Bus clients in reverse order of initialization.
+  PermissionBrokerClient::Shutdown();
+
+  LacrosDBusThreadManager::Shutdown();
+}
+
+}  // namespace chromeos
diff --git a/chromeos/lacros/lacros_dbus_helper.h b/chromeos/lacros/lacros_dbus_helper.h
new file mode 100644
index 0000000..00b6c6f3
--- /dev/null
+++ b/chromeos/lacros/lacros_dbus_helper.h
@@ -0,0 +1,20 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
+#define CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
+
+#include "base/component_export.h"
+
+namespace chromeos {
+
+// Initializes the D-Bus thread manager and Chrome DBus services for Lacros.
+COMPONENT_EXPORT(CHROMEOS_LACROS) void LacrosInitializeDBus();
+
+// Shuts down the D-Bus thread manager and Chrome DBus services for Lacros.
+COMPONENT_EXPORT(CHROMEOS_LACROS) void LacrosShutdownDBus();
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_LACROS_LACROS_DBUS_HELPER_H_
diff --git a/chromeos/lacros/lacros_dbus_thread_manager.cc b/chromeos/lacros/lacros_dbus_thread_manager.cc
new file mode 100644
index 0000000..7378a97
--- /dev/null
+++ b/chromeos/lacros/lacros_dbus_thread_manager.cc
@@ -0,0 +1,48 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+
+#include "base/logging.h"
+
+namespace chromeos {
+
+static LacrosDBusThreadManager* g_lacros_dbus_thread_manager = nullptr;
+
+LacrosDBusThreadManager::LacrosDBusThreadManager() = default;
+
+LacrosDBusThreadManager::~LacrosDBusThreadManager() = default;
+
+// static
+void LacrosDBusThreadManager::Initialize() {
+  CHECK(!g_lacros_dbus_thread_manager);
+  g_lacros_dbus_thread_manager = new LacrosDBusThreadManager();
+}
+
+// static
+LacrosDBusThreadManager* LacrosDBusThreadManager::Get() {
+  CHECK(g_lacros_dbus_thread_manager)
+      << "LacrosDBusThreadManager::Get() called before Initialize()";
+  return g_lacros_dbus_thread_manager;
+}
+
+// static
+bool LacrosDBusThreadManager::IsInitialized() {
+  return !!g_lacros_dbus_thread_manager;
+}
+
+// static
+void LacrosDBusThreadManager::Shutdown() {
+  // Ensure that we only shutdown DBusThreadManager once.
+  CHECK(g_lacros_dbus_thread_manager);
+
+  LacrosDBusThreadManager* lacros_dbus_thread_manager =
+      g_lacros_dbus_thread_manager;
+  g_lacros_dbus_thread_manager = nullptr;
+  delete lacros_dbus_thread_manager;
+
+  VLOG(1) << "LacrosDBusThreadManager Shutdown completed";
+}
+
+}  // namespace chromeos
diff --git a/chromeos/lacros/lacros_dbus_thread_manager.h b/chromeos/lacros/lacros_dbus_thread_manager.h
new file mode 100644
index 0000000..f006a07
--- /dev/null
+++ b/chromeos/lacros/lacros_dbus_thread_manager.h
@@ -0,0 +1,44 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
+#define CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
+
+#include "base/component_export.h"
+#include "chromeos/dbus/init/dbus_thread_manager_base.h"
+
+namespace chromeos {
+
+// Lacros implementation of DBusThreadManagerBase.
+class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosDBusThreadManager
+    : public DBusThreadManagerBase {
+ public:
+  // Sets the global instance. Must be called before any calls to Get().
+  // We explicitly initialize and shut down the global object, rather than
+  // making it a Singleton, to ensure clean startup and shutdown.
+  // This will initialize real or fake DBusClients depending on command-line
+  // arguments and whether this process runs in a ChromeOS environment.
+  static void Initialize();
+
+  // Gets the global instance. Initialize() must be called first.
+  static LacrosDBusThreadManager* Get();
+
+  // Returns true if LacrosDBusThreadManager has been initialized. Call this to
+  // avoid initializing + shutting down LacrosDBusThreadManager more than once.
+  static bool IsInitialized();
+
+  // Destroys the global instance.
+  static void Shutdown();
+
+ private:
+  LacrosDBusThreadManager();
+  LacrosDBusThreadManager(const LacrosDBusThreadManager&) = delete;
+  const LacrosDBusThreadManager& operator=(const LacrosDBusThreadManager&) =
+      delete;
+  ~LacrosDBusThreadManager() override;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_LACROS_LACROS_DBUS_THREAD_MANAGER_H_
diff --git a/chromeos/login/auth/challenge_response_key.h b/chromeos/login/auth/challenge_response_key.h
index 83306aa6..75dffd14 100644
--- a/chromeos/login/auth/challenge_response_key.h
+++ b/chromeos/login/auth/challenge_response_key.h
@@ -74,4 +74,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ChallengeResponseKey;
+}
+
 #endif  // CHROMEOS_LOGIN_AUTH_CHALLENGE_RESPONSE_KEY_H_
diff --git a/chromeos/login/auth/extended_authenticator.h b/chromeos/login/auth/extended_authenticator.h
index 9c0bf14..15469635 100644
--- a/chromeos/login/auth/extended_authenticator.h
+++ b/chromeos/login/auth/extended_authenticator.h
@@ -106,4 +106,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::ExtendedAuthenticator;
+}
+
 #endif  // CHROMEOS_LOGIN_AUTH_EXTENDED_AUTHENTICATOR_H_
diff --git a/chromeos/login/auth/fake_extended_authenticator.h b/chromeos/login/auth/fake_extended_authenticator.h
index b4765e9d..3842f5f 100644
--- a/chromeos/login/auth/fake_extended_authenticator.h
+++ b/chromeos/login/auth/fake_extended_authenticator.h
@@ -57,4 +57,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::FakeExtendedAuthenticator;
+}
+
 #endif  // CHROMEOS_LOGIN_AUTH_FAKE_EXTENDED_AUTHENTICATOR_H_
diff --git a/chromeos/login/auth/stub_authenticator.h b/chromeos/login/auth/stub_authenticator.h
index 2b50bd4..693468f 100644
--- a/chromeos/login/auth/stub_authenticator.h
+++ b/chromeos/login/auth/stub_authenticator.h
@@ -97,4 +97,10 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove after the //chrome/browser/chromeos
+// source migration is finished.
+namespace ash {
+using ::chromeos::StubAuthenticator;
+}
+
 #endif  // CHROMEOS_LOGIN_AUTH_STUB_AUTHENTICATOR_H_
diff --git a/chromeos/network/managed_state.cc b/chromeos/network/managed_state.cc
index 9bbd845..625f7d8 100644
--- a/chromeos/network/managed_state.cc
+++ b/chromeos/network/managed_state.cc
@@ -143,8 +143,8 @@
   // uint32_t will automatically get converted to a double, which is why we try
   // to obtain the value as a double (see dbus/values_util.h).
   uint32_t new_value;
-  double double_value;
-  if (!value.GetAsDouble(&double_value) || double_value < 0) {
+  double double_value = value.GetIfDouble().value_or(-1);
+  if (double_value < 0) {
     NET_LOG(ERROR) << "Error parsing state value: " << NetworkPathId(path_)
                    << "." << key;
     return false;
diff --git a/chromeos/network/network_configuration_handler.h b/chromeos/network/network_configuration_handler.h
index 957b6e77..bd373a9 100644
--- a/chromeos/network/network_configuration_handler.h
+++ b/chromeos/network/network_configuration_handler.h
@@ -237,4 +237,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkConfigurationHandler;
+}  // namespace ash
+
 #endif  // CHROMEOS_NETWORK_NETWORK_CONFIGURATION_HANDLER_H_
diff --git a/chromeos/network/network_profile_handler.h b/chromeos/network/network_profile_handler.h
index b087adf..c931c0fc 100644
--- a/chromeos/network/network_profile_handler.h
+++ b/chromeos/network/network_profile_handler.h
@@ -109,4 +109,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::NetworkProfileHandler;
+}  // namespace ash
+
 #endif  // CHROMEOS_NETWORK_NETWORK_PROFILE_HANDLER_H_
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index 7e4a9e8..81161b9b 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -109,14 +109,11 @@
 // |onc_object|.
 void ExpandField(const std::string& fieldname,
                  const VariableExpander& variable_expander,
-                 base::DictionaryValue* onc_object) {
+                 base::Value* onc_object) {
   std::string* field_value = onc_object->FindStringKey(fieldname);
   if (!field_value)
     return;
-
   variable_expander.ExpandString(field_value);
-
-  onc_object->SetKey(fieldname, base::Value(*field_value));
 }
 
 // A |Mapper| for masking sensitive fields (e.g. credentials such as
@@ -164,30 +161,34 @@
 
 // Returns a map GUID->PEM of all server and authority certificates defined in
 // the Certificates section of ONC, which is passed in as |certificates|.
-CertPEMsByGUIDMap GetServerAndCACertsByGUID(
-    const base::ListValue& certificates) {
+CertPEMsByGUIDMap GetServerAndCACertsByGUID(const base::Value& certificates) {
   CertPEMsByGUIDMap certs_by_guid;
-  for (const auto& entry : certificates.GetList()) {
-    const base::DictionaryValue* cert = nullptr;
-    bool entry_is_dictionary = entry.GetAsDictionary(&cert);
-    DCHECK(entry_is_dictionary);
+  for (const auto& cert : certificates.GetList()) {
+    DCHECK(cert.is_dict());
 
-    std::string guid = GetString(*cert, ::onc::certificate::kGUID);
-    std::string cert_type = GetString(*cert, ::onc::certificate::kType);
-    if (cert_type != ::onc::certificate::kServer &&
-        cert_type != ::onc::certificate::kAuthority) {
+    const std::string* guid = cert.FindStringKey(::onc::certificate::kGUID);
+    if (!guid || guid->empty()) {
+      NET_LOG(ERROR) << "Certificate with missing or empty GUID.";
       continue;
     }
-    std::string x509_data = GetString(*cert, ::onc::certificate::kX509);
-
-    std::string der = DecodePEM(x509_data);
+    const std::string* cert_type =
+        cert.FindStringKey(::onc::certificate::kType);
+    DCHECK(cert_type);
+    if (*cert_type != ::onc::certificate::kServer &&
+        *cert_type != ::onc::certificate::kAuthority) {
+      continue;
+    }
+    const std::string* x509_data =
+        cert.FindStringKey(::onc::certificate::kX509);
+    std::string der;
+    if (x509_data)
+      der = DecodePEM(*x509_data);
     std::string pem;
     if (der.empty() || !net::X509Certificate::GetPEMEncodedFromDER(der, &pem)) {
-      LOG(ERROR) << "Certificate with GUID " << guid
-                 << " is not in PEM encoding.";
+      NET_LOG(ERROR) << "Certificate not PEM encoded, GUID: " << *guid;
       continue;
     }
-    certs_by_guid[guid] = pem;
+    certs_by_guid[*guid] = pem;
   }
 
   return certs_by_guid;
@@ -234,7 +235,7 @@
 bool ResolveSingleCertRef(const CertPEMsByGUIDMap& certs_by_guid,
                           const std::string& key_guid_ref,
                           const std::string& key_pem,
-                          base::DictionaryValue* onc_object) {
+                          base::Value* onc_object) {
   std::string* guid_ref = onc_object->FindStringKey(key_guid_ref);
   if (!guid_ref)
     return true;
@@ -261,14 +262,12 @@
 bool ResolveCertRefList(const CertPEMsByGUIDMap& certs_by_guid,
                         const std::string& key_guid_ref_list,
                         const std::string& key_pem_list,
-                        base::DictionaryValue* onc_object) {
-  const base::ListValue* guid_ref_list = nullptr;
-  if (!onc_object->GetListWithoutPathExpansion(key_guid_ref_list,
-                                               &guid_ref_list)) {
+                        base::Value* onc_object) {
+  const base::Value* guid_ref_list = onc_object->FindListKey(key_guid_ref_list);
+  if (!guid_ref_list)
     return true;
-  }
 
-  std::unique_ptr<base::ListValue> pem_list(new base::ListValue);
+  base::Value pem_list(base::Value::Type::LIST);
   for (const auto& entry : guid_ref_list->GetList()) {
     std::string guid_ref;
     bool entry_is_string = entry.GetAsString(&guid_ref);
@@ -278,12 +277,11 @@
     if (!GUIDRefToPEMEncoding(certs_by_guid, guid_ref, &pem_encoded))
       return false;
 
-    pem_list->AppendString(pem_encoded);
+    pem_list.Append(pem_encoded);
   }
 
   onc_object->RemoveKey(key_guid_ref_list);
-  onc_object->SetKey(key_pem_list,
-                     base::Value::FromUniquePtrValue(std::move(pem_list)));
+  onc_object->SetKey(key_pem_list, std::move(pem_list));
   return true;
 }
 
@@ -292,7 +290,7 @@
 bool ResolveSingleCertRefToList(const CertPEMsByGUIDMap& certs_by_guid,
                                 const std::string& key_guid_ref,
                                 const std::string& key_pem_list,
-                                base::DictionaryValue* onc_object) {
+                                base::Value* onc_object) {
   std::string* guid_ref = onc_object->FindStringKey(key_guid_ref);
   if (!guid_ref)
     return true;
@@ -301,11 +299,10 @@
   if (!GUIDRefToPEMEncoding(certs_by_guid, *guid_ref, &pem_encoded))
     return false;
 
-  std::unique_ptr<base::ListValue> pem_list(new base::ListValue);
-  pem_list->AppendString(pem_encoded);
+  base::Value pem_list(base::Value::Type::LIST);
+  pem_list.Append(pem_encoded);
   onc_object->RemoveKey(key_guid_ref);
-  onc_object->SetKey(key_pem_list,
-                     base::Value::FromUniquePtrValue(std::move(pem_list)));
+  onc_object->SetKey(key_pem_list, std::move(pem_list));
   return true;
 }
 
@@ -316,9 +313,9 @@
                                 const std::string& key_guid_refs,
                                 const std::string& key_guid_ref,
                                 const std::string& key_pem_list,
-                                base::DictionaryValue* onc_object) {
-  if (onc_object->HasKey(key_guid_refs)) {
-    if (onc_object->HasKey(key_guid_ref)) {
+                                base::Value* onc_object) {
+  if (onc_object->FindKey(key_guid_refs)) {
+    if (onc_object->FindKey(key_guid_ref)) {
       LOG(ERROR) << "Found both " << key_guid_refs << " and " << key_guid_ref
                  << ". Ignoring and removing the latter.";
       onc_object->RemoveKey(key_guid_ref);
@@ -336,7 +333,8 @@
 // |onc_object|.
 bool ResolveServerCertRefsInObject(const CertPEMsByGUIDMap& certs_by_guid,
                                    const OncValueSignature& signature,
-                                   base::DictionaryValue* onc_object) {
+                                   base::Value* onc_object) {
+  DCHECK(onc_object->is_dict());
   if (&signature == &kCertificatePatternSignature) {
     if (!ResolveCertRefList(certs_by_guid, ::onc::client_cert::kIssuerCARef,
                             ::onc::client_cert::kIssuerCAPEMs, onc_object)) {
@@ -367,19 +365,17 @@
   }
 
   // Recurse into nested objects.
-  for (base::DictionaryValue::Iterator it(*onc_object); !it.IsAtEnd();
-       it.Advance()) {
-    base::DictionaryValue* inner_object = nullptr;
-    if (!onc_object->GetDictionaryWithoutPathExpansion(it.key(), &inner_object))
+  for (auto it : onc_object->DictItems()) {
+    if (!it.second.is_dict())
       continue;
 
     const OncFieldSignature* field_signature =
-        GetFieldSignature(signature, it.key());
+        GetFieldSignature(signature, it.first);
     if (!field_signature)
       continue;
 
     if (!ResolveServerCertRefsInObject(
-            certs_by_guid, *field_signature->value_signature, inner_object)) {
+            certs_by_guid, *field_signature->value_signature, &it.second)) {
       return false;
     }
   }
@@ -468,7 +464,8 @@
 void SetProxyForScheme(const net::ProxyConfig::ProxyRules& proxy_rules,
                        const std::string& scheme,
                        const std::string& onc_scheme,
-                       base::DictionaryValue* dict) {
+                       base::Value* dict) {
+  DCHECK(dict->is_dict());
   const net::ProxyList* proxy_list = nullptr;
   if (proxy_rules.type == net::ProxyConfig::ProxyRules::Type::PROXY_LIST) {
     proxy_list = &proxy_rules.single_proxies;
@@ -479,7 +476,6 @@
   if (!proxy_list || proxy_list->IsEmpty())
     return;
   const net::ProxyServer& server = proxy_list->Get();
-  std::unique_ptr<base::DictionaryValue> url_dict(new base::DictionaryValue);
   std::string host = server.host_port_pair().host();
 
   // For all proxy types except SOCKS, the default scheme of the proxy host is
@@ -490,17 +486,17 @@
   // Only prefix the host with a non-default scheme.
   if (server.scheme() != default_scheme)
     host = SchemeToString(server.scheme()) + "://" + host;
-  url_dict->SetKey(::onc::proxy::kHost, base::Value(host));
-  url_dict->SetKey(::onc::proxy::kPort,
-                   base::Value(server.host_port_pair().port()));
-  dict->SetKey(onc_scheme,
-               base::Value::FromUniquePtrValue(std::move(url_dict)));
+  base::Value url_dict(base::Value::Type::DICTIONARY);
+  url_dict.SetKey(::onc::proxy::kHost, base::Value(host));
+  url_dict.SetKey(::onc::proxy::kPort,
+                  base::Value(server.host_port_pair().port()));
+  dict->SetKey(onc_scheme, std::move(url_dict));
 }
 
 // Returns the NetworkConfiugration with |guid| from |network_configs|, or
 // nullptr if no such NetworkConfiguration is found.
 const base::DictionaryValue* GetNetworkConfigByGUID(
-    const base::ListValue& network_configs,
+    const base::Value& network_configs,
     const std::string& guid) {
   for (const auto& entry : network_configs.GetList()) {
     const base::DictionaryValue* network = nullptr;
@@ -518,7 +514,7 @@
 // Returns the first Ethernet NetworkConfiguration from |network_configs| with
 // "Authentication: None", or nullptr if no such NetworkConfiguration is found.
 const base::DictionaryValue* GetNetworkConfigForEthernetWithoutEAP(
-    const base::ListValue& network_configs) {
+    const base::Value& network_configs) {
   VLOG(2) << "Search for ethernet policy without EAP.";
   for (const auto& entry : network_configs.GetList()) {
     const base::DictionaryValue* network = nullptr;
@@ -547,7 +543,7 @@
 // service, or otherwise returns the first Ethernet NetworkConfiguration with
 // "Authentication: None".
 const base::DictionaryValue* GetNetworkConfigForNetworkFromOnc(
-    const base::ListValue& network_configs,
+    const base::Value& network_configs,
     const NetworkState& network) {
   // In all cases except Ethernet, we use the GUID of |network|.
   if (!network.Matches(NetworkTypePattern::Ethernet()))
@@ -586,7 +582,7 @@
     const NetworkState& network) {
   if (!pref_service) {
     VLOG(2) << "No pref service";
-    return NULL;
+    return nullptr;
   }
 
   const PrefService::Preference* preference =
@@ -594,7 +590,7 @@
   if (!preference) {
     VLOG(2) << "No preference " << pref_name;
     // The preference may not exist in tests.
-    return NULL;
+    return nullptr;
   }
 
   // User prefs are not stored in this Preference yet but only the policy.
@@ -607,17 +603,13 @@
   if (preference->IsDefaultValue()) {
     VLOG(2) << "Preference has no recommended or mandatory value.";
     // No policy set.
-    return NULL;
+    return nullptr;
   }
   VLOG(2) << "Preference with policy found.";
   const base::Value* onc_policy_value = preference->GetValue();
   DCHECK(onc_policy_value);
 
-  const base::ListValue* onc_policy = NULL;
-  onc_policy_value->GetAsList(&onc_policy);
-  DCHECK(onc_policy);
-
-  return GetNetworkConfigForNetworkFromOnc(*onc_policy, network);
+  return GetNetworkConfigForNetworkFromOnc(*onc_policy_value, network);
 }
 
 // Returns the global network configuration dictionary from the ONC policy of
@@ -630,7 +622,7 @@
         user_manager::UserManager::Get()->GetActiveUser();
     if (!user) {
       LOG(ERROR) << "No user logged in yet.";
-      return NULL;
+      return nullptr;
     }
     username_hash = user->username_hash();
   }
@@ -1191,7 +1183,7 @@
         base::ListValue exclude_domains;
         for (const auto& rule : bypass_rules.rules())
           exclude_domains.AppendString(rule->ToString());
-        if (!exclude_domains.empty()) {
+        if (!exclude_domains.GetList().empty()) {
           proxy_settings.SetKey(::onc::proxy::kExcludeDomains,
                                 std::move(exclude_domains));
         }
@@ -1343,7 +1335,7 @@
     return network_policy;
   }
   VLOG(2) << "Network " << network.path() << " is unmanaged.";
-  return NULL;
+  return nullptr;
 }
 
 bool HasPolicyForNetwork(const PrefService* profile_prefs,
@@ -1352,7 +1344,7 @@
   ::onc::ONCSource ignored_onc_source;
   const base::DictionaryValue* policy = onc::GetPolicyForNetwork(
       profile_prefs, local_state_prefs, network, &ignored_onc_source);
-  return policy != NULL;
+  return policy != nullptr;
 }
 
 bool HasUserPasswordSubsitutionVariable(const OncValueSignature& signature,
diff --git a/chromeos/network/onc/onc_validator.cc b/chromeos/network/onc/onc_validator.cc
index 7754101c..6dd9c88 100644
--- a/chromeos/network/onc/onc_validator.cc
+++ b/chromeos/network/onc/onc_validator.cc
@@ -453,7 +453,7 @@
     if (!str.empty())
       return false;
   } else if (value->GetAsList(&list)) {
-    if (!list->empty())
+    if (!list->GetList().empty())
       return false;
   } else {
     NOTREACHED();
diff --git a/chromeos/network/proxy/ui_proxy_config_service.h b/chromeos/network/proxy/ui_proxy_config_service.h
index 8dd3a113..cc8b66ae 100644
--- a/chromeos/network/proxy/ui_proxy_config_service.h
+++ b/chromeos/network/proxy/ui_proxy_config_service.h
@@ -9,6 +9,8 @@
 
 #include "base/component_export.h"
 #include "base/macros.h"
+// TODO(https://crbug.com/1164001): remove and use forward declaration.
+#include "chromeos/network/network_profile_handler.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/proxy_config/proxy_prefs.h"
 
@@ -22,7 +24,6 @@
 
 class NetworkState;
 class NetworkStateHandler;
-class NetworkProfileHandler;
 
 // This class provides an interface to the UI for getting a network proxy
 // configuration.
@@ -90,4 +91,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::UIProxyConfigService;
+}  // namespace ash
+
 #endif  // CHROMEOS_NETWORK_PROXY_UI_PROXY_CONFIG_SERVICE_H_
diff --git a/chromeos/network/system_token_cert_db_storage.h b/chromeos/network/system_token_cert_db_storage.h
index 150243ba..6fdc39d 100644
--- a/chromeos/network/system_token_cert_db_storage.h
+++ b/chromeos/network/system_token_cert_db_storage.h
@@ -112,4 +112,9 @@
 
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+using ::chromeos::SystemTokenCertDbStorage;
+}  // namespace ash
+
 #endif  // CHROMEOS_NETWORK_SYSTEM_TOKEN_CERT_DB_STORAGE_H_
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index 5aa68f2..c9da8beb 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-93-4554.0-1625477697-benchmark-93.0.4567.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-93-4554.0-1625477697-benchmark-93.0.4568.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection.h b/chromeos/services/cros_healthd/public/cpp/service_connection.h
index 2e8a22d..8ff23f7 100644
--- a/chromeos/services/cros_healthd/public/cpp/service_connection.h
+++ b/chromeos/services/cros_healthd/public/cpp/service_connection.h
@@ -341,4 +341,11 @@
 }  // namespace cros_healthd
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace cros_healthd {
+using ::chromeos::cros_healthd::ServiceConnection;
+}  // namespace cros_healthd
+}  // namespace ash
+
 #endif  // CHROMEOS_SERVICES_CROS_HEALTHD_PUBLIC_CPP_SERVICE_CONNECTION_H_
diff --git a/chromeos/services/libassistant/chromium_http_connection.cc b/chromeos/services/libassistant/chromium_http_connection.cc
index d7cffb44..bd3ad243 100644
--- a/chromeos/services/libassistant/chromium_http_connection.cc
+++ b/chromeos/services/libassistant/chromium_http_connection.cc
@@ -18,6 +18,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "net/base/load_flags.h"
 #include "services/network/public/cpp/header_util.h"
+#include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
diff --git a/chromeos/services/multidevice_setup/host_backend_delegate_impl.cc b/chromeos/services/multidevice_setup/host_backend_delegate_impl.cc
index 563b9c8a..22584a7 100644
--- a/chromeos/services/multidevice_setup/host_backend_delegate_impl.cc
+++ b/chromeos/services/multidevice_setup/host_backend_delegate_impl.cc
@@ -294,16 +294,15 @@
   if (host_from_last_sync_ == host_from_sync)
     return;
 
-  PA_LOG(VERBOSE) << "HostBackendDelegateImpl::OnNewDevicesSynced(): New host "
-                  << "device has been set."
-                  << "\n  Old host: "
-                  << (host_from_last_sync_
-                          ? host_from_last_sync_->GetInstanceIdDeviceIdForLogs()
-                          : kNoHostForLogging)
-                  << "\n  New host: "
-                  << (host_from_sync
-                          ? host_from_sync->GetInstanceIdDeviceIdForLogs()
-                          : kNoHostForLogging);
+  PA_LOG(INFO) << "HostBackendDelegateImpl::OnNewDevicesSynced(): New host "
+               << "device has been set. Old host: "
+               << (host_from_last_sync_
+                       ? host_from_last_sync_->GetInstanceIdDeviceIdForLogs()
+                       : kNoHostForLogging)
+               << ", New host: "
+               << (host_from_sync
+                       ? host_from_sync->GetInstanceIdDeviceIdForLogs()
+                       : kNoHostForLogging);
 
   host_from_last_sync_ = host_from_sync;
 
diff --git a/chromeos/services/multidevice_setup/host_status_provider_impl.cc b/chromeos/services/multidevice_setup/host_status_provider_impl.cc
index cd41601..270e388 100644
--- a/chromeos/services/multidevice_setup/host_status_provider_impl.cc
+++ b/chromeos/services/multidevice_setup/host_status_provider_impl.cc
@@ -117,16 +117,16 @@
     return;
   }
 
-  PA_LOG(VERBOSE) << "HostStatusProviderImpl::"
-                  << "CheckForUpdatedStatusAndNotifyIfChanged(): Host status "
-                  << "changed. New status: "
-                  << current_status_and_device.host_status() << ", Old status: "
-                  << current_status_and_device_.host_status()
-                  << ", Host device: "
-                  << (current_status_and_device.host_device()
-                          ? current_status_and_device.host_device()
-                                ->GetInstanceIdDeviceIdForLogs()
-                          : "[no host]");
+  PA_LOG(INFO) << "HostStatusProviderImpl::"
+               << "CheckForUpdatedStatusAndNotifyIfChanged(): Host status "
+               << "changed. New status: "
+               << current_status_and_device.host_status()
+               << ", Old status: " << current_status_and_device_.host_status()
+               << ", Host device: "
+               << (current_status_and_device.host_device()
+                       ? current_status_and_device.host_device()
+                             ->GetInstanceIdDeviceIdForLogs()
+                       : "[no host]");
 
   current_status_and_device_ = current_status_and_device;
   NotifyHostStatusChange(current_status_and_device_.host_status(),
diff --git a/chromeos/services/network_config/in_process_instance.h b/chromeos/services/network_config/in_process_instance.h
index d1201f9..fba1551 100644
--- a/chromeos/services/network_config/in_process_instance.h
+++ b/chromeos/services/network_config/in_process_instance.h
@@ -23,4 +23,11 @@
 }  // namespace network_config
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace network_config {
+using ::chromeos::network_config::BindToInProcessInstance;
+}  // namespace network_config
+}  // namespace ash
+
 #endif  // CHROMEOS_SERVICES_NETWORK_CONFIG_IN_PROCESS_INSTANCE_H_
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h
index 1f6acda..e627469 100644
--- a/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h
+++ b/chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h
@@ -63,4 +63,11 @@
 }  // namespace network_config
 }  // namespace chromeos
 
+// TODO(https://crbug.com/1164001): remove when moved to ash.
+namespace ash {
+namespace network_config {
+using ::chromeos::network_config::CrosNetworkConfigTestHelper;
+}  // namespace network_config
+}  // namespace ash
+
 #endif  // CHROMEOS_SERVICES_NETWORK_CONFIG_PUBLIC_CPP_CROS_NETWORK_CONFIG_TEST_HELPER_H_
diff --git a/chromeos/strings/chromeos_strings_af.xtb b/chromeos/strings/chromeos_strings_af.xtb
index 71089fc..6695daaf 100644
--- a/chromeos/strings/chromeos_strings_af.xtb
+++ b/chromeos/strings/chromeos_strings_af.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Geen internet nie</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Aktiveringstatus</translation>
+<translation id="2294675138977897428">Geen Ethernet-verbinding bespeur nie</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Skakel Bluetooth aan om toestelle in die omtrek te ontdek</translation>
 <translation id="2364498172489649528">Geslaag</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Onbekende wi-fi-sekuriteitprotokol</translation>
 <translation id="65587193855025101">Plat oppervlak</translation>
 <translation id="6564646048574748301">Misluk – Kon nie drukker bereik nie</translation>
+<translation id="6603230386432466813">Sukkel jy om te koppel?</translation>
 <translation id="6618744767048954150">Werk tans</translation>
 <translation id="6620487321149975369">Druktake sal in geskiedenis verskyn tensy hulle handmatig verwyder word</translation>
 <translation id="6643016212128521049">Vee uit</translation>
diff --git a/chromeos/strings/chromeos_strings_ar.xtb b/chromeos/strings/chromeos_strings_ar.xtb
index 24a3e508..cbcc876 100644
--- a/chromeos/strings/chromeos_strings_ar.xtb
+++ b/chromeos/strings/chromeos_strings_ar.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732">يدير <ph name="MANAGER" /> هذا المستخدم، ويمكنه إدارة الإعدادات ومراقبة نشاط المستخدم عن بُعد.</translation>
 <translation id="150962533380566081">‏PUK غير صالح.</translation>
 <translation id="1510238584712386396">مشغِّل التطبيقات</translation>
+<translation id="1600964289716072707">يُرجى وضع صفحة أخرى على الماسح الضوئي واختيار "المسح ضوئيًا" لإضافة الصفحة.</translation>
 <translation id="1621067168122174824">تشغيل اختبار فحص البطارية</translation>
 <translation id="1641857168437328880">وحدة تغذية المستندات (وجه واحد)</translation>
 <translation id="1644574205037202324">السجل</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">‏تعذَّر التحويل باستخدام نظام أسماء النطاقات (DNS).</translation>
 <translation id="6768237774506518020">‏إن متوسط تعطُّل التحويل باستخدام نظام أسماء النطاقات (DNS) عالٍ.</translation>
 <translation id="6853312040151791195">معدّل تفريغ الشحن</translation>
+<translation id="6905724422583748843">الرجوع إلى <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">غطاء الماسح الضوئي مفتوح. يُرجى إغلاق الغطاء وإعادة المحاولة.</translation>
 <translation id="6911383237894364323">تعذَّر الاتصال بخوادم الوسائط.</translation>
 <translation id="6957231940976260713">اسم الخدمة</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">رقم تعريف النموذج</translation>
 <translation id="7805768142964895445">الحالة</translation>
 <translation id="7819857487979277519">‏PSK (WPA أو RSN)</translation>
+<translation id="7835501727204647447">‏تثبيت CloudReady</translation>
 <translation id="7881066108824108340">نظام أسماء النطاقات</translation>
 <translation id="7882358943899516840">نوع مقدم الخدمة</translation>
 <translation id="7936303884198020182">لم يتم العثور على خوادم الأسماء.</translation>
diff --git a/chromeos/strings/chromeos_strings_as.xtb b/chromeos/strings/chromeos_strings_as.xtb
index 0ab10ec..1c66953 100644
--- a/chromeos/strings/chromeos_strings_as.xtb
+++ b/chromeos/strings/chromeos_strings_as.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" />এ এই ব্যৱহাৰকাৰীগৰাকীক পৰিচালনা কৰে আৰু হয়তো দূৰৰ পৰা ছেটিং পৰিচালনা কৰে আৰু ব্যৱহাৰকাৰীৰ কাৰ্যকলাপ নিৰীক্ষণ কৰে।</translation>
 <translation id="150962533380566081">অমান্য PUK।</translation>
 <translation id="1510238584712386396">লঞ্চাৰ</translation>
+<translation id="1600964289716072707">অন্য এখন পৃষ্ঠা স্কেনাৰটোত ৰাখক আৰু পৃষ্ঠা যোগ কৰিবৰ বাবে স্কেন কৰক বাছনি কৰক।</translation>
 <translation id="1621067168122174824">চাৰ্জ পৰীক্ষা চলাওক</translation>
 <translation id="1641857168437328880">নথি ফীডাৰ (এফাল থকা)</translation>
 <translation id="1644574205037202324">ইতিহাস</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">DNSৰ সমাধান বিফল হৈছে</translation>
 <translation id="6768237774506518020">DNSৰ সমাধান বিফল হোৱাৰ হাৰ উচ্চ</translation>
 <translation id="6853312040151791195">চাৰ্জ খৰচ হোৱাৰ হাৰ</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" />লৈ উভতি যাওক</translation>
 <translation id="6910312834584889076">স্কেনাৰৰ ঢাকনীখন খোলা আছে। ঢাকনীখন বন্ধ কৰি পুনৰ চেষ্টা কৰি চাওক।</translation>
 <translation id="6911383237894364323">মিডিয়া ছাৰ্ভাৰৰ সৈতে সংযোগ কৰিব পৰা নগ’ল</translation>
 <translation id="6957231940976260713">সেৱাৰ নাম</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">ম’ডেল আইডি:</translation>
 <translation id="7805768142964895445">স্থিতি</translation>
 <translation id="7819857487979277519">PSK (WPA বা RSN)</translation>
+<translation id="7835501727204647447">CloudReady ইনষ্টল কৰক</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">প্ৰদানকাৰীৰ ধৰণ</translation>
 <translation id="7936303884198020182">ড’মেইন নাম থকা কোনো ছাৰ্ভাৰ পোৱা নগ'ল</translation>
diff --git a/chromeos/strings/chromeos_strings_bn.xtb b/chromeos/strings/chromeos_strings_bn.xtb
index 2920a36..bb0be295 100644
--- a/chromeos/strings/chromeos_strings_bn.xtb
+++ b/chromeos/strings/chromeos_strings_bn.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> এই ব্যবহারকারীকে ম্যানেজ করে এবং তার ফলে এটি হয়ত অন্য জায়গা থেকে সেটিংস ম্যানেজ করতে এবং ব্যবহারকারীর অ্যাক্টিভিটির উপর নজর রাখতে পারে।</translation>
 <translation id="150962533380566081">ভুল PUK।</translation>
 <translation id="1510238584712386396">লঞ্চার</translation>
+<translation id="1600964289716072707">পৃষ্ঠা যোগ করতে স্ক্যানারে আপনার ডকুমেন্ট রেখে 'স্ক্যান করুন' বিকল্পটি বেছে নিন।</translation>
 <translation id="1621067168122174824">চার্জ টেস্ট করুন</translation>
 <translation id="1641857168437328880">ডকুমেন্ট ফিডার (এক পিঠের)</translation>
 <translation id="1644574205037202324">ইতিহাস</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">DNS রেজোলিউশন সফল হয়নি</translation>
 <translation id="6768237774506518020">DNS রেজোলিউশনের বেশি ফেল রেট</translation>
 <translation id="6853312040151791195">ডিসচার্জ হওয়ার রেট</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> এ ফিরুন</translation>
 <translation id="6910312834584889076">স্ক্যানারের কভার খোলা আছে। কভার বন্ধ করে আবার চেষ্টা করুন।</translation>
 <translation id="6911383237894364323">মিডিয়া সার্ভারে কানেক্ট করা যায়নি</translation>
 <translation id="6957231940976260713">পরিষেবার নাম</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">মডেল আইডি</translation>
 <translation id="7805768142964895445">স্থিতি</translation>
 <translation id="7819857487979277519">PSK (WPA বা RSN)</translation>
+<translation id="7835501727204647447">CloudReady ইনস্টল করুন</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">পরিষেবা প্রদানকারীর ধরন</translation>
 <translation id="7936303884198020182">ডোমেন নেম সার্ভার খুঁজে পাওয়া যায়নি</translation>
diff --git a/chromeos/strings/chromeos_strings_bs.xtb b/chromeos/strings/chromeos_strings_bs.xtb
index 4444613..5758b97 100644
--- a/chromeos/strings/chromeos_strings_bs.xtb
+++ b/chromeos/strings/chromeos_strings_bs.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Nema internetske veze</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Status aktivacije</translation>
+<translation id="2294675138977897428">Veza s Ethernetom nije otkrivena</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Uključite Bluetooth da otkrijete uređaje u blizini</translation>
 <translation id="2364498172489649528">Uspješno</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Nepoznati sigurnosni protokol za WiFi</translation>
 <translation id="65587193855025101">Položeno</translation>
 <translation id="6564646048574748301">Nije uspjelo – štampač je nedostupan</translation>
+<translation id="6603230386432466813">Imate li problema s povezivanjem?</translation>
 <translation id="6618744767048954150">Pokrenuto</translation>
 <translation id="6620487321149975369">Zadaci za štampanje će se pojaviti u historiji osim ako ih ne uklonite ručno</translation>
 <translation id="6643016212128521049">Obriši</translation>
diff --git a/chromeos/strings/chromeos_strings_cs.xtb b/chromeos/strings/chromeos_strings_cs.xtb
index 1834c23..9a961d5 100644
--- a/chromeos/strings/chromeos_strings_cs.xtb
+++ b/chromeos/strings/chromeos_strings_cs.xtb
@@ -72,7 +72,7 @@
 <translation id="2448312741937722512">Typ</translation>
 <translation id="2461822463642141190">Aktuální</translation>
 <translation id="249323605434939166"><ph name="QUERY_TEXT" /> · <ph name="SOURCE_LANGUAGE_NAME" /></translation>
-<translation id="2517472476991765520">Vyhledat</translation>
+<translation id="2517472476991765520">Naskenovat</translation>
 <translation id="2570743873672969996">Běží test <ph name="TEST_NAME" />…</translation>
 <translation id="2585245331261708204">Novinky v Chrome OS</translation>
 <translation id="2620436844016719705">Systém</translation>
diff --git a/chromeos/strings/chromeos_strings_de.xtb b/chromeos/strings/chromeos_strings_de.xtb
index 1b80d33..5e6ebf2 100644
--- a/chromeos/strings/chromeos_strings_de.xtb
+++ b/chromeos/strings/chromeos_strings_de.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> verwaltet diesen Nutzer und kann per Remotezugriff Einstellungen ändern und die Nutzeraktivität überwachen.</translation>
 <translation id="150962533380566081">Ungültiger PUK.</translation>
 <translation id="1510238584712386396">Launcher</translation>
+<translation id="1600964289716072707">Legen Sie eine andere Seite in den Scanner und wählen Sie „Scannen“ aus, um die Seite hinzuzufügen.</translation>
 <translation id="1621067168122174824">Ladetest ausführen</translation>
 <translation id="1641857168437328880">Dokumenteneinzug (einseitig)</translation>
 <translation id="1644574205037202324">Verlauf</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">Fehlgeschlagene DNS-Auflösungen</translation>
 <translation id="6768237774506518020">Hohe Fehlerrate bei der DNS-Auflösung</translation>
 <translation id="6853312040151791195">Entladestrom</translation>
+<translation id="6905724422583748843">Zurück zu <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">Die Abdeckung des Scanners ist offen. Schließen Sie sie und versuchen Sie es noch einmal.</translation>
 <translation id="6911383237894364323">Verbindung zu Medienservern kann nicht hergestellt werden</translation>
 <translation id="6957231940976260713">Name des Dienstes</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">Modell-ID</translation>
 <translation id="7805768142964895445">Status</translation>
 <translation id="7819857487979277519">PSK (WPA oder RSN)</translation>
+<translation id="7835501727204647447">CloudReady installieren</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Providertyp</translation>
 <translation id="7936303884198020182">Es wurden keine Nameserver gefunden</translation>
diff --git a/chromeos/strings/chromeos_strings_es-419.xtb b/chromeos/strings/chromeos_strings_es-419.xtb
index 36671d1..e298287 100644
--- a/chromeos/strings/chromeos_strings_es-419.xtb
+++ b/chromeos/strings/chromeos_strings_es-419.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> administra a este usuario y es posible que administre la configuración y supervise la actividad del usuario de forma remota.</translation>
 <translation id="150962533380566081">PUK no válida.</translation>
 <translation id="1510238584712386396">Selector</translation>
+<translation id="1600964289716072707">Coloca otra página en el escáner y seleccionar Escanear para agregar la página.</translation>
 <translation id="1621067168122174824">Ejecutar prueba de carga</translation>
 <translation id="1641857168437328880">Alimentador de documentos (una cara)</translation>
 <translation id="1644574205037202324">Historial</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">Resoluciones DNS con error</translation>
 <translation id="6768237774506518020">Tasa alta de errores para la resolución de DNS</translation>
 <translation id="6853312040151791195">Velocidad de descarga</translation>
+<translation id="6905724422583748843">Volver a <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">La tapa del escáner está abierta. Ciérrala y vuelve a intentarlo.</translation>
 <translation id="6911383237894364323">No es posible conectarse a los servidores de medios</translation>
 <translation id="6957231940976260713">Nombre del servicio</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">ID del modelo</translation>
 <translation id="7805768142964895445">Estado</translation>
 <translation id="7819857487979277519">PSK (WPA o RSN)</translation>
+<translation id="7835501727204647447">Instalar CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Tipo de proveedor</translation>
 <translation id="7936303884198020182">no se encontraron servidores de nombres</translation>
diff --git a/chromeos/strings/chromeos_strings_et.xtb b/chromeos/strings/chromeos_strings_et.xtb
index 5fc4721..551b1aed 100644
--- a/chromeos/strings/chromeos_strings_et.xtb
+++ b/chromeos/strings/chromeos_strings_et.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Interneti-ühendus puudub</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Aktiveerimise olek</translation>
+<translation id="2294675138977897428">Etherneti-ühendust ei õnnestunud tuvastada</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> DPI</translation>
 <translation id="2338501278241028356">Lülitage Bluetooth sisse, et läheduses olevaid seadmeid avastada</translation>
 <translation id="2364498172489649528">Läbitud</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Tundmatu WiFi-turvaprotokoll</translation>
 <translation id="65587193855025101">Tasaskanner</translation>
 <translation id="6564646048574748301">Ebaõnnestus – printeriga ei saa ühendust</translation>
+<translation id="6603230386432466813">Kas teil on ühenduse loomisega probleeme?</translation>
 <translation id="6618744767048954150">Pooleli</translation>
 <translation id="6620487321149975369">Prinditööd kuvatakse ajaloos, kui neid käsitsi ei eemaldata</translation>
 <translation id="6643016212128521049">Tühjenda</translation>
diff --git a/chromeos/strings/chromeos_strings_eu.xtb b/chromeos/strings/chromeos_strings_eu.xtb
index 4e6f320..51cee06 100644
--- a/chromeos/strings/chromeos_strings_eu.xtb
+++ b/chromeos/strings/chromeos_strings_eu.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> domeinuak kudeatzen du erabiltzaile hau, eta baliteke urrunetik haren ezarpenak kudeatzea eta jarduerak gainbegiratzea.</translation>
 <translation id="150962533380566081">PUK kodeak ez du balio.</translation>
 <translation id="1510238584712386396">Abiarazlea</translation>
+<translation id="1600964289716072707">Kokatu beste orri bat eskanerrean eta hautatu "Eskaneatu" orri hori gehitzeko.</translation>
 <translation id="1621067168122174824">Abiarazi kargatzeko prozesuaren proba</translation>
 <translation id="1641857168437328880">Dokumentu-elikatzailea (alde bakarrekoa)</translation>
 <translation id="1644574205037202324">Historia</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">huts egin dute DNS bidezko ebazpenek</translation>
 <translation id="6768237774506518020">DNS bidezko ebazpenen hutsegite-tasa altua</translation>
 <translation id="6853312040151791195">Bateriaren deskargatze-abiadura</translation>
+<translation id="6905724422583748843">Itzuli <ph name="PAGE_NAME" /> orrira</translation>
 <translation id="6910312834584889076">Eskanerraren estalkia irekita dago. Itxi ezazu eta saiatu berriro.</translation>
 <translation id="6911383237894364323">Ezin da konektatu multimedia-zerbitzarietara</translation>
 <translation id="6957231940976260713">Zerbitzuaren izena</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">Modeloaren IDa</translation>
 <translation id="7805768142964895445">Egoera</translation>
 <translation id="7819857487979277519">PSK (WPA edo RSN)</translation>
+<translation id="7835501727204647447">Instalatu CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Hornitzaile mota</translation>
 <translation id="7936303884198020182">Ez da aurkitu izenen zerbitzaririk</translation>
diff --git a/chromeos/strings/chromeos_strings_fr.xtb b/chromeos/strings/chromeos_strings_fr.xtb
index 4f7b148..44e92a6 100644
--- a/chromeos/strings/chromeos_strings_fr.xtb
+++ b/chromeos/strings/chromeos_strings_fr.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> gère cet utilisateur dont il peut modifier les paramètres et surveiller l'activité à distance.</translation>
 <translation id="150962533380566081">Clé PUK incorrecte.</translation>
 <translation id="1510238584712386396">Lanceur d'applications</translation>
+<translation id="1600964289716072707">Placez une autre page sur le scanner, puis sélectionnez "Scanner" pour ajouter une page.</translation>
 <translation id="1621067168122174824">Lancer le test de recharge</translation>
 <translation id="1641857168437328880">Chargeur de document (recto)</translation>
 <translation id="1644574205037202324">Historique</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">Échec de résolutions DNS</translation>
 <translation id="6768237774506518020">Taux d'échec élevé des résolutions DNS</translation>
 <translation id="6853312040151791195">Vitesse de décharge</translation>
+<translation id="6905724422583748843">Revenir à <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">Le capot du scanner est ouvert. Refermez-le, puis réessayez.</translation>
 <translation id="6911383237894364323">Impossible de se connecter aux serveurs multimédias</translation>
 <translation id="6957231940976260713">Nom du service</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">ID du modèle</translation>
 <translation id="7805768142964895445">État</translation>
 <translation id="7819857487979277519">PSK (WPA ou RSN)</translation>
+<translation id="7835501727204647447">Installer CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Type de fournisseur</translation>
 <translation id="7936303884198020182">Aucun serveur de noms trouvé</translation>
diff --git a/chromeos/strings/chromeos_strings_gl.xtb b/chromeos/strings/chromeos_strings_gl.xtb
index ac7fbfa..793c8f7 100644
--- a/chromeos/strings/chromeos_strings_gl.xtb
+++ b/chromeos/strings/chromeos_strings_gl.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> xestiona este usuario, e pode axustar a súa configuración e supervisar a súa actividade de forma remota.</translation>
 <translation id="150962533380566081">O PUK non é válido.</translation>
 <translation id="1510238584712386396">Menú de aplicacións</translation>
+<translation id="1600964289716072707">Se queres engadir outra páxina, colócaa no escáner e selecciona Escanear.</translation>
 <translation id="1621067168122174824">Realizar proba de carga</translation>
 <translation id="1641857168437328880">Alimentador de documentos (a unha cara)</translation>
 <translation id="1644574205037202324">Historial</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">Produciuse un erro coas resolucións de DNS</translation>
 <translation id="6768237774506518020">Hai un alto índice de erros relacionados coas resolucións de DNS</translation>
 <translation id="6853312040151791195">Taxa de descarga</translation>
+<translation id="6905724422583748843">Volver a <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">A tapa do escáner está aberta. Péchaa e téntao de novo.</translation>
 <translation id="6911383237894364323">Non se puido establecer conexión cos servidores multimedia</translation>
 <translation id="6957231940976260713">Nome do servizo</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">ID do modelo</translation>
 <translation id="7805768142964895445">Estado</translation>
 <translation id="7819857487979277519">PSK (WPA ou RSN)</translation>
+<translation id="7835501727204647447">Instalar CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Tipo de fornecedor</translation>
 <translation id="7936303884198020182">Non se atoparon servidores de nomes</translation>
diff --git a/chromeos/strings/chromeos_strings_gu.xtb b/chromeos/strings/chromeos_strings_gu.xtb
index 863cbc3..7a18d59 100644
--- a/chromeos/strings/chromeos_strings_gu.xtb
+++ b/chromeos/strings/chromeos_strings_gu.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> આ વપરાશકર્તાને મેનેજ કરે છે તથા સેટિંગ અને વપરાશકર્તાની પ્રવૃત્તિને દૂરથી મેનેજ અને તેનું નિરીક્ષણ કરે એવું બની શકે.</translation>
 <translation id="150962533380566081">અમાન્ય PUK.</translation>
 <translation id="1510238584712386396">લૉન્ચર</translation>
+<translation id="1600964289716072707">અન્ય પેજને સ્કૅનર પર મૂકો અને પેજ ઉમેરવા માટે 'સ્કૅન કરો' પસંદ કરો.</translation>
 <translation id="1621067168122174824">ચાર્જિંગનું પરીક્ષણ ચાલુ કરો</translation>
 <translation id="1641857168437328880">દસ્તાવેજનું ફીડર (એક બાજુથી)</translation>
 <translation id="1644574205037202324">ઇતિહાસ</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">નિષ્ફળ રહેલા DNS રિઝોલ્યુશન</translation>
 <translation id="6768237774506518020">DNS રિઝોલ્યુશન નિષ્ફળતાનો ઉચ્ચ રેટ</translation>
 <translation id="6853312040151791195">ડિસ્ચાર્જ થવાની ટકાવારી</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> પર પાછા જાઓ</translation>
 <translation id="6910312834584889076">સ્કૅનરનું કવર ખુલ્લું છે. કવર બંધ કરો અને ફરી પ્રયાસ કરો.</translation>
 <translation id="6911383237894364323">મીડિયા સર્વર સાથે કનેક્ટ કરી શકાયું નથી</translation>
 <translation id="6957231940976260713">સેવાનું નામ</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">મોડલ ID</translation>
 <translation id="7805768142964895445">સ્થિતિ</translation>
 <translation id="7819857487979277519">PSK (WPA અથવા RSN)</translation>
+<translation id="7835501727204647447">CloudReady ઇન્સ્ટૉલ કરો</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">પ્રદાતાનો પ્રકાર</translation>
 <translation id="7936303884198020182">IP કન્ફિગ્યુરેશનમાં કોઈ નામ સર્વર મળ્યા નથી</translation>
diff --git a/chromeos/strings/chromeos_strings_hr.xtb b/chromeos/strings/chromeos_strings_hr.xtb
index d696a78..5eb0dafe 100644
--- a/chromeos/strings/chromeos_strings_hr.xtb
+++ b/chromeos/strings/chromeos_strings_hr.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Nema interneta</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Status aktivacije</translation>
+<translation id="2294675138977897428">Veza s Ethernetom nije otkrivena</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Uključite Bluetooth da biste otkrili uređaje u blizini</translation>
 <translation id="2364498172489649528">Uspješno</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Nepoznat sigurnosni protokol za Wi-Fi</translation>
 <translation id="65587193855025101">Plošni skener</translation>
 <translation id="6564646048574748301">Nije uspjelo – pisač nije dostupan</translation>
+<translation id="6603230386432466813">Imate li problema s povezivanjem?</translation>
 <translation id="6618744767048954150">U tijeku</translation>
 <translation id="6620487321149975369">Zadaci ispisa prikazivat će se u povijesti ako se ne uklone ručno</translation>
 <translation id="6643016212128521049">Izbriši</translation>
diff --git a/chromeos/strings/chromeos_strings_ml.xtb b/chromeos/strings/chromeos_strings_ml.xtb
index c40b695..5a8feb5 100644
--- a/chromeos/strings/chromeos_strings_ml.xtb
+++ b/chromeos/strings/chromeos_strings_ml.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> ആണ് ഈ ഉപയോക്താവിനെ മാനേജ് ചെയ്യുന്നത്, ഒപ്പം വിദൂരമായി ക്രമീകരണം മാനേജ് ചെയ്യുകയും ഉപയോക്തൃ ആക്‌റ്റിവിറ്റി നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം.</translation>
 <translation id="150962533380566081">അസാധുവായ PUK.</translation>
 <translation id="1510238584712386396">ലോഞ്ചർ</translation>
+<translation id="1600964289716072707">സ്കാനറിൽ മറ്റൊരു പേജ് വയ്‌ക്കുക, പേജ് ചേർക്കാൻ സ്‌കാൻ ചെയ്യുക തിരഞ്ഞെടുക്കുക.</translation>
 <translation id="1621067168122174824">ചാർജ് ടെസ്റ്റ് റൺ ചെയ്യുക</translation>
 <translation id="1641857168437328880">ഡോക്യുമെന്റ് ഫീഡർ (ഒരു വശമുള്ളത്)</translation>
 <translation id="1644574205037202324">ചരിത്രം</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">പരാജയപ്പെട്ട DNS റെസല്യൂഷനുകൾ</translation>
 <translation id="6768237774506518020">ഉയർന്ന DNS റെസല്യൂഷൻ ഫെയ്‌ലിയർ നിരക്ക്</translation>
 <translation id="6853312040151791195">ഡിസ്‌ചാർജ് ചെയ്യൽ റേറ്റ്</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> എന്ന പേജിലേക്ക് മടങ്ങുക</translation>
 <translation id="6910312834584889076">സ്‌കാനറിന്റെ കവർ തുറന്നിരിക്കുന്നു. കവർ അടച്ച് വീണ്ടും ശ്രമിക്കുക.</translation>
 <translation id="6911383237894364323">മീഡിയ സെർവറുകളിലേക്ക് കണക്റ്റ് ചെയ്യാനാകുന്നില്ല</translation>
 <translation id="6957231940976260713">സേവനത്തിന്‍റെ പേര്</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">മോഡൽ ഐഡി</translation>
 <translation id="7805768142964895445">നില</translation>
 <translation id="7819857487979277519">PSK (WPA അല്ലെങ്കിൽ RSN)</translation>
+<translation id="7835501727204647447">CloudReady ഇൻസ്‌റ്റാൾ ചെയ്യുക</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">പ്രൊവൈഡര്‍ തരം:</translation>
 <translation id="7936303884198020182">നെയിം സെർവറുകളൊന്നും കണ്ടെത്തിയില്ല</translation>
diff --git a/chromeos/strings/chromeos_strings_mn.xtb b/chromeos/strings/chromeos_strings_mn.xtb
index 22f7c14..e417842 100644
--- a/chromeos/strings/chromeos_strings_mn.xtb
+++ b/chromeos/strings/chromeos_strings_mn.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Интернэт алга</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Идэвхжүүлэх статус</translation>
+<translation id="2294675138977897428">Этернэт холболт илэрсэнгүй</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Ойролцоох төхөөрөмж хайхын тулд Bluetooth-г асаана уу</translation>
 <translation id="2364498172489649528">Давсан</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">WiFi-н аюулгүй байдлын үл мэдэгдэх протокол</translation>
 <translation id="65587193855025101">Тавцант</translation>
 <translation id="6564646048574748301">Амжилтгүй болсон - Хэвлэгчид холбогдох боломжгүй</translation>
+<translation id="6603230386432466813">Холбогдоход асуудал гарсан уу?</translation>
 <translation id="6618744767048954150">Ажиллуулж байна</translation>
 <translation id="6620487321149975369">Хэвлэлийн ажлыг гараар хасахгүй бол түүхэнд харагдана</translation>
 <translation id="6643016212128521049">Цэвэрлэх</translation>
diff --git a/chromeos/strings/chromeos_strings_ne.xtb b/chromeos/strings/chromeos_strings_ne.xtb
index 01d5c55..b1bf181 100644
--- a/chromeos/strings/chromeos_strings_ne.xtb
+++ b/chromeos/strings/chromeos_strings_ne.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> ले यो डिभाइस व्यवस्थापन गर्छ र यसले टाढैबाट सेटिङ व्यवस्थापन गर्न र प्रयोगकर्ताले गर्ने क्रियाकलाप निगरानी गर्न सक्छ।</translation>
 <translation id="150962533380566081">अमान्य PUK।</translation>
 <translation id="1510238584712386396">लन्चर</translation>
+<translation id="1600964289716072707">स्क्यानरमा अर्को पेज राख्नुहोस् र पेज थप्न "स्क्यान गर्नुहोस्" विकल्प चयन गर्नुहोस्।</translation>
 <translation id="1621067168122174824">ब्याट्रीको चार्जसम्बन्धी परीक्षण गर्नुहोस्</translation>
 <translation id="1641857168437328880">डकुमेन्ट फिडर (एकतर्फी)</translation>
 <translation id="1644574205037202324">इतिहास</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">DNS रिजोल्युसन पूरा हुन सकेनन्</translation>
 <translation id="6768237774506518020">DNS रिजोल्युसन पूरा हुन नसक्ने दर उच्च छ</translation>
 <translation id="6853312040151791195">डिस्चार्ज हुने दर</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> मा फर्कनुहोस्</translation>
 <translation id="6910312834584889076">स्क्यानरको कभर खुला छ। कभर लगाउनुहोस् र फेरि प्रयास गर्नुहोस्।</translation>
 <translation id="6911383237894364323">मिडिया सर्भरहरूमा कनेक्ट गर्न सकिएन</translation>
 <translation id="6957231940976260713">सेवाको नाम</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">मोडेलको ID</translation>
 <translation id="7805768142964895445">स्थिति</translation>
 <translation id="7819857487979277519">PSK (WPA वा RSN)</translation>
+<translation id="7835501727204647447">CloudReady इन्स्टल गर्नुहोस्</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">प्रदायकको प्रकार</translation>
 <translation id="7936303884198020182">कुनै पनि डोमेन नेम सर्भर फेला परेन</translation>
diff --git a/chromeos/strings/chromeos_strings_nl.xtb b/chromeos/strings/chromeos_strings_nl.xtb
index bddfe14b..bd8d7a9 100644
--- a/chromeos/strings/chromeos_strings_nl.xtb
+++ b/chromeos/strings/chromeos_strings_nl.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Geen internet</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Activeringsstatus</translation>
+<translation id="2294675138977897428">Geen ethernetverbinding gevonden</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Zet Bluetooth aan om apparaten in de buurt te vinden</translation>
 <translation id="2364498172489649528">Geslaagd</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Onbekend wifi-beveiligingsprotocol</translation>
 <translation id="65587193855025101">Flatbed</translation>
 <translation id="6564646048574748301">Mislukt - Printer is niet bereikbaar</translation>
+<translation id="6603230386432466813">Heb je problemen met verbinding maken?</translation>
 <translation id="6618744767048954150">Wordt uitgevoerd</translation>
 <translation id="6620487321149975369">Afdruktaken zie je in de geschiedenis, tenzij ze handmatig worden verwijderd</translation>
 <translation id="6643016212128521049">Wissen</translation>
diff --git a/chromeos/strings/chromeos_strings_or.xtb b/chromeos/strings/chromeos_strings_or.xtb
index 3febd6292..51cb5d3 100644
--- a/chromeos/strings/chromeos_strings_or.xtb
+++ b/chromeos/strings/chromeos_strings_or.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ପରିଚାଳନା କରେ ଏବଂ ରିମୋଟ୍ ଭାବେ ସେଟିଂସକୁ ପରିଚାଳନା ଏବଂ ଉପଯୋଗକର୍ତ୍ତା କାର୍ଯ୍ୟକଳାପକୁ ନିରୀକ୍ଷଣ କରିପାରେ।</translation>
 <translation id="150962533380566081">ଅବୈଧ PUK।</translation>
 <translation id="1510238584712386396">ଲଞ୍ଚର୍</translation>
+<translation id="1600964289716072707">ପୃଷ୍ଠା ଯୋଗ କରିବା ପାଇଁ ଅନ୍ୟ ଏକ ପୃଷ୍ଠାକୁ ସ୍କାନରରେ ରଖି 'ସ୍କାନ୍ କରନ୍ତୁ'କୁ ଚୟନ କରନ୍ତୁ।</translation>
 <translation id="1621067168122174824">ବ୍ୟାଟେରୀ ଚାର୍ଜ ଟେଷ୍ଟ ଚଲାନ୍ତୁ</translation>
 <translation id="1641857168437328880">ଡକ୍ୟୁମେଣ୍ଟ ଫିଡର୍ (ଗୋଟିଏ-ପାର୍ଶ୍ୱ)</translation>
 <translation id="1644574205037202324">ଇତିବୃତ୍ତି</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">ବିଫଳ ହୋଇଥିବା DNS ରିଜୋଲ୍ୟୁସନ୍</translation>
 <translation id="6768237774506518020">ଉଚ୍ଚ DNS ରିଜୋଲ୍ୟୁସନ୍ ବିଫଳତା ହାର</translation>
 <translation id="6853312040151791195">ଡିସଚାର୍ଜିଂ ରେଟ୍</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" />କୁ ଫେରନ୍ତୁ</translation>
 <translation id="6910312834584889076">ସ୍କାନରର କଭର୍ ଖୋଲା ଅଛି। କଭର୍ ବନ୍ଦ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।</translation>
 <translation id="6911383237894364323">ମିଡିଆ ସର୍ଭରଗୁଡ଼ିକ ସହ ସଂଯୋଗ କରିବାକୁ ଅସମର୍ଥ</translation>
 <translation id="6957231940976260713">ସେବାର ନାମ</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">ମଡେଲ୍ ID</translation>
 <translation id="7805768142964895445">ସ୍ଥିତି</translation>
 <translation id="7819857487979277519">PSK (WPA or RSN)</translation>
+<translation id="7835501727204647447">CloudReady ଇନଷ୍ଟଲ୍ କରନ୍ତୁ</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">ପ୍ରଦାତା ପ୍ରକାର</translation>
 <translation id="7936303884198020182">କୌଣସି ନେମ୍ ସର୍ଭର୍ ମିଳୁ ନାହିଁ</translation>
diff --git a/chromeos/strings/chromeos_strings_pa.xtb b/chromeos/strings/chromeos_strings_pa.xtb
index 32b3ad6..1aa28b6d 100644
--- a/chromeos/strings/chromeos_strings_pa.xtb
+++ b/chromeos/strings/chromeos_strings_pa.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> ਇਸ ਵਰਤੋਂਕਾਰ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਦੂਰ-ਦਰਾਡੇ ਤੋਂ ਸੈਟਿੰਗਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਅਤੇ ਵਰਤੋਂਕਾਰ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।</translation>
 <translation id="150962533380566081">ਅਵੈਧ PUK।</translation>
 <translation id="1510238584712386396">ਲੌਂਚਰ</translation>
+<translation id="1600964289716072707">ਹੋਰ ਪੰਨੇ ਨੂੰ ਸਕੈਨਰ 'ਤੇ ਰੱਖੋ ਅਤੇ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਸਕੈਨ ਕਰੋ ਚੁਣੋ</translation>
 <translation id="1621067168122174824">ਚਾਰਜ ਟੈਸਟ ਚਲਾਓ</translation>
 <translation id="1641857168437328880">ਦਸਤਾਵੇਜ਼ ਫ਼ੀਡਰ (ਇੱਕ ਪਾਸੜ)</translation>
 <translation id="1644574205037202324">ਇਤਿਹਾਸ</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">ਅਸਫਲ DNS ਰੈਜ਼ੋਲਿਊਸ਼ਨ</translation>
 <translation id="6768237774506518020">DNS ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਦੀ ਉੱਚ ਅਸਫਲ ਦਰ</translation>
 <translation id="6853312040151791195">ਡਿਸਚਾਰਜ ਹੋਣ ਦੀ ਦਰ</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> 'ਤੇ ਵਾਪਸ ਜਾਓ</translation>
 <translation id="6910312834584889076">ਸਕੈਨਰ ਦਾ ਕਵਰ ਖੁੱਲ੍ਹਾ ਹੈ। ਕਵਰ ਬੰਦ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।</translation>
 <translation id="6911383237894364323">ਮੀਡੀਆ ਸਰਵਰਾਂ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</translation>
 <translation id="6957231940976260713">ਸੇਵਾ ਦਾ ਨਾਮ</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">ਮਾਡਲ ਆਈ.ਡੀ.</translation>
 <translation id="7805768142964895445">ਸਥਿਤੀ</translation>
 <translation id="7819857487979277519">PSK (WPA ਜਾਂ RSN)</translation>
+<translation id="7835501727204647447">CloudReady ਨੂੰ ਸਥਾਪਤ ਕਰੋ</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">ਪ੍ਰਦਾਨਕ ਕਿਸਮ</translation>
 <translation id="7936303884198020182">ਕੋਈ ਨਾਮ ਸਰਵਰ ਨਹੀਂ ਮਿਲਿਆ</translation>
diff --git a/chromeos/strings/chromeos_strings_si.xtb b/chromeos/strings/chromeos_strings_si.xtb
index 8e56411..c7693dd 100644
--- a/chromeos/strings/chromeos_strings_si.xtb
+++ b/chromeos/strings/chromeos_strings_si.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">අන්තර්ජාලය නැත</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">සක්‍රිය කිරීමේ තත්ත්වය</translation>
+<translation id="2294675138977897428">ඊතර්නෙට් සම්බන්ධතාවක් අනාවරණය කර නොගන්නා ලදී</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">අවට උපාංග සොයා ගැනීමට බ්ලූටූත් ක්‍රියාත්මක කරන්න</translation>
 <translation id="2364498172489649528">සමත් විය</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">නොදන්නා Wi-Fi ආරක්ෂක ප්‍රොටොකෝලය</translation>
 <translation id="65587193855025101">Flatbed</translation>
 <translation id="6564646048574748301">අසාර්ථක විය - මුද්‍රණ යන්ත්‍රය වෙත ළඟා විය නොහැකිය</translation>
+<translation id="6603230386432466813">සම්බන්ධ වීමේ ගැටලුවක් තිබේද?</translation>
 <translation id="6618744767048954150">ධාවන වේ</translation>
 <translation id="6620487321149975369">මුද්‍රණ කාර්ය අතින් ඉවත් නොකළහොත් ඉතිහාසයේ දිස්වනු ඇත</translation>
 <translation id="6643016212128521049">මකන්න</translation>
diff --git a/chromeos/strings/chromeos_strings_sq.xtb b/chromeos/strings/chromeos_strings_sq.xtb
index 9319951..c4fdd85 100644
--- a/chromeos/strings/chromeos_strings_sq.xtb
+++ b/chromeos/strings/chromeos_strings_sq.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> menaxhon këtë përdorues dhe mund të menaxhojë në distancë cilësimet dhe të monitorojë aktivitetin e përdoruesit.</translation>
 <translation id="150962533380566081">Kodi PUK i pavlefshëm.</translation>
 <translation id="1510238584712386396">Nisësi</translation>
+<translation id="1600964289716072707">Vendos një faqe tjetër në skaner dhe zgjidh "Skano" për të shtuar faqen.</translation>
 <translation id="1621067168122174824">Ekzekuto testin e karikimit</translation>
 <translation id="1641857168437328880">Furnizuesi i dokumentit (një anë)</translation>
 <translation id="1644574205037202324">Historiku</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">Rezolucione të dështuara të DNS-së</translation>
 <translation id="6768237774506518020">Normë e lartë e rezolucioneve të dështuara të DNS-së</translation>
 <translation id="6853312040151791195">Shpejtësia e shkarkimit</translation>
+<translation id="6905724422583748843">Prapa te <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">Kapaku i skanerit është i hapur. Mbylle kapakun dhe provo përsëri.</translation>
 <translation id="6911383237894364323">Nuk mund të lidhet me serverët e medias.</translation>
 <translation id="6957231940976260713">Emri i shërbimit</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">ID-ja e modelit</translation>
 <translation id="7805768142964895445">Statusi</translation>
 <translation id="7819857487979277519">PSK (WPA ose RSN)</translation>
+<translation id="7835501727204647447">Instalo CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">Lloji i ofruesit</translation>
 <translation id="7936303884198020182">Nuk u gjetën serverë DNS</translation>
diff --git a/chromeos/strings/chromeos_strings_ta.xtb b/chromeos/strings/chromeos_strings_ta.xtb
index 59e818c8..6ed379c 100644
--- a/chromeos/strings/chromeos_strings_ta.xtb
+++ b/chromeos/strings/chromeos_strings_ta.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732">இந்தப் பயனரை <ph name="MANAGER" /> நிர்வகிக்கிறது. இது தொலைநிலையிலிருந்து அமைப்புகளை நிர்வகிக்கலாம், அத்துடன் பயனர் செயல்பாட்டையும் கண்காணிக்கலாம்.</translation>
 <translation id="150962533380566081">தவறான PUK.</translation>
 <translation id="1510238584712386396">துவக்கி</translation>
+<translation id="1600964289716072707">பக்கத்தைச் சேர்க்க, ஸ்கேனரில் வேறொரு பக்கத்தை வைத்துவிட்டு 'ஸ்கேன் செய்' என்பதைத் தேர்ந்தெடுக்கவும்.</translation>
 <translation id="1621067168122174824">சார்ஜ் சோதனையை இயக்கு</translation>
 <translation id="1641857168437328880">டாக்குமெண்ட் ஃபீடர் (ஒரு பக்கம்)</translation>
 <translation id="1644574205037202324">வரலாறு</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">DNS ரெசல்யூஷன்கள் தோல்வி அடைந்தது</translation>
 <translation id="6768237774506518020">DNS ரெசல்யூஷன் தோல்வி விகிதம் அதிகமாக உள்ளது</translation>
 <translation id="6853312040151791195">சார்ஜ் இறங்கும் விகிதம்</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> பக்கத்திற்குச் செல்லும்</translation>
 <translation id="6910312834584889076">ஸ்கேனரின் கவர் திறந்துள்ளது. கவரை மூடிவிட்டு மீண்டும் முயலவும்.</translation>
 <translation id="6911383237894364323">மீடியா சேவையகங்களுடன் இணைக்க முடியவில்லை</translation>
 <translation id="6957231940976260713">சேவைப் பெயர்</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">மாடல் ஐடி</translation>
 <translation id="7805768142964895445">நிலை</translation>
 <translation id="7819857487979277519">PSK (WPA அல்லது RSN)</translation>
+<translation id="7835501727204647447">CloudReadyயை நிறுவு</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">வழங்குநர் வகை</translation>
 <translation id="7936303884198020182">பெயர் சேவையகங்கள் எதுவும் இல்லை</translation>
diff --git a/chromeos/strings/chromeos_strings_te.xtb b/chromeos/strings/chromeos_strings_te.xtb
index c2973f3..1fb1f42 100644
--- a/chromeos/strings/chromeos_strings_te.xtb
+++ b/chromeos/strings/chromeos_strings_te.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" />, ఈ యూజర్‌ను మేనేజ్ చేస్తుంది, ఇంకా అది సెట్టింగ్‌లను రిమోట్‌గా మేనేజ్ చేయవచ్చు, యూజర్ యాక్టివిటీని మానిటర్ చేయవచ్చు.</translation>
 <translation id="150962533380566081">PUK చెల్లదు.</translation>
 <translation id="1510238584712386396">లాంచర్</translation>
+<translation id="1600964289716072707">పేజీని జోడించడానికి, స్కానర్‌పై మరొక పేజీని పెట్టి, 'స్కాన్ చేయండి' ఆప్షన్‌ను ఎంచుకోండి.</translation>
 <translation id="1621067168122174824">ఛార్జ్ పరీక్షను రన్ చేయండి</translation>
 <translation id="1641857168437328880">డాక్యుమెంట్ ఫీడర్ (ఒక వైపున)</translation>
 <translation id="1644574205037202324">హిస్టరీ</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">విఫలమైన DNS రిజల్యూషన్‌లు</translation>
 <translation id="6768237774506518020">అధిక DNS రిజల్యూషన్ వైఫల్య రేటు</translation>
 <translation id="6853312040151791195">డిశ్చార్జింగ్ రేట్</translation>
+<translation id="6905724422583748843">తిరిగి <ph name="PAGE_NAME" />‌కు</translation>
 <translation id="6910312834584889076">స్కానర్ కవర్ తెరిచి ఉంది. కవర్‌ను మూసివేసి, మళ్లీ ట్రై చేయండి.</translation>
 <translation id="6911383237894364323">మీడియా సర్వర్‌లకు కనెక్ట్ చేయడం సాధ్యం కాలేదు</translation>
 <translation id="6957231940976260713">సేవ పేరు</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">మోడల్ ID</translation>
 <translation id="7805768142964895445">స్థితి</translation>
 <translation id="7819857487979277519">PSK (WPA లేదా RSN)</translation>
+<translation id="7835501727204647447">CloudReadyని ఇన్‌స్టాల్ చేయండి</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">ప్రదాత రకం</translation>
 <translation id="7936303884198020182">పేరుతో సర్వర్‌లు కనుగొనబడలేదు</translation>
diff --git a/chromeos/strings/chromeos_strings_ur.xtb b/chromeos/strings/chromeos_strings_ur.xtb
index bb0527b..e2e45d89 100644
--- a/chromeos/strings/chromeos_strings_ur.xtb
+++ b/chromeos/strings/chromeos_strings_ur.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> اس صارف کا نظم کرتا ہے اور دور سے ترتیبات کا نظم اور صارف کی سرگرمی کو مانیٹر کر سکتا ہے۔</translation>
 <translation id="150962533380566081">‏غلط PUK۔</translation>
 <translation id="1510238584712386396">لانچر</translation>
+<translation id="1600964289716072707">اسکینر پر کوئی دوسرا صفحہ رکھیں اور صفحہ شامل کرنے کیلئے 'اسکین کریں' منتخب کریں۔</translation>
 <translation id="1621067168122174824">چارج ٹیسٹ چلائیں</translation>
 <translation id="1641857168437328880">دستاویز فیڈر (یک طرفہ)</translation>
 <translation id="1644574205037202324">سرگزشت</translation>
@@ -286,6 +287,7 @@
 <translation id="6766275201586212568">‏ناکام DNS ریزولیوشنز</translation>
 <translation id="6768237774506518020">‏DNS ریزولیوشن ناکام ہونے کی زیادہ شرح</translation>
 <translation id="6853312040151791195">ڈسچارج ہونے کی شرح</translation>
+<translation id="6905724422583748843"><ph name="PAGE_NAME" /> پر واپس جائیں</translation>
 <translation id="6910312834584889076">اسکینر کا سرورق کھلا ہوا ہے۔ سرورق کو بند کریں اور دوبارہ کوشش کریں۔</translation>
 <translation id="6911383237894364323">میڈیا سرورز سے منسلک ہونے سے قاصر</translation>
 <translation id="6957231940976260713">سروس کا نام</translation>
@@ -330,6 +332,7 @@
 <translation id="7769672763586021400">‏ماڈل ID</translation>
 <translation id="7805768142964895445">صورتحال</translation>
 <translation id="7819857487979277519">‏‫‫PSK‎‏ (WPA یا RSN)‏</translation>
+<translation id="7835501727204647447">‏CloudReady انسٹال کریں</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">فراہم کنندہ کی قسم</translation>
 <translation id="7936303884198020182">کوئی نام سرور نہیں ملا</translation>
diff --git a/chromeos/strings/chromeos_strings_uz.xtb b/chromeos/strings/chromeos_strings_uz.xtb
index 57b3620..7db4f1d 100644
--- a/chromeos/strings/chromeos_strings_uz.xtb
+++ b/chromeos/strings/chromeos_strings_uz.xtb
@@ -63,6 +63,7 @@
 <translation id="2224337661447660594">Internet yo‘q</translation>
 <translation id="2230051135190148440">CHAP</translation>
 <translation id="225692081236532131">Aktivatsiya holati</translation>
+<translation id="2294675138977897428">Ethermet aloqasi aniqlanmadi</translation>
 <translation id="2326139988748364651"><ph name="RESOLUTION_VALUE" /> dpi</translation>
 <translation id="2338501278241028356">Yaqin-atrofdagi qurilmalarni aniqlash uchun Bluetooth adapterini yoqing</translation>
 <translation id="2364498172489649528">Tugadi</translation>
@@ -278,6 +279,7 @@
 <translation id="6527081081771465939">Notanish WiFi xavfsizlik protokoli</translation>
 <translation id="65587193855025101">Planshetli</translation>
 <translation id="6564646048574748301">Bajarilmadi - Printer ulanmagan</translation>
+<translation id="6603230386432466813">Ulanishda muammo bormi?</translation>
 <translation id="6618744767048954150">Bajarilmoqda</translation>
 <translation id="6620487321149975369">Chop etish vazifalari mustaqil olib tashlanmagucha tarix sahifasida chiqadi</translation>
 <translation id="6643016212128521049">Tozalash</translation>
diff --git a/chromeos/strings/chromeos_strings_zh-CN.xtb b/chromeos/strings/chromeos_strings_zh-CN.xtb
index 3ca10ba1..4b5f3a9 100644
--- a/chromeos/strings/chromeos_strings_zh-CN.xtb
+++ b/chromeos/strings/chromeos_strings_zh-CN.xtb
@@ -32,6 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> 负责管理此用户,而且可能会远程管理设置并监控用户活动。</translation>
 <translation id="150962533380566081">PUK 无效。</translation>
 <translation id="1510238584712386396">启动器</translation>
+<translation id="1600964289716072707">将另一个网页放置在扫描仪上,然后选择“扫描”即可添加网页。</translation>
 <translation id="1621067168122174824">运行充电测试</translation>
 <translation id="1641857168437328880">文件馈送器(单面)</translation>
 <translation id="1644574205037202324">历史记录</translation>
@@ -287,6 +288,7 @@
 <translation id="6766275201586212568">DNS 解析失败</translation>
 <translation id="6768237774506518020">DNS 解析失败比率较高</translation>
 <translation id="6853312040151791195">放电速率</translation>
+<translation id="6905724422583748843">返回“<ph name="PAGE_NAME" />”</translation>
 <translation id="6910312834584889076">扫描仪的盖子没合上。请合上盖子,然后重试。</translation>
 <translation id="6911383237894364323">无法连接到媒体服务器</translation>
 <translation id="6957231940976260713">服务名称</translation>
@@ -331,6 +333,7 @@
 <translation id="7769672763586021400">型号 ID</translation>
 <translation id="7805768142964895445">状态</translation>
 <translation id="7819857487979277519">PSK(WPA 或 RSN)</translation>
+<translation id="7835501727204647447">安装 CloudReady</translation>
 <translation id="7881066108824108340">DNS</translation>
 <translation id="7882358943899516840">提供商类型</translation>
 <translation id="7936303884198020182">找不到任何域名服务器</translation>
diff --git a/chromeos/strings/chromeos_strings_zh-HK.xtb b/chromeos/strings/chromeos_strings_zh-HK.xtb
index f76a130..ed8b558 100644
--- a/chromeos/strings/chromeos_strings_zh-HK.xtb
+++ b/chromeos/strings/chromeos_strings_zh-HK.xtb
@@ -32,7 +32,7 @@
 <translation id="1499900233129743732"><ph name="MANAGER" /> 管理此使用者,並可能會遠端管理設定並監察使用者活動。</translation>
 <translation id="150962533380566081">PUK 無效。</translation>
 <translation id="1510238584712386396">啟動器</translation>
-<translation id="1600964289716072707">將其他頁面放到掃描器上,並選取 [掃描] 即可新增頁面。</translation>
+<translation id="1600964289716072707">將其他頁面放到掃瞄器上,並選取 [掃瞄] 即可新增頁面。</translation>
 <translation id="1621067168122174824">執行充電測試</translation>
 <translation id="1641857168437328880">文件送紙器 (單面)</translation>
 <translation id="1644574205037202324">記錄</translation>
@@ -288,7 +288,7 @@
 <translation id="6766275201586212568">DNS 解析失敗</translation>
 <translation id="6768237774506518020">DNS 解析失敗率高</translation>
 <translation id="6853312040151791195">放電率</translation>
-<translation id="6905724422583748843">返回「<ph name="PAGE_NAME" />」頁面</translation>
+<translation id="6905724422583748843">返番去<ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">掃瞄器的外蓋已開啟。請關上外蓋,然後再試一次。</translation>
 <translation id="6911383237894364323">無法連線至媒體伺服器</translation>
 <translation id="6957231940976260713">服務名稱</translation>
diff --git a/chromeos/ui/base/tablet_state.cc b/chromeos/ui/base/tablet_state.cc
index 5c6c2d05..6bfe389 100644
--- a/chromeos/ui/base/tablet_state.cc
+++ b/chromeos/ui/base/tablet_state.cc
@@ -6,7 +6,6 @@
 
 #include "base/check_op.h"
 #include "build/chromeos_buildflags.h"
-#include "ui/display/screen.h"
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "ui/base/pointer/touch_ui_controller.h"
@@ -25,13 +24,11 @@
 TabletState::TabletState() {
   DCHECK_EQ(nullptr, g_instance);
   g_instance = this;
-  display::Screen::GetScreen()->AddObserver(this);
 }
 
 TabletState::~TabletState() {
   DCHECK_EQ(this, g_instance);
   g_instance = nullptr;
-  display::Screen::GetScreen()->RemoveObserver(this);
 }
 
 bool TabletState::InTabletMode() const {
diff --git a/chromeos/ui/base/tablet_state.h b/chromeos/ui/base/tablet_state.h
index f1efd19..2830a90 100644
--- a/chromeos/ui/base/tablet_state.h
+++ b/chromeos/ui/base/tablet_state.h
@@ -35,6 +35,8 @@
   void OnDisplayTabletStateChanged(display::TabletState state) override;
 
  private:
+  display::ScopedDisplayObserver display_observer_{this};
+
   display::TabletState state_ = display::TabletState::kInClamshellMode;
 };
 
diff --git a/components/account_id/account_id.cc b/components/account_id/account_id.cc
index d7af5f7..ee0ba4c 100644
--- a/components/account_id/account_id.cc
+++ b/components/account_id/account_id.cc
@@ -35,7 +35,7 @@
 
 }  // anonymous namespace
 
-AccountId::AccountId() {}
+AccountId::AccountId() = default;
 
 AccountId::AccountId(const std::string& id,
                      const std::string& user_email,
@@ -54,10 +54,9 @@
   // TODO(alemate): check gaia_id is not empty once it is required.
 }
 
-AccountId::AccountId(const AccountId& other)
-    : id_(other.id_),
-      user_email_(other.user_email_),
-      account_type_(other.account_type_) {}
+AccountId::AccountId(const AccountId& other) = default;
+
+AccountId& AccountId::operator=(const AccountId& other) = default;
 
 bool AccountId::operator==(const AccountId& other) const {
   if (this == &other)
diff --git a/components/account_id/account_id.h b/components/account_id/account_id.h
index 8f56e65..0ead8677 100644
--- a/components/account_id/account_id.h
+++ b/components/account_id/account_id.h
@@ -32,6 +32,7 @@
   AccountId();
 
   AccountId(const AccountId& other);
+  AccountId& operator=(const AccountId& other);
 
   // If any of the comparable AccountIds has AccountType == UNKNOWN then it
   // compares emails.
diff --git a/components/arc/DEPS b/components/arc/DEPS
index b6b8652..b9e5989e 100644
--- a/components/arc/DEPS
+++ b/components/arc/DEPS
@@ -39,6 +39,10 @@
     "+ash/public",
     "+services/service_manager/public",
   ],
+  "arc_intent_helper_bridge.cc": [
+    # For net::IsLocalhost.
+    "+net/base/url_util.h",
+  ],
   "arc_util.cc": [
     "+ui/aura",
   ],
diff --git a/components/arc/arc_features.cc b/components/arc/arc_features.cc
index d2123b7..e2cc25c 100644
--- a/components/arc/arc_features.cc
+++ b/components/arc/arc_features.cc
@@ -61,6 +61,10 @@
 const base::Feature kImageCopyPasteCompatFeature{
     "ArcImageCopyPasteCompat", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls keyboard shortcut helper integration feature in ARC.
+const base::Feature kKeyboardShortcutHelperIntegrationFeature{
+    "ArcKeyboardShortcutHelperIntegration", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Controls experimental 64-bit native bridge support for ARC on boards that
 // have 64-bit native bridge support available but not yet enabled.
 const base::Feature kNativeBridge64BitSupportExperimentFeature{
@@ -112,4 +116,22 @@
 const base::Feature kVideoDecoder{"ArcVideoDecoder",
                                   base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Controls whether a custom memory size is used when creating ARCVM. When
+// enabled, ARCVM is sized with the following formula:
+//  min(max_mib, RAM + shift_mib)
+// If disabled, memory is sized by concierge which, at the time of writing, uses
+// RAM - 1024 MiB.
+const base::Feature kVmMemorySize{"ArcVmMemorySize",
+                                  base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Controls the amount to "shift" system RAM when sizing ARCVM. The default
+// value of 0 means that ARCVM's memory will be thr same as the system.
+const base::FeatureParam<int> kVmMemorySizeShiftMiB{&kVmMemorySize, "shift_mib",
+                                                    0};
+
+// Controls the maximum amount of memory to give ARCVM. The default value of
+// INT32_MAX means that ARCVM's memory is not capped.
+const base::FeatureParam<int> kVmMemorySizeMaxMiB{&kVmMemorySize, "max_mib",
+                                                  INT32_MAX};
+
 }  // namespace arc
diff --git a/components/arc/arc_features.h b/components/arc/arc_features.h
index b3b98e85..6457e0c 100644
--- a/components/arc/arc_features.h
+++ b/components/arc/arc_features.h
@@ -24,6 +24,7 @@
 extern const base::Feature kEnableWebAppShareFeature;
 extern const base::Feature kFilePickerExperimentFeature;
 extern const base::Feature kImageCopyPasteCompatFeature;
+extern const base::Feature kKeyboardShortcutHelperIntegrationFeature;
 extern const base::Feature kNativeBridge64BitSupportExperimentFeature;
 extern const base::Feature kNativeBridgeToggleFeature;
 extern const base::Feature kPictureInPictureFeature;
@@ -33,6 +34,9 @@
 extern const base::Feature kUseHighMemoryDalvikProfile;
 extern const base::Feature kUsbStorageUIFeature;
 extern const base::Feature kVideoDecoder;
+extern const base::Feature kVmMemorySize;
+extern const base::FeatureParam<int> kVmMemorySizeShiftMiB;
+extern const base::FeatureParam<int> kVmMemorySizeMaxMiB;
 
 }  // namespace arc
 
diff --git a/components/arc/arc_prefs.cc b/components/arc/arc_prefs.cc
index 85bb65d..476e58df 100644
--- a/components/arc/arc_prefs.cc
+++ b/components/arc/arc_prefs.cc
@@ -57,12 +57,12 @@
 // |kArcInitialSettingsPending| can be different and
 // |kArcInitialSettingsPending| may even be handled in the next user session.
 const char kArcInitialSettingsPending[] = "arc.initial.settings.pending";
+// A preference that indicates that a management transition is necessary, in
+// response to account management state change.
+const char kArcManagementTransition[] = "arc.management_transition";
 // A preference that indicated whether Android reported it's compliance status
 // with provided policies. This is used only as a signal to start Android kiosk.
 const char kArcPolicyComplianceReported[] = "arc.policy_compliance_reported";
-// A preference that indicates that a supervision transition is necessary, in
-// response to a CHILD_ACCOUNT transiting to a REGULAR_ACCOUNT or vice-versa.
-const char kArcSupervisionTransition[] = "arc.supervision_transition";
 // A preference that indicates that user accepted PlayStore terms.
 const char kArcTermsAccepted[] = "arc.terms.accepted";
 // A preference that indicates that ToS was shown in OOBE flow.
@@ -165,7 +165,7 @@
   registry->RegisterBooleanPref(kArcLocationServiceEnabled, false);
 
   registry->RegisterIntegerPref(
-      kArcSupervisionTransition,
+      kArcManagementTransition,
       static_cast<int>(ArcSupervisionTransition::NO_TRANSITION));
 
   registry->RegisterBooleanPref(kArcIsManaged, false);
diff --git a/components/arc/arc_prefs.h b/components/arc/arc_prefs.h
index f071e31..413511cb 100644
--- a/components/arc/arc_prefs.h
+++ b/components/arc/arc_prefs.h
@@ -27,6 +27,7 @@
 ARC_EXPORT extern const char kArcHasAccessToRemovableMedia[];
 ARC_EXPORT extern const char kArcInitialSettingsPending[];
 ARC_EXPORT extern const char kArcLocationServiceEnabled[];
+ARC_EXPORT extern const char kArcManagementTransition[];
 ARC_EXPORT extern const char kArcPackages[];
 ARC_EXPORT extern const char kArcPaiStarted[];
 ARC_EXPORT extern const char kArcPolicyComplianceReported[];
@@ -37,7 +38,6 @@
 ARC_EXPORT extern const char kArcShowResizeLockSplashScreenLimits[];
 ARC_EXPORT extern const char kArcSignedIn[];
 ARC_EXPORT extern const char kArcSkippedReportingNotice[];
-ARC_EXPORT extern const char kArcSupervisionTransition[];
 ARC_EXPORT extern const char kArcTermsAccepted[];
 ARC_EXPORT extern const char kArcTermsShownInOobe[];
 ARC_EXPORT extern const char kArcVisibleExternalStorages[];
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.cc b/components/arc/compat_mode/arc_resize_lock_manager.cc
index cba099ce..fa072c570 100644
--- a/components/arc/compat_mode/arc_resize_lock_manager.cc
+++ b/components/arc/compat_mode/arc_resize_lock_manager.cc
@@ -208,6 +208,8 @@
   // Because we use the compat mode button as the "anchor" in the splash, we
   // need to show it after the setup of the compat mode button.
   if (is_first_launch && ShouldShowSplashScreenDialog(pref_delegate_)) {
+    // Compat-mode button must exist as the anchoring target of the splash.
+    UpdateCompatModeButton(window);
     const bool is_for_unresizable =
         window->GetProperty(ash::kArcResizeLockTypeKey) ==
         ash::ArcResizeLockType::FULLY_LOCKED;
diff --git a/components/arc/enterprise/snapshot_hours_policy_service.cc b/components/arc/enterprise/snapshot_hours_policy_service.cc
index a0f6911..11a59c5 100644
--- a/components/arc/enterprise/snapshot_hours_policy_service.cc
+++ b/components/arc/enterprise/snapshot_hours_policy_service.cc
@@ -29,10 +29,17 @@
       prefs::kArcSnapshotHours,
       base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy,
                           weak_ptr_factory_.GetWeakPtr()));
+
+  DCHECK(user_manager::UserManager::Get());
+  user_manager::UserManager::Get()->AddObserver(this);
+
   UpdatePolicy();
 }
 
-SnapshotHoursPolicyService::~SnapshotHoursPolicyService() = default;
+SnapshotHoursPolicyService::~SnapshotHoursPolicyService() {
+  DCHECK(user_manager::UserManager::Get());
+  user_manager::UserManager::Get()->RemoveObserver(this);
+}
 
 void SnapshotHoursPolicyService::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
@@ -44,8 +51,7 @@
 
 void SnapshotHoursPolicyService::StartObservingPrimaryProfilePrefs(
     PrefService* profile_prefs) {
-  if (!user_manager::UserManager::Get() ||
-      !user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()) {
+  if (!user_manager::UserManager::Get()->IsLoggedInAsPublicAccount()) {
     // Do not care about ArcEnabled policy for other than MGS.
     return;
   }
@@ -55,6 +61,7 @@
       prefs::kArcEnabled,
       base::BindRepeating(&SnapshotHoursPolicyService::UpdatePolicy,
                           weak_ptr_factory_.GetWeakPtr()));
+
   UpdatePolicy();
 }
 
@@ -66,11 +73,19 @@
   UpdatePolicy();
 }
 
+void SnapshotHoursPolicyService::LocalStateChanged(
+    user_manager::UserManager* user_manager) {
+  UpdatePolicy();
+}
+
 void SnapshotHoursPolicyService::UpdatePolicy() {
   intervals_.clear();
   base::ScopedClosureRunner snapshot_disabler(
       base::BindOnce(&SnapshotHoursPolicyService::DisableSnapshots,
                      weak_ptr_factory_.GetWeakPtr()));
+
+  if (!IsMgsConfigured())
+    return;
   if (!IsArcEnabled())
     return;
 
@@ -178,5 +193,13 @@
   return !profile_prefs_ || profile_prefs_->GetBoolean(prefs::kArcEnabled);
 }
 
+bool SnapshotHoursPolicyService::IsMgsConfigured() const {
+  for (auto* const user : user_manager::UserManager::Get()->GetUsers()) {
+    if (user->GetType() == user_manager::UserType::USER_TYPE_PUBLIC_ACCOUNT)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace data_snapshotd
 }  // namespace arc
diff --git a/components/arc/enterprise/snapshot_hours_policy_service.h b/components/arc/enterprise/snapshot_hours_policy_service.h
index 32921b3..7c5ec1d3 100644
--- a/components/arc/enterprise/snapshot_hours_policy_service.h
+++ b/components/arc/enterprise/snapshot_hours_policy_service.h
@@ -14,6 +14,7 @@
 #include "base/util/timer/wall_clock_timer.h"
 #include "chromeos/policy/weekly_time/weekly_time_interval.h"
 #include "components/prefs/pref_change_registrar.h"
+#include "components/user_manager/user_manager.h"
 
 class PrefService;
 
@@ -24,7 +25,7 @@
 // data snapshot feature, handles ARC data snapshot update intervals.
 //
 // ArcDataSnapshotdManager is an owner of this object.
-class SnapshotHoursPolicyService {
+class SnapshotHoursPolicyService : public user_manager::UserManager::Observer {
  public:
   // Observer interface.
   class Observer : public base::CheckedObserver {
@@ -44,7 +45,7 @@
   SnapshotHoursPolicyService(const SnapshotHoursPolicyService&) = delete;
   SnapshotHoursPolicyService& operator=(const SnapshotHoursPolicyService&) =
       delete;
-  ~SnapshotHoursPolicyService();
+  ~SnapshotHoursPolicyService() override;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
@@ -54,6 +55,9 @@
   // Stops observing primary profile prefs.
   void StopObservingPrimaryProfilePrefs();
 
+  // user_manager::UserManager::Observer overrides:
+  void LocalStateChanged(user_manager::UserManager* user_manager) override;
+
   // Returns the end time of the current interval when ARC data snapshot update
   // is possible.
   // Returns null outside of the interval.
@@ -102,6 +106,9 @@
   // true.
   bool IsArcEnabled() const;
 
+  // Returns true if MGS is configured for a device, otherwise returns false.
+  bool IsMgsConfigured() const;
+
   // The feature is disabled when either kArcDataSnapshotHours policy is not set
   // or ARC is disabled by policy for MGS.
   bool is_snapshot_enabled_ = false;
diff --git a/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc b/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc
index e92d165..b24bcdd2 100644
--- a/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc
+++ b/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc
@@ -27,6 +27,7 @@
 namespace {
 
 constexpr char kPublicAccountEmail[] = "public-session-account@localhost";
+constexpr char kUserAccountEmail[] = "regular-user-account@localhost";
 
 // DeviceArcDataSnapshotHours policy with one correct interval.
 constexpr char kJsonPolicy[] =
@@ -146,14 +147,16 @@
 
   void SetUp() override {
     arc::prefs::RegisterLocalStatePrefs(local_state_.registry());
-    policy_service_ =
-        std::make_unique<SnapshotHoursPolicyService>(local_state());
-    observer_ = std::make_unique<FakeObserver>();
-    policy_service()->AddObserver(observer_.get());
 
     fake_user_manager_ = new user_manager::FakeUserManager();
     scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
         base::WrapUnique(fake_user_manager_));
+    fake_user_manager_->set_local_state(local_state());
+
+    policy_service_ =
+        std::make_unique<SnapshotHoursPolicyService>(local_state());
+    observer_ = std::make_unique<FakeObserver>();
+    policy_service()->AddObserver(observer_.get());
   }
 
   void TearDown() override {
@@ -183,9 +186,14 @@
 
   // Enable feature and check.
   void EnableSnapshot(int enabled_calls_num = 1) {
+    auto account_id = AccountId::FromUserEmail(kPublicAccountEmail);
+    EXPECT_TRUE(fake_user_manager_->AddPublicAccountUser(account_id));
+    policy_service()->LocalStateChanged(user_manager());
+
     absl::optional<base::Value> policy = base::JSONReader::Read(kJsonPolicy);
     EXPECT_TRUE(policy.has_value());
     local_state()->Set(arc::prefs::kArcSnapshotHours, policy.value());
+
     EnsureSnapshotEnabled(enabled_calls_num);
   }
 
@@ -202,9 +210,28 @@
 
   void LoginAsPublicSession() {
     auto account_id = AccountId::FromUserEmail(kPublicAccountEmail);
-    user_manager()->AddPublicAccountUser(account_id);
-    user_manager()->UserLoggedIn(account_id, account_id.GetUserEmail(), false,
+    const auto* user = fake_user_manager_->AddPublicAccountUser(account_id);
+    user_manager()->UserLoggedIn(account_id, user->username_hash(), false,
                                  false);
+    user_manager()->SwitchActiveUser(account_id);
+    EXPECT_EQ(user_manager()->GetActiveUser()->GetAccountId(), account_id);
+    policy_service()->LocalStateChanged(user_manager());
+  }
+
+  void RemovePublicSession() {
+    auto account_id = AccountId::FromUserEmail(kPublicAccountEmail);
+    user_manager()->RemoveUserFromList(account_id);
+    policy_service()->LocalStateChanged(user_manager());
+  }
+
+  void LoginAsRegularUser() {
+    auto account_id = AccountId::FromUserEmail(kUserAccountEmail);
+    const auto* user = user_manager()->AddUser(account_id);
+    user_manager()->UserLoggedIn(account_id, user->username_hash(), false,
+                                 false);
+    user_manager()->SwitchActiveUser(account_id);
+    EXPECT_EQ(user_manager()->GetActiveUser()->GetAccountId(), account_id);
+    policy_service()->LocalStateChanged(user_manager());
   }
 
   SnapshotHoursPolicyService* policy_service() { return policy_service_.get(); }
@@ -228,6 +255,15 @@
   EnsureSnapshotDisabled();
 }
 
+// Test that the feature is disabled if MGS is not configured.
+TEST_F(SnapshotHoursPolicyServiceTest, MgsIsNotConfigured) {
+  EnableSnapshot();
+
+  RemovePublicSession();
+
+  EnsureSnapshotDisabled(1 /* disabled_calls_num */);
+}
+
 TEST_F(SnapshotHoursPolicyServiceTest, OneIntervalEnabled) {
   EnableSnapshot();
 }
@@ -304,6 +340,7 @@
 TEST_F(SnapshotHoursPolicyServiceTest, DisableByUserPolicyForUser) {
   EnableSnapshot();
 
+  LoginAsRegularUser();
   TestingPrefServiceSimple profile_prefs;
   arc::prefs::RegisterProfilePrefs(profile_prefs.registry());
   profile_prefs.SetBoolean(arc::prefs::kArcEnabled, false);
diff --git a/components/arc/ime/arc_ime_bridge.h b/components/arc/ime/arc_ime_bridge.h
index b815556..cb4443ee 100644
--- a/components/arc/ime/arc_ime_bridge.h
+++ b/components/arc/ime/arc_ime_bridge.h
@@ -47,7 +47,6 @@
         const std::u16string& text_in_range,
         const gfx::Range& selection_range,
         bool is_screen_coordinates) = 0;
-    virtual bool ShouldEnableKeyEventForwarding() = 0;
     virtual void SendKeyEvent(std::unique_ptr<ui::KeyEvent> key_event,
                               KeyEventDoneCallback callback) = 0;
   };
diff --git a/components/arc/ime/arc_ime_bridge_impl.cc b/components/arc/ime/arc_ime_bridge_impl.cc
index d6c1623..aa3c796 100644
--- a/components/arc/ime/arc_ime_bridge_impl.cc
+++ b/components/arc/ime/arc_ime_bridge_impl.cc
@@ -167,7 +167,8 @@
 
 void ArcImeBridgeImpl::ShouldEnableKeyEventForwarding(
     ShouldEnableKeyEventForwardingCallback callback) {
-  std::move(callback).Run(delegate_->ShouldEnableKeyEventForwarding());
+  // TODO(b/190487153): Clean up this once the caller is removed.
+  std::move(callback).Run(true);
 }
 
 void ArcImeBridgeImpl::SendKeyEvent(std::unique_ptr<ui::KeyEvent> key_event,
diff --git a/components/arc/ime/arc_ime_service.cc b/components/arc/ime/arc_ime_service.cc
index 33eda70..57b579b 100644
--- a/components/arc/ime/arc_ime_service.cc
+++ b/components/arc/ime/arc_ime_service.cc
@@ -6,10 +6,8 @@
 
 #include <utility>
 
-#include "ash/constants/ash_features.h"
 #include "ash/keyboard/ui/keyboard_ui_controller.h"
 #include "ash/public/cpp/app_types_util.h"
-#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/histogram_functions.h"
@@ -418,11 +416,6 @@
     input_method->OnCaretBoundsChanged(this);
 }
 
-bool ArcImeService::ShouldEnableKeyEventForwarding() {
-  return base::FeatureList::IsEnabled(
-      chromeos::features::kArcPreImeKeyEventSupport);
-}
-
 void ArcImeService::SendKeyEvent(std::unique_ptr<ui::KeyEvent> key_event,
                                  KeyEventDoneCallback callback) {
   ui::InputMethod* const input_method = GetInputMethod();
@@ -493,22 +486,6 @@
 
   InvalidateSurroundingTextAndSelectionRange();
 
-  // For apps that doesn't handle hardware keyboard events well, keys that are
-  // typically on software keyboard and lack of them are fatal, namely,
-  // unmodified enter and backspace keys are sent through IME.
-  if (!HasModifier(&event) && !ShouldEnableKeyEventForwarding()) {
-    if (event.key_code() ==  ui::VKEY_RETURN) {
-      has_composition_text_ = false;
-      ime_bridge_->SendInsertText(u"\n", /*new_cursor_position=*/1);
-      return;
-    }
-    if (event.key_code() ==  ui::VKEY_BACK) {
-      has_composition_text_ = false;
-      ime_bridge_->SendInsertText(u"\b", /*new_cursor_position=*/1);
-      return;
-    }
-  }
-
   if (IsCharacterKeyEvent(&event)) {
     has_composition_text_ = false;
     ime_bridge_->SendInsertText(std::u16string(1, event.GetText()),
@@ -709,9 +686,6 @@
 }
 
 void ArcImeService::OnDispatchingKeyEventPostIME(ui::KeyEvent* event) {
-  if (!ShouldEnableKeyEventForwarding())
-    return;
-
   if (receiver_->HasCallback()) {
     receiver_->DispatchKeyEventPostIME(event);
     event->SetHandled();
diff --git a/components/arc/ime/arc_ime_service.h b/components/arc/ime/arc_ime_service.h
index acaee65..4d7f134 100644
--- a/components/arc/ime/arc_ime_service.h
+++ b/components/arc/ime/arc_ime_service.h
@@ -102,7 +102,6 @@
       const std::u16string& text_in_range,
       const gfx::Range& selection_range,
       bool is_screen_coordinates) override;
-  bool ShouldEnableKeyEventForwarding() override;
   void SendKeyEvent(std::unique_ptr<ui::KeyEvent> key_event,
                     KeyEventDoneCallback callback) override;
 
diff --git a/components/arc/ime/arc_ime_service_unittest.cc b/components/arc/ime/arc_ime_service_unittest.cc
index f6bbad7fc..3a2386c 100644
--- a/components/arc/ime/arc_ime_service_unittest.cc
+++ b/components/arc/ime/arc_ime_service_unittest.cc
@@ -9,12 +9,10 @@
 #include <string>
 #include <utility>
 
-#include "ash/constants/ash_features.h"
 #include "ash/keyboard/ui/keyboard_ui_controller.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "components/arc/mojom/ime.mojom.h"
 #include "components/arc/session/arc_bridge_service.h"
@@ -568,10 +566,6 @@
 }
 
 TEST_F(ArcImeServiceTest, OnDispatchingKeyEventPostIME) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      chromeos::features::kArcPreImeKeyEventSupport);
-
   instance_->OnWindowFocused(arc_win_.get(), nullptr);
   instance_->OnTextInputTypeChanged(ui::TEXT_INPUT_TYPE_TEXT, true,
                                     mojom::TEXT_INPUT_FLAG_NONE);
@@ -623,9 +617,6 @@
 }
 
 TEST_F(ArcImeServiceTest, SendKeyEvent) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      chromeos::features::kArcPreImeKeyEventSupport);
   base::test::SingleThreadTaskEnvironment task_environment;
 
   instance_->OnWindowFocused(arc_win_.get(), nullptr);
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 9135502..626ed5c 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -25,6 +25,7 @@
 #include "components/arc/intent_helper/open_url_delegate.h"
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/url_formatter/url_fixer.h"
+#include "net/base/url_util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/layout.h"
 #include "url/url_constants.h"
@@ -102,6 +103,14 @@
   UMA_HISTOGRAM_ENUMERATION("Arc.IntentHelper.OpenAppWithIntentAction", action);
 }
 
+// Returns true if a Web App is allowed to be opened for the given URL.
+bool CanOpenWebAppForUrl(const GURL& url) {
+  bool is_http_localhost =
+      url.SchemeIs(url::kHttpScheme) && net::IsLocalhost(url);
+  return url.is_valid() &&
+         (url.SchemeIs(url::kHttpsScheme) || is_http_localhost);
+}
+
 }  // namespace
 
 // static
@@ -255,11 +264,9 @@
   RecordOpenType(ArcIntentHelperOpenType::WEB_APP);
   // Converts |url| to a fixed-up one and checks validity.
   const GURL gurl(url_formatter::FixupURL(url, /*desired_tld=*/std::string()));
-  if (!gurl.is_valid())
-    return;
 
   // Web app launches should only be invoked on HTTPS URLs.
-  if (gurl.SchemeIs(url::kHttpsScheme))
+  if (CanOpenWebAppForUrl(gurl))
     g_open_url_delegate->OpenWebAppFromArc(gurl);
 }
 
@@ -362,15 +369,13 @@
     return;
   }
 
-  if (!start_url.is_valid())
-    return;
-
-  RecordOpenType(ArcIntentHelperOpenType::WEB_APP);
-  RecordOpenAppIntentAction(intent);
-
   // Web app launches should only be invoked on HTTPS URLs.
-  if (start_url.SchemeIs(url::kHttpsScheme))
+  if (CanOpenWebAppForUrl(start_url)) {
+    RecordOpenType(ArcIntentHelperOpenType::WEB_APP);
+    RecordOpenAppIntentAction(intent);
+
     g_open_url_delegate->OpenAppWithIntent(start_url, std::move(intent));
+  }
 }
 
 ArcIntentHelperBridge::GetResult ArcIntentHelperBridge::GetActivityIcons(
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
index cc3a6884..c5a229e2 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
@@ -381,11 +381,15 @@
             test_open_url_delegate_->TakeLastOpenedUrl());
 }
 
-// Tests that OnOpenWebApp opens only HTTPS URLs.
+// Tests that OnOpenWebApp opens only HTTPS URLs or localhost.
 TEST_F(ArcIntentHelperTest, TestOnOpenWebApp) {
   instance_->OnOpenWebApp("http://google.com");
   EXPECT_EQ(GURL(), test_open_url_delegate_->TakeLastOpenedUrl());
 
+  instance_->OnOpenWebApp("http://localhost/");
+  EXPECT_EQ(GURL("http://localhost/"),
+            test_open_url_delegate_->TakeLastOpenedUrl());
+
   instance_->OnOpenWebApp("https://google.com");
   EXPECT_EQ(GURL("https://google.com"),
             test_open_url_delegate_->TakeLastOpenedUrl());
@@ -435,6 +439,11 @@
     EXPECT_FALSE(test_open_url_delegate_->TakeLastOpenedUrl().is_valid());
     EXPECT_TRUE(test_open_url_delegate_->TakeLastOpenedIntent().is_null());
 
+    instance_->OnOpenAppWithIntent(GURL("http://localhost:8000/foo"),
+                                   mojom::LaunchIntent::New());
+    EXPECT_TRUE(test_open_url_delegate_->TakeLastOpenedUrl().is_valid());
+    EXPECT_FALSE(test_open_url_delegate_->TakeLastOpenedIntent().is_null());
+
     instance_->OnOpenAppWithIntent(GURL("chrome://settings"),
                                    mojom::LaunchIntent::New());
     EXPECT_FALSE(test_open_url_delegate_->TakeLastOpenedUrl().is_valid());
diff --git a/components/arc/session/arc_session_impl.cc b/components/arc/session/arc_session_impl.cc
index 3d80b2ab..c190cbd 100644
--- a/components/arc/session/arc_session_impl.cc
+++ b/components/arc/session/arc_session_impl.cc
@@ -454,6 +454,9 @@
   params.arc_custom_tabs_experiment = is_custom_tab_enabled;
   params.enable_image_copy_paste_compat =
       base::FeatureList::IsEnabled(arc::kImageCopyPasteCompatFeature);
+  params.enable_keyboard_shortcut_helper_integration =
+      base::FeatureList::IsEnabled(
+          arc::kKeyboardShortcutHelperIntegrationFeature);
   params.lcd_density = lcd_density_;
   params.num_cores_disabled = num_cores_disabled;
 
diff --git a/components/arc/session/arc_start_params.h b/components/arc/session/arc_start_params.h
index 2ae4200..520cf3ad 100644
--- a/components/arc/session/arc_start_params.h
+++ b/components/arc/session/arc_start_params.h
@@ -86,6 +86,9 @@
   // Flag to enable image copy & paste app compat.
   bool enable_image_copy_paste_compat = false;
 
+  // Flag to enable keyboard shortcut helper integration.
+  bool enable_keyboard_shortcut_helper_integration = false;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(StartParams);
 };
diff --git a/components/arc/session/arc_vm_client_adapter.cc b/components/arc/session/arc_vm_client_adapter.cc
index 83bd6be..15492a7 100644
--- a/components/arc/session/arc_vm_client_adapter.cc
+++ b/components/arc/session/arc_vm_client_adapter.cc
@@ -10,6 +10,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <algorithm>
 #include <deque>
 #include <set>
 #include <utility>
@@ -222,6 +223,9 @@
                          start_params.arc_custom_tabs_experiment),
       base::StringPrintf("androidboot.image_copy_paste_compat=%d",
                          start_params.enable_image_copy_paste_compat),
+      base::StringPrintf(
+          "androidboot.keyboard_shortcut_helper_integration=%d",
+          start_params.enable_keyboard_shortcut_helper_integration),
       base::StringPrintf("androidboot.disable_system_default_app=%d",
                          start_params.arc_disable_system_default_app),
       "androidboot.chromeos_channel=" + channel,
@@ -376,6 +380,29 @@
 
   // Add hugepages.
   request.set_use_hugepages(IsArcVmUseHugePages());
+
+  // Specify VM Memory.
+  if (base::FeatureList::IsEnabled(kVmMemorySize)) {
+    base::SystemMemoryInfoKB info;
+    if (base::GetSystemMemoryInfo(&info)) {
+      const int ram_mib = info.total / 1024;
+      const int shift_mib = kVmMemorySizeShiftMiB.Get();
+      const int max_mib = kVmMemorySizeMaxMiB.Get();
+      const int vm_ram_mib = std::min(max_mib, ram_mib + shift_mib);
+      constexpr int kVmRamMinMib = 2048;
+      if (vm_ram_mib > kVmRamMinMib) {
+        request.set_memory_mib(vm_ram_mib);
+      } else {
+        VLOG(1) << "VmMemorySize is enabled, but computed size is "
+                << "min(" << ram_mib << " + " << shift_mib << "," << max_mib
+                << ") == " << vm_ram_mib << "MiB, less than " << kVmRamMinMib
+                << " MiB safe minium.";
+      }
+    } else {
+      VLOG(1) << "VmMemorySize is enabled, but GetSystemMemoryInfo failed.";
+    }
+  }
+
   return request;
 }
 
diff --git a/components/arc/session/arc_vm_client_adapter_unittest.cc b/components/arc/session/arc_vm_client_adapter_unittest.cc
index 62a43b88..cba7782e 100644
--- a/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -25,6 +25,7 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/posix/safe_strerror.h"
+#include "base/process/process_metrics.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -1841,6 +1842,86 @@
   EXPECT_FALSE(request.use_hugepages());
 }
 
+// Test that StartArcVmRequest has no memory_mib field when kVmMemorySize is
+// disabled.
+TEST_F(ArcVmClientAdapterTest, ArcVmMemorySizeDisabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(kVmMemorySize);
+  StartParams start_params(GetPopulatedStartParams());
+  SetValidUserInfo();
+  StartMiniArcWithParams(true, std::move(start_params));
+  auto request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_EQ(request.memory_mib(), 0u);
+}
+
+// Test that StartArcVmRequest has `memory_mib == system memory` when
+// kVmMemorySize is enabled with no maximum and shift_mib := 0.
+TEST_F(ArcVmClientAdapterTest, ArcVmMemorySizeEnabledBig) {
+  base::test::ScopedFeatureList feature_list;
+  base::FieldTrialParams params;
+  params["shift_mib"] = "0";
+  feature_list.InitAndEnableFeatureWithParameters(kVmMemorySize, params);
+  base::SystemMemoryInfoKB info;
+  ASSERT_TRUE(base::GetSystemMemoryInfo(&info));
+  const uint32_t total_mib = info.total / 1024;
+  StartParams start_params(GetPopulatedStartParams());
+  SetValidUserInfo();
+  StartMiniArcWithParams(true, std::move(start_params));
+  auto request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_EQ(request.memory_mib(), total_mib);
+}
+
+// Test that StartArcVmRequest has `memory_mib == system memory - 1024` when
+// kVmMemorySize is enabled with no maximum and shift_mib := -1024.
+TEST_F(ArcVmClientAdapterTest, ArcVmMemorySizeEnabledSmall) {
+  base::test::ScopedFeatureList feature_list;
+  base::FieldTrialParams params;
+  params["shift_mib"] = "-1024";
+  feature_list.InitAndEnableFeatureWithParameters(kVmMemorySize, params);
+  base::SystemMemoryInfoKB info;
+  ASSERT_TRUE(base::GetSystemMemoryInfo(&info));
+  const uint32_t total_mib = info.total / 1024;
+  StartParams start_params(GetPopulatedStartParams());
+  SetValidUserInfo();
+  StartMiniArcWithParams(true, std::move(start_params));
+  auto request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_EQ(request.memory_mib(), total_mib - 1024);
+}
+
+// Test that StartArcVmRequest has memory_mib unset when kVmMemorySize is
+// enabled, but the requested size is too low (due to max_mib being lower than
+// the 2048 safety minimum).
+TEST_F(ArcVmClientAdapterTest, ArcVmMemorySizeEnabledLow) {
+  base::test::ScopedFeatureList feature_list;
+  base::FieldTrialParams params;
+  params["shift_mib"] = "0";
+  params["max_mib"] = "1024";
+  feature_list.InitAndEnableFeatureWithParameters(kVmMemorySize, params);
+  StartParams start_params(GetPopulatedStartParams());
+  SetValidUserInfo();
+  StartMiniArcWithParams(true, std::move(start_params));
+  auto request = GetTestConciergeClient()->start_arc_vm_request();
+  // The 1024 max_mib is below the 2048 MiB safety cut-off, so we expect
+  // memory_mib to be unset.
+  EXPECT_EQ(request.memory_mib(), 0u);
+}
+
+// Test that StartArcVmRequest has `memory_mib == 2049` when kVmMemorySize is
+// enabled with max_mib := 2049.
+// NOTE: requires that the test running system has more than 2049 MiB of RAM.
+TEST_F(ArcVmClientAdapterTest, ArcVmMemorySizeEnabledMax) {
+  base::test::ScopedFeatureList feature_list;
+  base::FieldTrialParams params;
+  params["shift_mib"] = "0";
+  params["max_mib"] = "2049";  // Above the 2048 minimum cut-off.
+  feature_list.InitAndEnableFeatureWithParameters(kVmMemorySize, params);
+  StartParams start_params(GetPopulatedStartParams());
+  SetValidUserInfo();
+  StartMiniArcWithParams(true, std::move(start_params));
+  auto request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_EQ(request.memory_mib(), 2049u);
+}
+
 struct DalvikMemoryProfileTestParam {
   // Requested profile.
   StartParams::DalvikMemoryProfile profile;
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index 64d19e8c..9b6a5e6 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -1849,6 +1849,13 @@
 }
 
 // static
+void AutofillMetrics::LogFormFillDurationFromLoadForOneTimeCode(
+    const base::TimeDelta& duration) {
+  LogFormFillDuration("Autofill.WebOTP.OneTimeCode.FillDuration.FromLoad",
+                      duration);
+}
+
+// static
 void AutofillMetrics::LogFormFillDurationFromInteraction(
     const DenseSet<FormType>& form_types,
     bool used_autofill,
@@ -1875,6 +1882,13 @@
 }
 
 // static
+void AutofillMetrics::LogFormFillDurationFromInteractionForOneTimeCode(
+    const base::TimeDelta& duration) {
+  LogFormFillDuration(
+      "Autofill.WebOTP.OneTimeCode.FillDuration.FromInteraction", duration);
+}
+
+// static
 void AutofillMetrics::LogFormFillDuration(const std::string& metric,
                                           const base::TimeDelta& duration) {
   base::UmaHistogramCustomTimes(metric, duration,
@@ -2241,6 +2255,17 @@
 }
 
 // static
+void AutofillMetrics::LogAutofillPerfectFilling(bool is_address,
+                                                bool perfect_filling) {
+  if (is_address) {
+    UMA_HISTOGRAM_BOOLEAN("Autofill.PerfectFilling.Addresses", perfect_filling);
+  } else {
+    UMA_HISTOGRAM_BOOLEAN("Autofill.PerfectFilling.CreditCards",
+                          perfect_filling);
+  }
+}
+
+// static
 void AutofillMetrics::LogDetermineHeuristicTypesTiming(
     const base::TimeDelta& duration) {
   UMA_HISTOGRAM_TIMES("Autofill.Timing.DetermineHeuristicTypes", duration);
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index fa977ce..393ef596 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -1387,6 +1387,12 @@
   static void LogFormFillDurationFromLoadWithoutAutofill(
       const base::TimeDelta& duration);
 
+  // This should be called when a form with |autocomplete="one-time-code"| is
+  // submitted. |duration| should be the time elapsed between form load and
+  // submission.
+  static void LogFormFillDurationFromLoadForOneTimeCode(
+      const base::TimeDelta& duration);
+
   // This should be called when a form is submitted. |duration| should be the
   // time elapsed between the initial form interaction and submission. This
   // metric is sliced by |form_type| and |used_autofill|.
@@ -1395,6 +1401,12 @@
       bool used_autofill,
       const base::TimeDelta& duration);
 
+  // This should be called when a form with |autocomplete="one-time-code"| is
+  // submitted. |duration| should be the time elapsed between the initial form
+  // interaction and submission.
+  static void LogFormFillDurationFromInteractionForOneTimeCode(
+      const base::TimeDelta& duration);
+
   static void LogFormFillDuration(const std::string& metric,
                                   const base::TimeDelta& duration);
 
@@ -1529,6 +1541,10 @@
       FormSignature form_signature,
       FormInteractionsUkmLogger* form_interactions_ukm_logger);
 
+  // Logs if every non-empty field in a submitted form was filled by Autofill.
+  // If |is_address| an address was filled, otherwise it was a credit card.
+  static void LogAutofillPerfectFilling(bool is_address, bool perfect_filling);
+
   // This should be called when determining the heuristic types for a form's
   // fields.
   static void LogDetermineHeuristicTypesTiming(const base::TimeDelta& duration);
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 1a16263f..e3d13741 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -688,7 +688,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Test that the correct bucket for the number of filled fields received a
@@ -711,6 +711,335 @@
   }
 }
 
+// Test that we log the perfect filling metric correctly for an address form in
+// which every field is autofilled.
+TEST_F(AutofillMetricsTest, PerfectFillingForAddresses_AllAutofillFilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"Email",
+                                  .name = u"email",
+                                  .value = u"buddy@gmail.com",
+                                  .is_autofilled = true},
+                                 {.label = u"City",
+                                  .name = u"city",
+                                  .value = u"Munich",
+                                  .is_autofilled = true},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
+                                                  ADDRESS_HOME_CITY};
+  std::vector<ServerFieldType> server_types = {NAME_FULL, EMAIL_ADDRESS,
+                                               ADDRESS_HOME_CITY};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for perfect filling for
+  // addresses.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 1);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     0);
+}
+
+// Test that we log the perfect filling metric correctly for an address form in
+// which every field is autofilled or empty.
+TEST_F(AutofillMetricsTest,
+       PerfectFillingForAddresses_AllAutofillFilledOrEmpty) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"Email",
+                                  .name = u"email",
+                                  .value = u"buddy@gmail.com",
+                                  .is_autofilled = true},
+                                 {.label = u"City",
+                                  .name = u"city",
+                                  .value = u"",
+                                  .is_autofilled = false},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
+                                                  ADDRESS_HOME_CITY};
+  std::vector<ServerFieldType> server_types = {NAME_FULL, EMAIL_ADDRESS,
+                                               ADDRESS_HOME_CITY};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for perfect filling for
+  // addresses.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 1);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     0);
+}
+
+// Test that we log the perfect filling metric correctly for an address form in
+// which a non-empty field is not autofilled.
+TEST_F(AutofillMetricsTest, PerfectFillingForAddresses_NotAllAutofilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"Email",
+                                  .name = u"email",
+                                  .value = u"buddy@gmail.com",
+                                  .is_autofilled = true},
+                                 {.label = u"City",
+                                  .name = u"city",
+                                  .value = u"Munich",
+                                  .is_autofilled = false},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
+                                                  ADDRESS_HOME_CITY};
+  std::vector<ServerFieldType> server_types = {NAME_FULL, EMAIL_ADDRESS,
+                                               ADDRESS_HOME_CITY};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for non-perfect filling for
+  // addresses.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 1);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 0);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     0);
+}
+
+// Test that we log the perfect filling metric correctly for a credit card form
+// in which every field is autofilled.
+TEST_F(AutofillMetricsTest, PerfectFillingForCreditCards_AllAutofilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"CCNumber",
+                                  .name = u"ccnumber",
+                                  .value = u"01230123012399",
+                                  .is_autofilled = true},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {CREDIT_CARD_NAME_FULL,
+                                                  CREDIT_CARD_NUMBER};
+  std::vector<ServerFieldType> server_types = {CREDIT_CARD_NAME_FULL,
+                                               CREDIT_CARD_NUMBER};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for perfect filling for credit
+  // cards.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 0);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     1);
+}
+
+// Test that we log the perfect filling metric correctly for a credit card form
+// in which not every field is autofilled or empty.
+TEST_F(AutofillMetricsTest, PerfectFillingForCreditCards_NotAllAutofilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"CCNumber",
+                                  .name = u"ccnumber",
+                                  .value = u"01230123012399",
+                                  .is_autofilled = false},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {CREDIT_CARD_NAME_FULL,
+                                                  CREDIT_CARD_NUMBER};
+  std::vector<ServerFieldType> server_types = {CREDIT_CARD_NAME_FULL,
+                                               CREDIT_CARD_NUMBER};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for non-perfect filling for
+  // credit cards.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 0);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     1);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     0);
+}
+
+// Test that we log the perfect filling metric correctly for a form that
+// contains both credit card and address information. Here, the form is fully
+// autofilled resulting in a perfect count for both addresses and credit cards.
+TEST_F(AutofillMetricsTest, PerfectFillingForMixedForm_AllAutofilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"CCNumber",
+                                  .name = u"ccnumber",
+                                  .value = u"01230123012399",
+                                  .is_autofilled = true},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {NAME_FULL,
+                                                  CREDIT_CARD_NUMBER};
+  std::vector<ServerFieldType> server_types = {NAME_FULL, CREDIT_CARD_NUMBER};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for perfect filling for credit
+  // cards and for addresses.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 1);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     0);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     1);
+}
+
+// Test that we log the perfect filling metric correctly for a form that
+// contains both credit card and address information.  Here, the form is not
+// fully autofilled resulting in a non-perfect count for both addresses and
+// credit cards
+TEST_F(AutofillMetricsTest, PerfectFillingForMixedForm_NotAllAutofilled) {
+  // Set up our form data with two autofilled fields.
+  FormData form =
+      test::GetFormData({.description_for_logging = "PerectFilling",
+                         .fields =
+                             {
+                                 {.label = u"Name",
+                                  .name = u"name",
+                                  .value = u"Elvis Aaron Presley",
+                                  .is_autofilled = true},
+                                 {.label = u"CCNumber",
+                                  .name = u"ccnumber",
+                                  .value = u"01230123012399",
+                                  .is_autofilled = false},
+                             },
+                         .unique_renderer_id = test::MakeFormRendererId(),
+                         .main_frame_origin = url::Origin::Create(
+                             autofill_client_.form_origin())});
+
+  std::vector<ServerFieldType> heuristic_types = {NAME_FULL,
+                                                  CREDIT_CARD_NUMBER};
+  std::vector<ServerFieldType> server_types = {NAME_FULL, CREDIT_CARD_NUMBER};
+
+  // Simulate having seen this form on page load.
+  browser_autofill_manager_->AddSeenForm(form, heuristic_types, server_types);
+
+  // Simulate form submission.
+  base::HistogramTester histogram_tester;
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
+                                             SubmissionSource::FORM_SUBMISSION);
+
+  // Here, it is expected that there is a count for non-perfect filling for
+  // credit cards and for addresses.
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 0, 1);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.Addresses", 1, 0);
+
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 0,
+                                     1);
+  histogram_tester.ExpectBucketCount("Autofill.PerfectFilling.CreditCards", 1,
+                                     0);
+}
+
 // Test that we log quality metrics appropriately.
 TEST_F(AutofillMetricsTest, QualityMetrics) {
   // Set up our form data.
@@ -757,7 +1086,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Heuristic predictions.
@@ -929,7 +1258,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::string histogram = "Autofill.AddressProfileImportStatus";
@@ -981,7 +1310,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::string histogram = "Autofill.AddressProfileImportStatus";
@@ -1046,7 +1375,7 @@
   base::HistogramTester histogram_tester;
   std::string histogram = "Autofill.AddressProfileImportStatus";
 
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Verify that one profile was imported using the union of the two sections.
@@ -1099,7 +1428,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1179,7 +1508,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1263,7 +1592,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1353,7 +1682,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1446,7 +1775,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1527,7 +1856,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   std::vector<AddressProfileImportRequirementExpectations> expectations = {
@@ -1640,7 +1969,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Rationalization quality.
@@ -1707,7 +2036,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Rationalization quality.
@@ -2182,7 +2511,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Rationalization quality.
@@ -2265,7 +2594,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // Rationalization quality.
@@ -2556,7 +2885,7 @@
 
   // Run the form submission code while tracking the histograms.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   ExpectedUkmMetrics expected_ukm_metrics;
@@ -3073,7 +3402,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   histogram_tester.ExpectBucketCount(
@@ -3143,7 +3472,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   for (const std::string source : {"Heuristic", "Server", "Overall"}) {
@@ -3216,7 +3545,7 @@
   // Simulate form submission.
   base::HistogramTester histogram_tester;
   browser_autofill_manager_->OnFormsSeen(forms);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // An autofillable form was submitted, and the number of stored profiles is
@@ -3250,7 +3579,7 @@
   // Simulate form submission.
   base::HistogramTester histogram_tester;
   browser_autofill_manager_->OnFormsSeen(forms);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // A non-autofillable form was submitted, and number of stored profiles is NOT
@@ -3305,7 +3634,7 @@
                                                   gfx::RectF(), TimeTicks());
 
   // Simulate form submission.
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   ExpectedUkmMetricsRecord name_field_ukm_record{
       {UkmEditedAutofilledFieldAtSubmission::kFieldSignatureName,
@@ -3364,7 +3693,7 @@
                                                   gfx::RectF(), TimeTicks());
 
   // Simulate form submission.
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // The |NAME_FULL| field was edited (bucket 112).
@@ -3444,7 +3773,7 @@
                                                   gfx::RectF(), TimeTicks());
 
   // Simulate form submission.
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   // An autofillable form was submitted, and the number of edited autofilled
@@ -4252,7 +4581,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     EXPECT_EQ(1,
               user_action_tester.GetActionCount("Autofill_OnWillSubmitForm"));
     EXPECT_EQ(1, user_action_tester.GetActionCount(
@@ -4430,7 +4759,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     EXPECT_EQ(1,
               user_action_tester.GetActionCount("Autofill_OnWillSubmitForm"));
     EXPECT_EQ(1, user_action_tester.GetActionCount(
@@ -5333,7 +5662,7 @@
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
@@ -5721,7 +6050,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -5766,7 +6095,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -5815,7 +6144,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -5865,7 +6194,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -5915,7 +6244,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -5970,7 +6299,7 @@
       AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(),
       browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
 
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.CreditCard",
@@ -6026,7 +6355,7 @@
                                                 field);
   browser_autofill_manager_->OnQueryFormFieldAutofill(
       0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
       "Autofill.FormEvents.Address",
@@ -6071,7 +6400,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
@@ -6106,7 +6435,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1);
@@ -6153,7 +6482,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     // Trigger UploadFormDataAsyncCallback.
     browser_autofill_manager_->Reset();
     histogram_tester.ExpectBucketCount(
@@ -6202,7 +6531,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6249,7 +6578,7 @@
         guid, kDefaultPageID, form, form.fields.front());
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_VIRTUAL_CARD_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6296,7 +6625,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6342,7 +6671,7 @@
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1);
@@ -6393,7 +6722,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     VerifySubmitFormUkm(test_ukm_recorder_, form,
                         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA,
@@ -6402,7 +6731,7 @@
                         {FormType::kCreditCardForm});
 
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     VerifyUkm(
         test_ukm_recorder_, form, UkmFormSubmittedType::kEntryName,
@@ -6499,7 +6828,7 @@
     browser_autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
                                                   field);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
@@ -6619,7 +6948,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6646,7 +6975,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
@@ -6675,7 +7004,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6705,7 +7034,7 @@
         guid, kDefaultPageID, form, form.fields.front());
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_VIRTUAL_CARD_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6735,7 +7064,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6794,9 +7123,9 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -6870,7 +7199,7 @@
     browser_autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
                                                   field);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard",
         FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0);
@@ -7030,7 +7359,7 @@
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.WithOffer",
         FORM_EVENT_SUGGESTIONS_SHOWN, 1);
@@ -7088,7 +7417,7 @@
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.WithOffer",
         FORM_EVENT_SUGGESTIONS_SHOWN, 1);
@@ -7151,7 +7480,7 @@
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     OnDidGetRealPan(AutofillClient::SUCCESS, "6011000990139424");
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     // Histograms without ".WithOffer" should be recorded.
     histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
                                        FORM_EVENT_SUGGESTIONS_SHOWN, 1);
@@ -7232,7 +7561,7 @@
     browser_autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
                                                   field);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.WithOffer",
         FORM_EVENT_SUGGESTIONS_SHOWN, 2);
@@ -7291,7 +7620,7 @@
 
     // Submitting the form without the filled suggestion.
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.WithOffer",
         FORM_EVENT_SUGGESTIONS_SHOWN, 1);
@@ -7358,7 +7687,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(),
         browser_autofill_manager_->MakeFrontendIDForTest(guid, std::string()));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.WithOffer",
         FORM_EVENT_SUGGESTIONS_SHOWN, 2);
@@ -7927,7 +8256,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -7954,7 +8283,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     // Trigger UploadFormDataAsyncCallback.
     browser_autofill_manager_->Reset();
     histogram_tester.ExpectBucketCount(
@@ -7983,7 +8312,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
@@ -8007,7 +8336,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(std::string(), guid));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -8026,9 +8355,9 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
@@ -8068,7 +8397,7 @@
     browser_autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
                                                   field);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
@@ -8143,7 +8472,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -8165,7 +8494,7 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1);
@@ -8189,7 +8518,7 @@
         AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(),
         browser_autofill_manager_->MakeFrontendIDForTest(std::string(), guid));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1);
@@ -8209,9 +8538,9 @@
     browser_autofill_manager_->OnQueryFormFieldAutofill(
         0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
@@ -8260,7 +8589,7 @@
     browser_autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form,
                                                   field);
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
         "Autofill.FormEvents.Address",
         FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0);
@@ -8683,7 +9012,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
@@ -8718,7 +9047,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1);
@@ -8755,7 +9084,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS,
@@ -8790,7 +9119,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS, 1);
@@ -8838,7 +9167,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME, 1);
@@ -8874,7 +9203,7 @@
     base::HistogramTester histogram_tester;
     base::UserActionTester user_action_tester;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL, 1);
@@ -8951,7 +9280,7 @@
     form.fields[2].is_autofilled = true;
 
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormSubmittedState",
         AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL, 1);
@@ -9555,7 +9884,7 @@
                                      ->second->form_parsed_timestamp();
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectTotalCount(
         "Autofill.FillDuration.FromLoad.WithAutofill", 0);
@@ -9582,7 +9911,7 @@
         parse_time + base::TimeDelta::FromMicroseconds(3));
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectTotalCount(
         "Autofill.FillDuration.FromLoad.WithAutofill", 0);
@@ -9610,7 +9939,7 @@
         form, parse_time + base::TimeDelta::FromMicroseconds(5));
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectUniqueSample(
         "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1);
@@ -9644,7 +9973,7 @@
         parse_time + base::TimeDelta::FromMicroseconds(3));
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectUniqueSample(
         "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1);
@@ -9676,7 +10005,7 @@
         parse_time + base::TimeDelta::FromMicroseconds(3));
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectUniqueSample(
         "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1);
@@ -9705,7 +10034,8 @@
     }
     test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
     browser_autofill_manager_->OnFormSubmitted(
-        second_form, false, SubmissionSource::FORM_SUBMISSION);
+        second_form, /*known_success=*/false,
+        SubmissionSource::FORM_SUBMISSION);
 
     histogram_tester.ExpectTotalCount(
         "Autofill.FillDuration.FromLoad.WithAutofill", 0);
@@ -10007,7 +10337,7 @@
   // Expect to log NEW_PROFILE_CREATED for the metric since a new profile is
   // submitted.
   browser_autofill_manager_->OnFormsSeen(forms);
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
                                      AutofillMetrics::NEW_PROFILE_CREATED, 1);
@@ -10020,8 +10350,8 @@
   // Expect to log EXISTING_PROFILE_USED for the metric since the same profile
   // is submitted.
   browser_autofill_manager_->OnFormsSeen(second_forms);
-  browser_autofill_manager_->OnFormSubmitted(second_form, false,
-                                             SubmissionSource::FORM_SUBMISSION);
+  browser_autofill_manager_->OnFormSubmitted(
+      second_form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
                                      AutofillMetrics::NEW_PROFILE_CREATED, 1);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
@@ -10033,8 +10363,8 @@
   // Expect to log NEW_PROFILE_CREATED for the metric since a new profile is
   // submitted.
   browser_autofill_manager_->OnFormsSeen(third_forms);
-  browser_autofill_manager_->OnFormSubmitted(third_form, false,
-                                             SubmissionSource::FORM_SUBMISSION);
+  browser_autofill_manager_->OnFormSubmitted(
+      third_form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
                                      AutofillMetrics::NEW_PROFILE_CREATED, 2);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
@@ -10046,8 +10376,8 @@
   // Expect to log EXISTING_PROFILE_UPDATED for the metric since the profile was
   // updated.
   browser_autofill_manager_->OnFormsSeen(fourth_forms);
-  browser_autofill_manager_->OnFormSubmitted(fourth_form, false,
-                                             SubmissionSource::FORM_SUBMISSION);
+  browser_autofill_manager_->OnFormSubmitted(
+      fourth_form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
                                      AutofillMetrics::NEW_PROFILE_CREATED, 2);
   histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted",
@@ -10260,7 +10590,7 @@
   {
     base::HistogramTester histograms;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histograms.ExpectBucketCount(
         "Autofill.FormEvents.CreditCard.OnNonsecurePage",
         FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1);
@@ -10322,7 +10652,7 @@
   {
     base::HistogramTester histograms;
     browser_autofill_manager_->OnFormSubmitted(
-        form, false, SubmissionSource::FORM_SUBMISSION);
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
     histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
                                  FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1);
     histograms.ExpectBucketCount("Autofill.FormEvents.CreditCard",
@@ -11239,6 +11569,65 @@
                          PhoneCollectionMetricState::kPhonePlusWebOTPPlusOTC));
 }
 
+TEST_F(AutofillMetricsTest, AutocompleteOneTimeCodeFormFilledDuration) {
+  base::TimeTicks now = AutofillTickClock::NowTicks();
+  TestAutofillTickClock test_clock;
+  test_clock.SetNowTicks(now);
+
+  FormData form;
+  form.host_frame = test::GetLocalFrameToken();
+  form.unique_renderer_id = test::MakeFormRendererId();
+  form.name = u"TestForm";
+  form.url = GURL("http://example.com/form.html");
+  form.action = GURL("http://example.com/submit.html");
+  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+
+  FormFieldData field;
+  test::CreateTestFormField("", "", "", "password", &field);
+  field.autocomplete_attribute = "one-time-code";
+  form.fields.push_back(field);
+
+  std::vector<FormData> forms(1, form);
+  form.fields[0].value = u"123456";
+
+  {
+    base::HistogramTester histogram_tester;
+    browser_autofill_manager_->OnFormsSeen(forms);
+    base::TimeTicks parse_time = browser_autofill_manager_->form_structures()
+                                     .begin()
+                                     ->second->form_parsed_timestamp();
+    test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
+    browser_autofill_manager_->OnFormSubmitted(
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
+
+    histogram_tester.ExpectTotalCount(
+        "Autofill.WebOTP.OneTimeCode.FillDuration.FromLoad", 1);
+    histogram_tester.ExpectUniqueSample(
+        "Autofill.WebOTP.OneTimeCode.FillDuration.FromLoad", 16, 1);
+    browser_autofill_manager_->Reset();
+  }
+
+  {
+    base::HistogramTester histogram_tester;
+    browser_autofill_manager_->OnFormsSeen(forms);
+    base::TimeTicks parse_time = browser_autofill_manager_->form_structures()
+                                     .begin()
+                                     ->second->form_parsed_timestamp();
+    browser_autofill_manager_->OnDidFillAutofillFormData(
+        form, parse_time + base::TimeDelta::FromMicroseconds(5));
+    browser_autofill_manager_->OnTextFieldDidChange(
+        form, form.fields.front(), gfx::RectF(),
+        parse_time + base::TimeDelta::FromMicroseconds(3));
+    test_clock.SetNowTicks(parse_time + base::TimeDelta::FromMicroseconds(17));
+    browser_autofill_manager_->OnFormSubmitted(
+        form, /*known_success=*/false, SubmissionSource::FORM_SUBMISSION);
+
+    histogram_tester.ExpectUniqueSample(
+        "Autofill.WebOTP.OneTimeCode.FillDuration.FromInteraction", 14, 1);
+    browser_autofill_manager_->Reset();
+  }
+}
+
 #endif  // !defined(OS_IOS)
 
 TEST_F(AutofillMetricsTest, LogAutocompleteSuggestionAcceptedIndex_WithIndex) {
@@ -11907,7 +12296,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   histogram_tester.ExpectUniqueSample(
@@ -11931,7 +12320,7 @@
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
-  browser_autofill_manager_->OnFormSubmitted(form, false,
+  browser_autofill_manager_->OnFormSubmitted(form, /*known_success=*/false,
                                              SubmissionSource::FORM_SUBMISSION);
 
   histogram_tester.ExpectUniqueSample(
diff --git a/components/autofill/core/browser/autofill_regex_constants.cc b/components/autofill/core/browser/autofill_regex_constants.cc
index 097f6c3..b6e8edf 100644
--- a/components/autofill/core/browser/autofill_regex_constants.cc
+++ b/components/autofill/core/browser/autofill_regex_constants.cc
@@ -42,7 +42,7 @@
     u"|calle";                  // es-MX
 const char16_t kHouseNumberRe[] =
     u"(house.?|street.?|^)number"              // en
-    u"|(haus|^)nummer"                         // de
+    u"|(haus|^)(nummer|nr\\.?)"                // de
     u"|^\\*?.?número(.?\\*?$| da residência)"  // pt-BR, pt-PT
     u"|дом|номер.?дома"                        // ru
     u"|exterior";                              // es-MX
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 427bb97..469e68d 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -1177,6 +1177,11 @@
   // Use the same timestamp on UKM Metrics generated within this method's scope.
   AutofillMetrics::UkmTimestampPin timestamp_pin(form_interactions_ukm_logger);
 
+  // Determine the type of the form.
+  DenseSet<FormType> form_types = GetFormTypes();
+  bool card_form = base::Contains(form_types, FormType::kCreditCardForm);
+  bool address_form = base::Contains(form_types, FormType::kAddressForm);
+
   size_t num_detected_field_types = 0;
   size_t num_edited_autofilled_fields = 0;
   size_t num_of_accepted_autofilled_fields = 0;
@@ -1185,6 +1190,10 @@
   bool did_autofill_some_possible_fields = false;
   bool is_for_credit_card = IsCompleteCreditCardForm();
   bool has_upi_vpa_field = false;
+  bool has_observed_one_time_code_field = false;
+  // A perfectly filled form is submitted as it was filled from Autofill without
+  // subsequent changes.
+  bool perfect_filling = true;
 
   // Determine the correct suffix for the metric, depending on whether or
   // not a submission was observed.
@@ -1216,6 +1225,14 @@
     if (field->previously_autofilled())
       num_edited_autofilled_fields++;
 
+    if (field->Type().html_type() == HTML_TYPE_ONE_TIME_CODE)
+      has_observed_one_time_code_field = true;
+
+    // The form was not perfectly filled if a non-empty field was not
+    // autofilled.
+    if (!field->value.empty() && !field->is_autofilled)
+      perfect_filling = false;
+
     const ServerFieldTypeSet& field_types = field->possible_types();
     DCHECK(!field_types.empty());
     if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) {
@@ -1301,9 +1318,40 @@
       }
     }
 
+    if (has_observed_one_time_code_field) {
+      if (!load_time.is_null()) {
+        DCHECK_GE(submission_time, load_time);
+        base::TimeDelta elapsed = submission_time - load_time;
+        AutofillMetrics::LogFormFillDurationFromLoadForOneTimeCode(elapsed);
+      }
+      if (!interaction_time.is_null()) {
+        DCHECK(submission_time > interaction_time);
+        base::TimeDelta elapsed = submission_time - interaction_time;
+        AutofillMetrics::LogFormFillDurationFromInteractionForOneTimeCode(
+            elapsed);
+      }
+    }
+
     AutofillMetrics::LogAutofillFormSubmittedState(
         state, is_for_credit_card, has_upi_vpa_field, GetFormTypes(),
         form_parsed_timestamp_, form_signature(), form_interactions_ukm_logger);
+
+    // The perfect filling metric is only recorded if Autofill was used on at
+    // least one field. This conditions this metric on Assistance, Readiness and
+    // Acceptance.
+    if (did_autofill_some_possible_fields) {
+      // Perfect filling is recorded for addresses and credit cards separately.
+      // Note that a form can be both an address and a credit card form
+      // simultaneously.
+      if (address_form) {
+        AutofillMetrics::LogAutofillPerfectFilling(/*is_address=*/true,
+                                                   perfect_filling);
+      }
+      if (card_form) {
+        AutofillMetrics::LogAutofillPerfectFilling(/*is_address=*/false,
+                                                   perfect_filling);
+      }
+    }
   }
 }
 
@@ -2605,11 +2653,19 @@
     auto type = field->Type().ToString();
     auto heuristic_type = AutofillType(field->heuristic_type()).ToString();
     auto server_type = AutofillType(field->server_type()).ToString();
+    if (field->server_type_prediction_is_override())
+      server_type += " (manual override)";
     auto html_type_description =
         field->html_type() != HTML_TYPE_UNSPECIFIED
             ? base::StrCat(
                   {", html: ", FieldTypeToStringPiece(field->html_type())})
             : "";
+    if (field->html_type() == HTML_TYPE_UNRECOGNIZED &&
+        (!base::FeatureList::IsEnabled(
+             features::kAutofillServerTypeTakesPrecedence) ||
+         !field->server_type_prediction_is_override())) {
+      html_type_description += " (disabling autofill)";
+    }
 
     buffer << Tr{} << "Type:"
            << base::StrCat({type, " (heuristic: ", heuristic_type, ", server: ",
diff --git a/components/autofill/core/browser/pattern_provider/resources/regex_patterns.json b/components/autofill/core/browser/pattern_provider/resources/regex_patterns.json
index f6c6ffc..dc426d20 100644
--- a/components/autofill/core/browser/pattern_provider/resources/regex_patterns.json
+++ b/components/autofill/core/browser/pattern_provider/resources/regex_patterns.json
@@ -127,7 +127,7 @@
     "de": [
       {
         "pattern_identifier": "de_house_number",
-        "positive_pattern": "(haus|^)nummer",
+        "positive_pattern": "(haus|^)(nummer|nr\\.?)",
         "positive_score": 1.1,
         "negative_pattern": null,
         "match_field_attributes": 3,
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 37127a1..fcf3a73 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -138,8 +138,7 @@
                                const AutofillTableEncryptor& encryptor) {
   std::string encrypted_data;
   encryptor.EncryptString16(number, &encrypted_data);
-  s->BindBlob(column_index, encrypted_data.data(),
-              static_cast<int>(encrypted_data.length()));
+  s->BindBlob(column_index, encrypted_data);
 }
 
 void BindCreditCardToStatement(const CreditCard& credit_card,
@@ -2040,8 +2039,7 @@
       "VALUES (?,?,?)"));
   s.BindString(0, credit_card_art_image.id);
   s.BindInt64(1, credit_card_art_image.instrument_id);
-  s.BindBlob(2, credit_card_art_image.card_art_image.data(),
-             credit_card_art_image.card_art_image.size());
+  s.BindBlob(2, credit_card_art_image.card_art_image);
   s.Run();
 
   return transaction.Commit();
@@ -3795,8 +3793,7 @@
 
   std::string encrypted_data;
   autofill_table_encryptor_->EncryptString16(full_number, &encrypted_data);
-  s.BindBlob(1, encrypted_data.data(),
-             static_cast<int>(encrypted_data.length()));
+  s.BindBlob(1, encrypted_data);
   s.BindInt64(2, AutofillClock::Now().ToInternalValue());  // unmask_date
 
   s.Run();
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 6234a6d8..a4847c3 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -231,7 +231,7 @@
 // field types that we don't fill (search term, price, ...) count towards that
 // counter, effectively reducing the threshold for some forms.
 const base::Feature kAutofillFixFillableFieldTypes{
-    "AutofillFixFillableFieldTypes", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AutofillFixFillableFieldTypes", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // The autocomplete attribute may prevent Autofill import, crbug/1213301. This
 // feature addresses the issue. For now, the fix only concerns fields with the
diff --git a/components/autofill/ios/form_util/fill_js_unittest.mm b/components/autofill/ios/form_util/fill_js_unittest.mm
index 1542bd2..9d0f9f3 100644
--- a/components/autofill/ios/form_util/fill_js_unittest.mm
+++ b/components/autofill/ios/form_util/fill_js_unittest.mm
@@ -5,8 +5,8 @@
 #import <Foundation/Foundation.h>
 #include <stddef.h>
 
+#include "base/cxx17_backports.h"
 #include "base/macros.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #import "components/autofill/ios/form_util/form_util_java_script_feature.h"
 #import "ios/web/public/test/web_test_with_web_state.h"
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn
index 876723b0..ffbb419 100644
--- a/components/autofill_assistant/browser/BUILD.gn
+++ b/components/autofill_assistant/browser/BUILD.gn
@@ -76,6 +76,8 @@
     "actions/set_form_field_value_action.h",
     "actions/set_persistent_ui_action.cc",
     "actions/set_persistent_ui_action.h",
+    "actions/set_touchable_area_action.cc",
+    "actions/set_touchable_area_action.h",
     "actions/show_cast_action.cc",
     "actions/show_cast_action.h",
     "actions/show_details_action.cc",
@@ -362,6 +364,7 @@
     "actions/set_attribute_action_unittest.cc",
     "actions/set_form_field_value_action_unittest.cc",
     "actions/set_persistent_ui_action_unittest.cc",
+    "actions/set_touchable_area_action_unittest.cc",
     "actions/show_cast_action_unittest.cc",
     "actions/show_details_action_unittest.cc",
     "actions/show_generic_ui_action_unittest.cc",
diff --git a/components/autofill_assistant/browser/actions/action.cc b/components/autofill_assistant/browser/actions/action.cc
index be0eb51..acc2dcc 100644
--- a/components/autofill_assistant/browser/actions/action.cc
+++ b/components/autofill_assistant/browser/actions/action.cc
@@ -234,6 +234,18 @@
     case ActionProto::ActionInfoCase::kClearPersistentUi:
       out << "ClearPersistentUi";
       break;
+    case ActionProto::ActionInfoCase::kScrollIntoViewIfNeeded:
+      out << "ScrollIntoViewIfNeeded";
+      break;
+    case ActionProto::ActionInfoCase::kScrollWindow:
+      out << "ScrollWindow";
+      break;
+    case ActionProto::ActionInfoCase::kScrollContainer:
+      out << "ScrollContainer";
+      break;
+    case ActionProto::ActionInfoCase::kSetTouchableArea:
+      out << "SetTouchableArea";
+      break;
     case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET:
       out << "ACTION_INFO_NOT_SET";
       break;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index da358e14..a2fbf05 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -429,10 +429,6 @@
   // detected, depending on the current settings.
   virtual void MaybeShowSlowConnectionWarning() = 0;
 
-  // Dispatches a custom JS event 'duplexweb' on document.
-  virtual void DispatchJsEvent(
-      base::OnceCallback<void(const ClientStatus&)> callback) const = 0;
-
   virtual base::WeakPtr<ActionDelegate> GetWeakPtr() const = 0;
 
  protected:
diff --git a/components/autofill_assistant/browser/actions/action_delegate_util.cc b/components/autofill_assistant/browser/actions/action_delegate_util.cc
index ad90dac..5b9ddeb 100644
--- a/components/autofill_assistant/browser/actions/action_delegate_util.cc
+++ b/components/autofill_assistant/browser/actions/action_delegate_util.cc
@@ -92,9 +92,11 @@
                      delegate->GetSettings().document_ready_check_timeout,
                      DOCUMENT_INTERACTIVE),
       actions);
-  actions->emplace_back(
-      base::BindOnce(&WebController::ScrollIntoView,
-                     delegate->GetWebController()->GetWeakPtr(), true));
+  actions->emplace_back(base::BindOnce(
+      &WebController::ScrollIntoView,
+      delegate->GetWebController()->GetWeakPtr(),
+      /* animation= */ std::string(), /* vertical_alignment= */ "center",
+      /* horizontal_alignment= */ "center"));
   if (click_type == ClickType::JAVASCRIPT) {
     actions->emplace_back(
         base::BindOnce(&WebController::JsClickElement,
diff --git a/components/autofill_assistant/browser/actions/dispatch_js_event_action.cc b/components/autofill_assistant/browser/actions/dispatch_js_event_action.cc
index fe626f43..4747c9a 100644
--- a/components/autofill_assistant/browser/actions/dispatch_js_event_action.cc
+++ b/components/autofill_assistant/browser/actions/dispatch_js_event_action.cc
@@ -12,6 +12,7 @@
 #include "components/autofill_assistant/browser/actions/action_delegate_util.h"
 #include "components/autofill_assistant/browser/client_status.h"
 #include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/web/web_controller.h"
 
 namespace autofill_assistant {
 
@@ -25,7 +26,7 @@
 
 void DispatchJsEventAction::InternalProcessAction(
     ProcessActionCallback callback) {
-  delegate_->DispatchJsEvent(
+  delegate_->GetWebController()->DispatchJsEvent(
       base::BindOnce(&DispatchJsEventAction::OnDispatchJsEvent,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
diff --git a/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc b/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc
index 13af118..6325992 100644
--- a/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/test/mock_callback.h"
 #include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
 #include "components/autofill_assistant/browser/service.pb.h"
+#include "components/autofill_assistant/browser/web/mock_web_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace autofill_assistant {
@@ -16,13 +17,16 @@
 using ::base::test::RunOnceCallback;
 using ::testing::_;
 using ::testing::Property;
+using ::testing::Return;
 
 class DispatchJsEventActionTest : public testing::Test {
  public:
   DispatchJsEventActionTest() {}
 
   void SetUp() override {
-    ON_CALL(mock_action_delegate_, DispatchJsEvent(_))
+    ON_CALL(mock_action_delegate_, GetWebController())
+        .WillByDefault(Return(&mock_web_controller_));
+    ON_CALL(mock_web_controller_, DispatchJsEvent(_))
         .WillByDefault(RunOnceCallback<0>(OkClientStatus()));
   }
 
@@ -35,12 +39,13 @@
   }
 
   MockActionDelegate mock_action_delegate_;
+  MockWebController mock_web_controller_;
   base::MockCallback<Action::ProcessActionCallback> callback_;
   DispatchJsEventProto proto_;
 };
 
-TEST_F(DispatchJsEventActionTest, EmptyProtoSetsMessageDoesNothing) {
-  EXPECT_CALL(mock_action_delegate_, DispatchJsEvent(_));
+TEST_F(DispatchJsEventActionTest, EmptyProtoSendsEvent) {
+  EXPECT_CALL(mock_web_controller_, DispatchJsEvent(_));
   EXPECT_CALL(
       callback_,
       Run(Pointee(Property(&ProcessedActionProto::status, ACTION_APPLIED))));
diff --git a/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler_unittest.cc b/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler_unittest.cc
index 9c6f111..68dbe4f 100644
--- a/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler_unittest.cc
+++ b/components/autofill_assistant/browser/actions/fallback_handler/required_fields_fallback_handler_unittest.cc
@@ -67,8 +67,8 @@
     ON_CALL(mock_action_delegate_, WaitUntilDocumentIsInReadyState(_, _, _, _))
         .WillByDefault(RunOnceCallback<3>(OkClientStatus(),
                                           base::TimeDelta::FromSeconds(0)));
-    ON_CALL(mock_web_controller_, ScrollIntoView(_, _, _))
-        .WillByDefault(RunOnceCallback<2>(OkClientStatus()));
+    ON_CALL(mock_web_controller_, ScrollIntoView(_, _, _, _, _))
+        .WillByDefault(RunOnceCallback<4>(OkClientStatus()));
     ON_CALL(mock_web_controller_, WaitUntilElementIsStable(_, _, _, _))
         .WillByDefault(RunOnceCallback<3>(OkClientStatus(),
                                           base::TimeDelta::FromSeconds(0)));
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h
index efa2b00..101f590 100644
--- a/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -207,9 +207,6 @@
   MOCK_METHOD1(MaybeShowSlowWebsiteWarning,
                void(base::OnceCallback<void(bool)>));
   MOCK_METHOD0(MaybeShowSlowConnectionWarning, void());
-  MOCK_CONST_METHOD1(
-      DispatchJsEvent,
-      void(base::OnceCallback<void(const ClientStatus&)> callback));
 
   base::WeakPtr<ActionDelegate> GetWeakPtr() const override {
     return weak_ptr_factory_.GetWeakPtr();
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc b/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
index 8303a30d..eac3adb 100644
--- a/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
@@ -84,8 +84,8 @@
     ON_CALL(mock_action_delegate_, WaitUntilDocumentIsInReadyState(_, _, _, _))
         .WillByDefault(RunOnceCallback<3>(OkClientStatus(),
                                           base::TimeDelta::FromSeconds(0)));
-    ON_CALL(mock_web_controller_, ScrollIntoView(_, _, _))
-        .WillByDefault(RunOnceCallback<2>(OkClientStatus()));
+    ON_CALL(mock_web_controller_, ScrollIntoView(_, _, _, _, _))
+        .WillByDefault(RunOnceCallback<4>(OkClientStatus()));
     ON_CALL(mock_web_controller_, WaitUntilElementIsStable(_, _, _, _))
         .WillByDefault(RunOnceCallback<3>(OkClientStatus(),
                                           base::TimeDelta::FromSeconds(0)));
@@ -394,8 +394,9 @@
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
   EXPECT_CALL(mock_web_controller_,
-              ScrollIntoView(true, EqualsElement(expected_element), _))
-      .WillOnce(RunOnceCallback<2>(OkClientStatus()));
+              ScrollIntoView(std::string(), "center", "center",
+                             EqualsElement(expected_element), _))
+      .WillOnce(RunOnceCallback<4>(OkClientStatus()));
   EXPECT_CALL(
       mock_web_controller_,
       ClickOrTapElement(ClickType::TAP, EqualsElement(expected_element), _))
@@ -455,8 +456,9 @@
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
   EXPECT_CALL(mock_web_controller_,
-              ScrollIntoView(true, EqualsElement(expected_element), _))
-      .WillOnce(RunOnceCallback<2>(OkClientStatus()));
+              ScrollIntoView(std::string(), "center", "center",
+                             EqualsElement(expected_element), _))
+      .WillOnce(RunOnceCallback<4>(OkClientStatus()));
   EXPECT_CALL(
       mock_web_controller_,
       ClickOrTapElement(ClickType::CLICK, EqualsElement(expected_element), _))
diff --git a/components/autofill_assistant/browser/actions/set_touchable_area_action.cc b/components/autofill_assistant/browser/actions/set_touchable_area_action.cc
new file mode 100644
index 0000000..a3f5b18
--- /dev/null
+++ b/components/autofill_assistant/browser/actions/set_touchable_area_action.cc
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/actions/set_touchable_area_action.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "components/autofill_assistant/browser/actions/action_delegate.h"
+#include "components/autofill_assistant/browser/client_status.h"
+
+namespace autofill_assistant {
+
+SetTouchableAreaAction::SetTouchableAreaAction(ActionDelegate* delegate,
+                                               const ActionProto& proto)
+    : Action(delegate, proto) {
+  DCHECK(proto_.has_set_touchable_area());
+}
+
+SetTouchableAreaAction::~SetTouchableAreaAction() {}
+
+void SetTouchableAreaAction::InternalProcessAction(
+    ProcessActionCallback callback) {
+  delegate_->SetTouchableElementArea(
+      proto().set_touchable_area().element_area());
+  UpdateProcessedAction(OkClientStatus());
+  std::move(callback).Run(std::move(processed_action_proto_));
+}
+
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/set_touchable_area_action.h b/components/autofill_assistant/browser/actions/set_touchable_area_action.h
new file mode 100644
index 0000000..27a2893
--- /dev/null
+++ b/components/autofill_assistant/browser/actions/set_touchable_area_action.h
@@ -0,0 +1,32 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SET_TOUCHABLE_AREA_ACTION_H_
+#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SET_TOUCHABLE_AREA_ACTION_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "components/autofill_assistant/browser/actions/action.h"
+
+namespace autofill_assistant {
+
+// Sets the touchable and restricted area of the overlay.
+class SetTouchableAreaAction : public Action {
+ public:
+  explicit SetTouchableAreaAction(ActionDelegate* delegate,
+                                  const ActionProto& proto);
+  ~SetTouchableAreaAction() override;
+
+  SetTouchableAreaAction(const SetTouchableAreaAction&) = delete;
+  SetTouchableAreaAction& operator=(const SetTouchableAreaAction&) = delete;
+
+ private:
+  // Overrides Action:
+  void InternalProcessAction(ProcessActionCallback callback) override;
+
+  base::WeakPtrFactory<SetTouchableAreaAction> weak_ptr_factory_{this};
+};
+
+}  // namespace autofill_assistant
+#endif  // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_CAST_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/set_touchable_area_action_unittest.cc b/components/autofill_assistant/browser/actions/set_touchable_area_action_unittest.cc
new file mode 100644
index 0000000..ce2e78c2
--- /dev/null
+++ b/components/autofill_assistant/browser/actions/set_touchable_area_action_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill_assistant/browser/actions/set_touchable_area_action.h"
+
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
+#include "components/autofill_assistant/browser/actions/mock_action_delegate.h"
+#include "components/autofill_assistant/browser/selector.h"
+#include "components/autofill_assistant/browser/service.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace autofill_assistant {
+namespace {
+
+using ::testing::_;
+using ::testing::SaveArgPointee;
+
+class SetTouchableAreaActionTest : public testing::Test {
+ public:
+  SetTouchableAreaActionTest() {}
+  void SetUp() override {}
+
+ protected:
+  void Run() {
+    ActionProto action_proto;
+    *action_proto.mutable_set_touchable_area() = proto_;
+    SetTouchableAreaAction action(&mock_action_delegate_, action_proto);
+    action.ProcessAction(callback_.Get());
+  }
+
+  MockActionDelegate mock_action_delegate_;
+  base::MockCallback<Action::ProcessActionCallback> callback_;
+  SetTouchableAreaProto proto_;
+};
+
+TEST_F(SetTouchableAreaActionTest, SetsTouchableElementArea) {
+  Selector touchable_element({"#id"});
+  *proto_.mutable_element_area()->add_touchable()->add_elements() =
+      touchable_element.proto;
+
+  EXPECT_CALL(mock_action_delegate_, SetTouchableElementArea(_));
+
+  ProcessedActionProto capture;
+  EXPECT_CALL(callback_, Run(_)).WillOnce(testing::SaveArgPointee<0>(&capture));
+  Run();
+
+  EXPECT_EQ(capture.status(), ACTION_APPLIED);
+}
+
+}  // namespace
+}  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/show_cast_action.cc b/components/autofill_assistant/browser/actions/show_cast_action.cc
index 03c63c7a..4c355cb 100644
--- a/components/autofill_assistant/browser/actions/show_cast_action.cc
+++ b/components/autofill_assistant/browser/actions/show_cast_action.cc
@@ -122,8 +122,8 @@
   }
   action_delegate_util::AddOptionalStep(
       wait_for_stable_element,
-      base::BindOnce(&WebController::ScrollIntoView,
-                     delegate_->GetWebController()->GetWeakPtr(), false),
+      base::BindOnce(&WebController::ScrollIntoViewIfNeeded,
+                     delegate_->GetWebController()->GetWeakPtr(), true),
       actions.get());
   action_delegate_util::AddOptionalStep(
       wait_for_stable_element,
diff --git a/components/autofill_assistant/browser/actions/show_cast_action.h b/components/autofill_assistant/browser/actions/show_cast_action.h
index 43a25b0..0abcd048 100644
--- a/components/autofill_assistant/browser/actions/show_cast_action.h
+++ b/components/autofill_assistant/browser/actions/show_cast_action.h
@@ -5,14 +5,13 @@
 #ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_CAST_ACTION_H_
 #define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_CAST_ACTION_H_
 
-#include "components/autofill_assistant/browser/actions/action.h"
-#include "components/autofill_assistant/browser/top_padding.h"
-
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
+#include "components/autofill_assistant/browser/actions/action.h"
 #include "components/autofill_assistant/browser/client_status.h"
+#include "components/autofill_assistant/browser/top_padding.h"
 #include "components/autofill_assistant/browser/web/element_finder.h"
 
 namespace autofill_assistant {
diff --git a/components/autofill_assistant/browser/actions/show_cast_action_unittest.cc b/components/autofill_assistant/browser/actions/show_cast_action_unittest.cc
index 30b653ed..f8c8f32 100644
--- a/components/autofill_assistant/browser/actions/show_cast_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/show_cast_action_unittest.cc
@@ -161,7 +161,7 @@
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
   EXPECT_CALL(mock_web_controller_,
-              ScrollIntoView(false, EqualsElement(expected_element), _))
+              ScrollIntoViewIfNeeded(true, EqualsElement(expected_element), _))
       .WillOnce(RunOnceCallback<2>(OkClientStatus()));
   EXPECT_CALL(
       mock_web_controller_,
diff --git a/components/autofill_assistant/browser/actions/use_address_action_unittest.cc b/components/autofill_assistant/browser/actions/use_address_action_unittest.cc
index 3410f16..855ecfb 100644
--- a/components/autofill_assistant/browser/actions/use_address_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/use_address_action_unittest.cc
@@ -566,8 +566,9 @@
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
   EXPECT_CALL(mock_web_controller_,
-              ScrollIntoView(true, EqualsElement(expected_element), _))
-      .WillOnce(RunOnceCallback<2>(OkClientStatus()));
+              ScrollIntoView(std::string(), "center", "center",
+                             EqualsElement(expected_element), _))
+      .WillOnce(RunOnceCallback<4>(OkClientStatus()));
   EXPECT_CALL(mock_web_controller_, WaitUntilElementIsStable(_, _, _, _))
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
diff --git a/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc b/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc
index 5f162fa2..c39887f 100644
--- a/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc
@@ -398,8 +398,9 @@
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
   EXPECT_CALL(mock_web_controller_,
-              ScrollIntoView(true, EqualsElement(expected_element), _))
-      .WillOnce(RunOnceCallback<2>(OkClientStatus()));
+              ScrollIntoView(std::string(), "center", "center",
+                             EqualsElement(expected_element), _))
+      .WillOnce(RunOnceCallback<4>(OkClientStatus()));
   EXPECT_CALL(mock_web_controller_, WaitUntilElementIsStable(_, _, _, _))
       .WillOnce(RunOnceCallback<3>(OkClientStatus(),
                                    base::TimeDelta::FromSeconds(0)));
diff --git a/components/autofill_assistant/browser/controller.cc b/components/autofill_assistant/browser/controller.cc
index a9d4434..bd59de9 100644
--- a/components/autofill_assistant/browser/controller.cc
+++ b/components/autofill_assistant/browser/controller.cc
@@ -25,7 +25,6 @@
 #include "components/autofill_assistant/browser/user_data.h"
 #include "components/autofill_assistant/browser/user_data_util.h"
 #include "components/autofill_assistant/browser/view_layout.pb.h"
-#include "components/autofill_assistant/browser/web/element_store.h"
 #include "components/google/core/common/google_util.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/strings/grit/components_strings.h"
@@ -128,13 +127,6 @@
   return web_controller_.get();
 }
 
-ElementStore* Controller::GetElementStore() const {
-  if (!element_store_) {
-    element_store_ = std::make_unique<ElementStore>(web_contents());
-  }
-  return element_store_.get();
-}
-
 const TriggerContext* Controller::GetTriggerContext() {
   DCHECK(trigger_context_);
   return trigger_context_.get();
diff --git a/components/autofill_assistant/browser/controller.h b/components/autofill_assistant/browser/controller.h
index f0ccd0af..c4229182 100644
--- a/components/autofill_assistant/browser/controller.h
+++ b/components/autofill_assistant/browser/controller.h
@@ -31,7 +31,6 @@
 #include "components/autofill_assistant/browser/user_action.h"
 #include "components/autofill_assistant/browser/user_data.h"
 #include "components/autofill_assistant/browser/user_model.h"
-#include "components/autofill_assistant/browser/web/element_store.h"
 #include "components/autofill_assistant/browser/web/web_controller.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -107,7 +106,6 @@
   const GURL& GetScriptURL() override;
   Service* GetService() override;
   WebController* GetWebController() override;
-  ElementStore* GetElementStore() const override;
   const TriggerContext* GetTriggerContext() override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   WebsiteLoginManager* GetWebsiteLoginManager() override;
@@ -416,9 +414,6 @@
   // Lazily instantiate in GetWebController().
   std::unique_ptr<WebController> web_controller_;
 
-  // Lazily initiate in GetElementStore();
-  mutable std::unique_ptr<ElementStore> element_store_;
-
   // Lazily instantiate in GetService().
   std::unique_ptr<Service> service_;
   std::unique_ptr<TriggerContext> trigger_context_;
diff --git a/components/autofill_assistant/browser/dom_action.proto b/components/autofill_assistant/browser/dom_action.proto
index b7b75fc..6520f36 100644
--- a/components/autofill_assistant/browser/dom_action.proto
+++ b/components/autofill_assistant/browser/dom_action.proto
@@ -22,16 +22,63 @@
 // Scroll the element into the view center.
 message ScrollIntoViewProto {
   optional ClientIdProto client_id = 1;
+  // Defines the transition animation. One of "auto" or "smooth". Defaults to
+  // "auto".
+  optional string animation = 2;
+  // Defines vertical alignment. One of "start", "center", "end" or "nearest".
+  // Defaults to "center".
+  optional string vertical_alignment = 3;
+  // Defines horizontal alignment. One of "start", "center", "end" or "nearest".
+  // Defaults to "center".
+  optional string horizontal_alignment = 4;
+}
+
+// Scroll the element into view only if necessary. Do not do anything otherwise.
+message ScrollIntoViewIfNeededProto {
+  optional ClientIdProto client_id = 1;
+  // Defines whether to center or scroll to the nearest edge. Defaults to true.
+  optional bool center = 2;
+}
+
+message ScrollDistance {
+  oneof value {
+    // Padding in CSS pixels.
+    int32 pixels = 1;
+    // Ratio in relation to the window in direction of the scrolling. E.g.
+    // |window.innerHeight|.
+    float window_ratio = 2;
+  }
+}
+
+message ScrollWindowProto {
+  // Optional frame. If not specified, will scroll the main window.
+  optional ClientIdProto optional_frame_id = 1;
+  optional ScrollDistance scroll_distance = 2;
+  // Defines the transition animation. One of "auto" or "smooth". Defaults to
+  // "auto".
+  optional string animation = 3;
+}
+
+message ScrollContainerProto {
+  optional ClientIdProto client_id = 1;
+  optional ScrollDistance scroll_distance = 2;
+  // Defines the transition animation. One of "auto" or "smooth". Defaults to
+  // "auto".
+  optional string animation = 3;
 }
 
 // Wait for the document ready status to be at least "interactive".
 message WaitForDocumentToBecomeInteractiveProto {
+  // Optional frame. If not specified, will wait for the state of the main
+  // frame.
   optional ClientIdProto client_id = 1;
   optional int32 timeout_in_ms = 2;
 }
 
 // Wait for the document ready status to be "complete".
 message WaitForDocumentToBecomeCompleteProto {
+  // Optional frame. If not specified, will wait for the state of the main
+  // frame.
   optional ClientIdProto client_id = 1;
   optional int32 timeout_in_ms = 2;
 }
diff --git a/components/autofill_assistant/browser/element_area.cc b/components/autofill_assistant/browser/element_area.cc
index 04af596..95c660b6 100644
--- a/components/autofill_assistant/browser/element_area.cc
+++ b/components/autofill_assistant/browser/element_area.cc
@@ -51,7 +51,6 @@
 
 void ElementArea::SetFromProto(const ElementAreaProto& proto) {
   rectangles_.clear();
-  last_visual_viewport_ = RectF();
   last_rectangles_.clear();
 
   AddRectangles(proto.touchable(), /* restricted= */ false);
@@ -99,10 +98,6 @@
   if (rectangles_.empty())
     return;
 
-  // If anything is still pending, skip the update.
-  if (visual_viewport_pending_update_)
-    return;
-
   for (auto& rectangle : rectangles_) {
     if (rectangle.IsPending())
       return;
@@ -110,7 +105,6 @@
 
   // Mark everything as pending at the same time, to avoid reporting partial
   // results.
-  visual_viewport_pending_update_ = true;
   for (auto& rectangle : rectangles_) {
     for (auto& position : rectangle.positions) {
       // To avoid reporting partial rectangles, all element positions become
@@ -119,14 +113,6 @@
     }
   }
 
-  // Viewport and element positions are always queried, and so reported, at the
-  // same time. This allows supporting both elements whose position is relative
-  // (and move with a scroll) as elements whose position is absolute (and don't
-  // move with a scroll.) Being able to tell the difference would be more
-  // effective and allow refreshing element positions less aggressively.
-  delegate_->GetWebController()->GetVisualViewport(base::BindOnce(
-      &ElementArea::OnGetVisualViewport, weak_ptr_factory_.GetWeakPtr()));
-
   for (auto& rectangle : rectangles_) {
     for (auto& position : rectangle.positions) {
       delegate_->GetWebController()->FindElement(
@@ -146,7 +132,7 @@
   for (auto& rectangle : rectangles_) {
     if (!rectangle.restricted) {
       area->emplace_back();
-      rectangle.FillRect(&area->back(), visual_viewport_);
+      rectangle.FillRect(&area->back());
     }
   }
 }
@@ -155,7 +141,7 @@
   for (auto& rectangle : rectangles_) {
     if (rectangle.restricted) {
       area->emplace_back();
-      rectangle.FillRect(&area->back(), visual_viewport_);
+      rectangle.FillRect(&area->back());
     }
   }
 }
@@ -186,8 +172,7 @@
   return false;
 }
 
-void ElementArea::Rectangle::FillRect(RectF* rect,
-                                      const RectF& visual_viewport) const {
+void ElementArea::Rectangle::FillRect(RectF* rect) const {
   bool has_first_rect = false;
   for (const auto& position : positions) {
     if (position.rect.empty()) {
@@ -204,10 +189,7 @@
     rect->left = std::min(rect->left, position.rect.left);
     rect->right = std::max(rect->right, position.rect.right);
   }
-  if (has_first_rect && full_width) {
-    rect->left = visual_viewport.left;
-    rect->right = visual_viewport.right;
-  }
+  rect->full_width = full_width;
   return;
 }
 
@@ -233,33 +215,11 @@
   // rectangles_. This is fine.
 }
 
-void ElementArea::OnGetVisualViewport(const ClientStatus& rect_status,
-                                      const RectF& rect) {
-  if (!visual_viewport_pending_update_)
-    return;
-
-  visual_viewport_pending_update_ = false;
-  if (!rect_status.ok())
-    return;
-
-  visual_viewport_ = rect;
-  ReportUpdate();
-}
-
 void ElementArea::ReportUpdate() {
   if (!on_update_)
     return;
 
   if (rectangles_.empty()) {
-    // Reporting of visual viewport is best effort when reporting empty
-    // rectangles. It might also be empty.
-    on_update_.Run({}, {});
-    return;
-  }
-
-  // If there are rectangles, delay reporting until both the visual viewport
-  // size and the rectangles are available.
-  if (visual_viewport_pending_update_) {
     return;
   }
 
@@ -270,8 +230,7 @@
     }
   }
 
-  if (visual_viewport_ == last_visual_viewport_ &&
-      rectangles_ == last_rectangles_) {
+  if (rectangles_ == last_rectangles_) {
     // The positions have not changed since the last update.
     return;
   }
@@ -281,9 +240,6 @@
   GetTouchableRectangles(&touchable_area);
   GetRestrictedRectangles(&restricted_area);
   if (VLOG_IS_ON(3)) {
-    if (!(visual_viewport_ == last_visual_viewport_)) {
-      VLOG(3) << "New viewport: " << visual_viewport_;
-    }
     if (!(rectangles_ == last_rectangles_)) {
       if (!touchable_area.empty()) {
         VLOG(3) << "New touchable rects: " << ToDebugString(touchable_area);
@@ -294,7 +250,6 @@
     }
   }
 
-  last_visual_viewport_ = visual_viewport_;
   last_rectangles_ = rectangles_;
   on_update_.Run(touchable_area, restricted_area);
 }
diff --git a/components/autofill_assistant/browser/element_area.h b/components/autofill_assistant/browser/element_area.h
index 5fccb548..ca6ce44e 100644
--- a/components/autofill_assistant/browser/element_area.h
+++ b/components/autofill_assistant/browser/element_area.h
@@ -96,7 +96,7 @@
     bool IsPending() const;
 
     // Fills the given rectangle from the current state, if possible.
-    void FillRect(RectF* rect, const RectF& visual_viewport) const;
+    void FillRect(RectF* rect) const;
 
     bool operator==(const Rectangle& another) const;
   };
@@ -116,22 +116,13 @@
   void OnGetElementRect(const Selector& selector,
                         const ClientStatus& rect_status,
                         const RectF& rect);
-  void OnGetVisualViewport(const ClientStatus& status, const RectF& rect);
   void ReportUpdate();
 
   ScriptExecutorDelegate* const delegate_;
   std::vector<Rectangle> rectangles_;
 
-  // If true, update for the visual viewport position is currently scheduled.
-  bool visual_viewport_pending_update_ = false;
-
-  // Visual viewport coordinates, in CSS pixels, relative to the layout
-  // viewport.
-  RectF visual_viewport_;
-
   // Cached positions from the last time an update was sent, used to avoid
   // sending updates when nothing has changed.
-  RectF last_visual_viewport_;
   std::vector<Rectangle> last_rectangles_;
 
   // While running, regularly calls Update().
diff --git a/components/autofill_assistant/browser/element_area_unittest.cc b/components/autofill_assistant/browser/element_area_unittest.cc
index 491cd44..5891f1ef 100644
--- a/components/autofill_assistant/browser/element_area_unittest.cc
+++ b/components/autofill_assistant/browser/element_area_unittest.cc
@@ -42,7 +42,24 @@
            bottom,
            ToString(RectF(left, top, right, bottom))) {
   if (abs(left - arg.left) < 0.01 && abs(top - arg.top) < 0.01 &&
-      abs(right - arg.right) < 0.01 && abs(bottom - arg.bottom) < 0.01) {
+      abs(right - arg.right) < 0.01 && abs(bottom - arg.bottom) < 0.01 &&
+      arg.full_width == false) {
+    return true;
+  }
+  *result_listener << arg;
+  return false;
+}
+
+MATCHER_P5(MatchingRectF,
+           left,
+           top,
+           right,
+           bottom,
+           full_width,
+           ToString(RectF(left, top, right, bottom, full_width))) {
+  if (abs(left - arg.left) < 0.01 && abs(top - arg.top) < 0.01 &&
+      abs(right - arg.right) < 0.01 && abs(bottom - arg.bottom) < 0.01 &&
+      full_width == arg.full_width) {
     return true;
   }
   *result_listener << arg;
@@ -74,9 +91,6 @@
     ON_CALL(mock_web_controller_, GetElementRect(_, _))
         .WillByDefault(
             RunOnceCallback<1>(ClientStatus(UNEXPECTED_JS_ERROR), RectF()));
-    ON_CALL(mock_web_controller_, GetVisualViewport(_))
-        .WillByDefault(
-            RunOnceCallback<0>(OkClientStatus(), RectF(0, 0, 200, 400)));
 
     element_area_.SetOnUpdate(base::BindRepeating(&ElementAreaTest::OnUpdate,
                                                   base::Unretained(this)));
@@ -174,37 +188,6 @@
   EXPECT_EQ(on_update_call_count_, 2);
 }
 
-TEST_F(ElementAreaTest, DontCallOnUpdateWhenViewportMissing) {
-  Selector expected_selector({"#found"});
-
-  // Swallowing calls to GetVisualViewport guarantees that the viewport
-  // position will never be known.
-  EXPECT_CALL(mock_web_controller_, GetVisualViewport(_)).WillOnce(DoNothing());
-  EXPECT_CALL(mock_web_controller_,
-              GetElementRect(EqualsElement(test_util::MockFindElement(
-                                 mock_web_controller_, expected_selector)),
-                             _))
-      .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75)));
-
-  SetElement("#found");
-  EXPECT_EQ(on_update_call_count_, 0);
-}
-
-TEST_F(ElementAreaTest, CallOnUpdateWhenViewportMissingAndEmptyRect) {
-  EXPECT_CALL(mock_web_controller_, GetVisualViewport(_))
-      .WillRepeatedly(
-          RunOnceCallback<0>(ClientStatus(UNEXPECTED_JS_ERROR), RectF()));
-
-  SetElement("#found");
-
-  // A newly empty element area should be reported.
-  on_update_call_count_ = 0;
-  element_area_.Clear();
-
-  EXPECT_EQ(on_update_call_count_, 1);
-  EXPECT_THAT(reported_area_, IsEmpty());
-}
-
 TEST_F(ElementAreaTest, TwoRectangles) {
   Selector expected_selector_top_left({"#top_left"});
   Selector expected_selector_bottom_right({"#bottom_right"});
@@ -372,9 +355,6 @@
                                  mock_web_controller_, expected_selector_2)),
                              _))
       .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(5, 7, 6, 8)));
-  EXPECT_CALL(mock_web_controller_, GetVisualViewport(_))
-      .WillRepeatedly(
-          RunOnceCallback<0>(OkClientStatus(), RectF(100, 0, 200, 400)));
 
   ElementAreaProto area_proto;
   auto* rectangle_proto = area_proto.add_touchable();
@@ -386,9 +366,8 @@
   std::vector<RectF> rectangles;
   element_area_.GetTouchableRectangles(&rectangles);
 
-  // left and right of the box come from the visual viewport, top from the 1st
-  // element, bottom from the 2nd.
-  EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(100, 3, 200, 8)));
+  // left and top come from the 1st element, right and bottom from the 2nd.
+  EXPECT_THAT(rectangles, ElementsAre(MatchingRectF(1, 3, 6, 8, true)));
 }
 
 TEST_F(ElementAreaTest, ElementMovesAfterUpdate) {
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
index 6beef07..228a610 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -37,10 +37,6 @@
   return web_controller_;
 }
 
-ElementStore* FakeScriptExecutorDelegate::GetElementStore() const {
-  return element_store_;
-}
-
 TriggerContext* FakeScriptExecutorDelegate::GetTriggerContext() {
   return trigger_context_.get();
 }
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.h b/components/autofill_assistant/browser/fake_script_executor_delegate.h
index ad93fc3..e62e449 100644
--- a/components/autofill_assistant/browser/fake_script_executor_delegate.h
+++ b/components/autofill_assistant/browser/fake_script_executor_delegate.h
@@ -30,7 +30,6 @@
   const GURL& GetScriptURL() override;
   Service* GetService() override;
   WebController* GetWebController() override;
-  ElementStore* GetElementStore() const override;
   TriggerContext* GetTriggerContext() override;
   autofill::PersonalDataManager* GetPersonalDataManager() override;
   WebsiteLoginManager* GetWebsiteLoginManager() override;
@@ -119,10 +118,6 @@
     web_controller_ = web_controller;
   }
 
-  void SetElementStore(ElementStore* element_store) {
-    element_store_ = element_store;
-  }
-
   void SetTriggerContext(std::unique_ptr<TriggerContext> trigger_context) {
     trigger_context_ = std::move(trigger_context);
   }
@@ -169,7 +164,6 @@
   GURL current_url_;
   Service* service_ = nullptr;
   WebController* web_controller_ = nullptr;
-  ElementStore* element_store_ = nullptr;
   std::unique_ptr<TriggerContext> trigger_context_;
   std::vector<AutofillAssistantState> state_history_;
   std::string status_message_;
diff --git a/components/autofill_assistant/browser/full_card_requester_unittest.cc b/components/autofill_assistant/browser/full_card_requester_unittest.cc
index 5c0b5a3a..10b0187e 100644
--- a/components/autofill_assistant/browser/full_card_requester_unittest.cc
+++ b/components/autofill_assistant/browser/full_card_requester_unittest.cc
@@ -15,12 +15,13 @@
 #include "components/autofill/core/browser/payments/card_unmask_delegate.h"
 #include "components/autofill/core/browser/payments/test_payments_client.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
-#include "components/autofill/core/browser/test_autofill_driver.h"
 #include "components/autofill_assistant/browser/mock_personal_data_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_renderer_host.h"
 #include "content/public/test/web_contents_tester.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace autofill_assistant {
@@ -46,16 +47,18 @@
   void SetUp() override {
     web_contents_ = content::WebContentsTester::CreateTestWebContents(
         &browser_context_, nullptr);
-    autofill_driver_ =
-        std::make_unique<testing::NiceMock<autofill::TestAutofillDriver>>();
     autofill_client_.SetPrefs(autofill::test::PrefServiceForTesting());
     autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
         web_contents_.get(), &autofill_client_, "en-US",
         autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
     autofill_client_.set_test_payments_client(
         std::make_unique<autofill::payments::TestPaymentsClient>(
-            autofill_driver_->GetURLLoaderFactory(),
+            test_url_loader_factory_.GetSafeWeakWrapper(),
             autofill_client_.GetIdentityManager(), &personal_data_manager_));
+    // Navigate to a site so that the ContentAutofillDriverFactory creates a
+    // ContentAutofillDriver for the frame.
+    content::WebContentsTester::For(web_contents_.get())
+        ->NavigateAndCommit(GURL("about:blank"), ui::PAGE_TRANSITION_TYPED);
   }
 
  protected:
@@ -63,7 +66,7 @@
   content::RenderViewHostTestEnabler rvh_test_enabler_;
   content::TestBrowserContext browser_context_;
   std::unique_ptr<content::WebContents> web_contents_;
-  std::unique_ptr<autofill::TestAutofillDriver> autofill_driver_;
+  ::network::TestURLLoaderFactory test_url_loader_factory_;
   MockAutofillClient autofill_client_;
   scoped_refptr<autofill::AutofillWebDataService> database_;
   MockPersonalDataManager personal_data_manager_;
diff --git a/components/autofill_assistant/browser/mock_website_login_manager.h b/components/autofill_assistant/browser/mock_website_login_manager.h
index 3f84416..734ee8e6 100644
--- a/components/autofill_assistant/browser/mock_website_login_manager.h
+++ b/components/autofill_assistant/browser/mock_website_login_manager.h
@@ -38,6 +38,26 @@
                void(const Login& login,
                     base::OnceCallback<void(bool, std::string)>&));
 
+  void DeletePasswordForLogin(
+      const Login& login,
+      base::OnceCallback<void(bool)> callback) override {
+    OnDeletePasswordForLogin(login, callback);
+  }
+
+  MOCK_METHOD2(OnDeletePasswordForLogin,
+               void(const Login& login, base::OnceCallback<void(bool)>&));
+
+  void EditPasswordForLogin(const Login& login,
+                            const std::string& new_password,
+                            base::OnceCallback<void(bool)> callback) override {
+    OnEditPasswordForLogin(login, new_password, callback);
+  }
+
+  MOCK_METHOD3(OnEditPasswordForLogin,
+               void(const Login& login,
+                    const std::string&,
+                    base::OnceCallback<void(bool)>&));
+
   std::string GeneratePassword(autofill::FormSignature form_signature,
                                autofill::FieldSignature field_signature,
                                uint64_t max_length) override {
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc
index e55089d6..1ab909f 100644
--- a/components/autofill_assistant/browser/protocol_utils.cc
+++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -32,6 +32,7 @@
 #include "components/autofill_assistant/browser/actions/set_attribute_action.h"
 #include "components/autofill_assistant/browser/actions/set_form_field_value_action.h"
 #include "components/autofill_assistant/browser/actions/set_persistent_ui_action.h"
+#include "components/autofill_assistant/browser/actions/set_touchable_area_action.h"
 #include "components/autofill_assistant/browser/actions/show_cast_action.h"
 #include "components/autofill_assistant/browser/actions/show_details_action.h"
 #include "components/autofill_assistant/browser/actions/show_form_action.h"
@@ -236,7 +237,14 @@
       return PerformOnSingleElementAction::WithClientId(
           delegate, action, action.scroll_into_view().client_id(),
           base::BindOnce(&WebController::ScrollIntoView,
-                         delegate->GetWebController()->GetWeakPtr(), true));
+                         delegate->GetWebController()->GetWeakPtr(),
+                         action.scroll_into_view().animation(),
+                         action.scroll_into_view().has_vertical_alignment()
+                             ? action.scroll_into_view().vertical_alignment()
+                             : "center",
+                         action.scroll_into_view().has_horizontal_alignment()
+                             ? action.scroll_into_view().horizontal_alignment()
+                             : "center"));
     case ActionProto::ActionInfoCase::kWaitForDocumentToBecomeInteractive:
       return PerformOnSingleElementAction::WithOptionalClientIdTimed(
           delegate, action,
@@ -354,6 +362,30 @@
       return std::make_unique<SetPersistentUiAction>(delegate, action);
     case ActionProto::ActionInfoCase::kClearPersistentUi:
       return std::make_unique<ClearPersistentUiAction>(delegate, action);
+    case ActionProto::ActionInfoCase::kScrollIntoViewIfNeeded:
+      return PerformOnSingleElementAction::WithClientId(
+          delegate, action, action.scroll_into_view_if_needed().client_id(),
+          base::BindOnce(&WebController::ScrollIntoViewIfNeeded,
+                         delegate->GetWebController()->GetWeakPtr(),
+                         action.scroll_into_view_if_needed().has_center()
+                             ? action.scroll_into_view_if_needed().center()
+                             : true));
+    case ActionProto::ActionInfoCase::kScrollWindow:
+      return PerformOnSingleElementAction::WithOptionalClientId(
+          delegate, action, action.scroll_window().optional_frame_id(),
+          base::BindOnce(&WebController::ScrollWindow,
+                         delegate->GetWebController()->GetWeakPtr(),
+                         action.scroll_window().scroll_distance(),
+                         action.scroll_window().animation()));
+    case ActionProto::ActionInfoCase::kScrollContainer:
+      return PerformOnSingleElementAction::WithClientId(
+          delegate, action, action.scroll_container().client_id(),
+          base::BindOnce(&WebController::ScrollContainer,
+                         delegate->GetWebController()->GetWeakPtr(),
+                         action.scroll_container().scroll_distance(),
+                         action.scroll_container().animation()));
+    case ActionProto::ActionInfoCase::kSetTouchableArea:
+      return std::make_unique<SetTouchableAreaAction>(delegate, action);
     case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: {
       VLOG(1) << "Encountered action with ACTION_INFO_NOT_SET";
       return std::make_unique<UnsupportedAction>(delegate, action);
diff --git a/components/autofill_assistant/browser/rectf.cc b/components/autofill_assistant/browser/rectf.cc
index 6af63f3ee..840ca2d3 100644
--- a/components/autofill_assistant/browser/rectf.cc
+++ b/components/autofill_assistant/browser/rectf.cc
@@ -6,22 +6,28 @@
 
 namespace autofill_assistant {
 
-RectF::RectF() : left(0.0f), top(0.0f), right(0.0f), bottom(0.0f) {}
+RectF::RectF()
+    : left(0.0f), top(0.0f), right(0.0f), bottom(0.0f), full_width(false) {}
 RectF::RectF(float l, float t, float r, float b)
-    : left(l), top(t), right(r), bottom(b) {}
+    : left(l), top(t), right(r), bottom(b), full_width(false) {}
+RectF::RectF(float l, float t, float r, float b, bool fw)
+    : left(l), top(t), right(r), bottom(b), full_width(fw) {}
 
 bool RectF::empty() const {
-  return right <= left || bottom <= top;
+  return (!full_width && right <= left) || bottom <= top;
 }
 
 bool RectF::operator==(const RectF& another) const {
   return left == another.left && top == another.top && right == another.right &&
-         bottom == another.bottom;
+         bottom == another.bottom && full_width == another.full_width;
 }
 
 std::ostream& operator<<(std::ostream& out, const RectF& rect) {
   out << "[l: " << rect.left << ", t: " << rect.top << ", r: " << rect.right
       << ", b: " << rect.bottom << "]";
+  if (rect.full_width) {
+    out << " full width";
+  }
   return out;
 }
 
diff --git a/components/autofill_assistant/browser/rectf.h b/components/autofill_assistant/browser/rectf.h
index d79e8f3..14e0fda 100644
--- a/components/autofill_assistant/browser/rectf.h
+++ b/components/autofill_assistant/browser/rectf.h
@@ -16,9 +16,11 @@
   float top;
   float right;
   float bottom;
+  bool full_width;
 
   RectF();
   RectF(float left, float top, float right, float bottom);
+  RectF(float left, float top, float right, float bottom, bool full_width);
 
   // Checks whether the rectangle is empty.
   bool empty() const;
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index 84c9566..c5672408 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -81,7 +81,9 @@
       listener_(listener),
       delegate_(delegate),
       ordered_interrupts_(ordered_interrupts),
-      scripts_state_(scripts_state) {
+      scripts_state_(scripts_state),
+      element_store_(
+          std::make_unique<ElementStore>(delegate->GetWebContents())) {
   DCHECK(delegate_);
   DCHECK(ordered_interrupts_);
 }
@@ -649,7 +651,7 @@
 }
 
 ElementStore* ScriptExecutor::GetElementStore() const {
-  return delegate_->GetElementStore();
+  return element_store_.get();
 }
 
 WebController* ScriptExecutor::GetWebController() const {
@@ -825,11 +827,6 @@
   return true;
 }
 
-void ScriptExecutor::DispatchJsEvent(
-    base::OnceCallback<void(const ClientStatus&)> callback) const {
-  delegate_->GetWebController()->DispatchJsEvent(std::move(callback));
-}
-
 base::WeakPtr<ActionDelegate> ScriptExecutor::GetWeakPtr() const {
   return weak_ptr_factory_.GetWeakPtr();
 }
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index 394e5f9..b1106edb 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -28,6 +28,7 @@
 #include "components/autofill_assistant/browser/top_padding.h"
 #include "components/autofill_assistant/browser/wait_for_dom_observer.h"
 #include "components/autofill_assistant/browser/web/element_finder.h"
+#include "components/autofill_assistant/browser/web/element_store.h"
 
 namespace autofill_assistant {
 class ElementStore;
@@ -276,8 +277,6 @@
   void MaybeShowSlowWebsiteWarning(
       base::OnceCallback<void(bool)> callback) override;
   void MaybeShowSlowConnectionWarning() override;
-  void DispatchJsEvent(
-      base::OnceCallback<void(const ClientStatus&)> callback) const override;
   base::WeakPtr<ActionDelegate> GetWeakPtr() const override;
 
  private:
@@ -483,6 +482,7 @@
   // being called.
   const std::vector<std::unique_ptr<Script>>* const ordered_interrupts_;
   std::map<std::string, ScriptStatus>* const scripts_state_;
+  std::unique_ptr<ElementStore> element_store_;
   RunScriptCallback callback_;
   std::vector<std::unique_ptr<Action>> actions_;
   std::vector<ProcessedActionProto> processed_actions_;
diff --git a/components/autofill_assistant/browser/script_executor_delegate.h b/components/autofill_assistant/browser/script_executor_delegate.h
index 1e0db3f..1cdda558 100644
--- a/components/autofill_assistant/browser/script_executor_delegate.h
+++ b/components/autofill_assistant/browser/script_executor_delegate.h
@@ -37,7 +37,6 @@
 class WebsiteLoginManager;
 class EventHandler;
 class UserModel;
-class ElementStore;
 
 class ScriptExecutorDelegate {
  public:
@@ -61,7 +60,6 @@
   virtual const GURL& GetScriptURL() = 0;
   virtual Service* GetService() = 0;
   virtual WebController* GetWebController() = 0;
-  virtual ElementStore* GetElementStore() const = 0;
   virtual const TriggerContext* GetTriggerContext() = 0;
   virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
   virtual WebsiteLoginManager* GetWebsiteLoginManager() = 0;
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto
index 7271d6e..7abcb83 100644
--- a/components/autofill_assistant/browser/service.proto
+++ b/components/autofill_assistant/browser/service.proto
@@ -760,6 +760,10 @@
     CheckOptionElementProto check_option_element = 76;
     SetPersistentUiProto set_persistent_ui = 77;
     ClearPersistentUiProto clear_persistent_ui = 78;
+    ScrollIntoViewIfNeededProto scroll_into_view_if_needed = 79;
+    ScrollWindowProto scroll_window = 80;
+    ScrollContainerProto scroll_container = 81;
+    SetTouchableAreaProto set_touchable_area = 82;
   }
 
   // Set to true to make the client remove any contextual information if the
@@ -1123,6 +1127,15 @@
 
     // Check the selected option of an element.
     CHECK_OPTION_ELEMENT = 24;
+
+    // Scroll an element into view only if needed.
+    SCROLL_INTO_VIEW_IF_NEEDED = 25;
+
+    // Scroll the window of a frame by a certain amount.
+    SCROLL_WINDOW = 26;
+
+    // Scroll the container by a certain amount.
+    SCROLL_CONTAINER = 27;
   }
 
   // The web-action that failed. This is usually a step in an execution chain
@@ -1434,12 +1447,6 @@
   // Optional title to show in the status bar.
   optional string title = 2;
 
-  // Restrict interaction to the area spanned by the given elements.
-  //
-  // Deprecated: use touchable_element_area instead. Ignored if
-  // touchable_element_area is non-empty.
-  repeated SelectorProto deprecated_touchable_elements = 5;
-
   // Restrict interaction to a series of rectangular areas.
   optional ElementAreaProto touchable_element_area = 6;
 
@@ -1464,7 +1471,12 @@
   // not set, the window will be scrolled.
   optional SelectorProto container = 12;
 
-  reserved 3, 4, 8;
+  reserved 3, 4, 5, 8;
+}
+
+// Set the touchable and restricted area of the overlay.
+message SetTouchableAreaProto {
+  optional ElementAreaProto element_area = 1;
 }
 
 // An area made up of rectangles whole border are made defined by the position
diff --git a/components/autofill_assistant/browser/web/mock_web_controller.h b/components/autofill_assistant/browser/web/mock_web_controller.h
index 3d62436..fbe5ab2 100644
--- a/components/autofill_assistant/browser/web/mock_web_controller.h
+++ b/components/autofill_assistant/browser/web/mock_web_controller.h
@@ -17,7 +17,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace autofill_assistant {
-struct RectF;
 
 class MockWebController : public WebController {
  public:
@@ -35,7 +34,13 @@
                void(const Selector& selector,
                     ElementFinder::Callback& callback));
 
-  MOCK_METHOD3(ScrollIntoView,
+  MOCK_METHOD5(ScrollIntoView,
+               void(const std::string&,
+                    const std::string&,
+                    const std::string&,
+                    const ElementFinder::Result&,
+                    base::OnceCallback<void(const ClientStatus&)>));
+  MOCK_METHOD3(ScrollIntoViewIfNeeded,
                void(bool,
                     const ElementFinder::Result&,
                     base::OnceCallback<void(const ClientStatus&)>));
@@ -120,9 +125,6 @@
                     const std::string&,
                     const ElementFinder::Result&,
                     base::OnceCallback<void(const ClientStatus&)>));
-  MOCK_METHOD1(GetVisualViewport,
-               void(base::OnceCallback<void(const ClientStatus&, const RectF&)>
-                        callback));
   MOCK_METHOD2(GetElementRect,
                void(const ElementFinder::Result& element,
                     ElementRectGetter::ElementRectCallback callback));
@@ -132,6 +134,8 @@
                     base::OnceCallback<void(const ClientStatus&,
                                             DocumentReadyState,
                                             base::TimeDelta)> callback));
+  MOCK_METHOD1(DispatchJsEvent,
+               void(base::OnceCallback<void(const ClientStatus&)> callback));
 
   base::WeakPtr<WebController> GetWeakPtr() const override {
     return weak_ptr_factory_.GetWeakPtr();
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc
index 66c954aa..f4c68cb 100644
--- a/components/autofill_assistant/browser/web/web_controller.cc
+++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -42,15 +42,6 @@
 
 namespace {
 
-// Get the visual viewport as a list of values to fill into RectF, that is:
-// left, top, right, bottom.
-const char* const kGetVisualViewport =
-    R"({ const v = window.visualViewport;
-         [v.pageLeft,
-          v.pageTop,
-          v.pageLeft + v.width,
-          v.pageTop + v.height] })";
-
 // Scrolls to the specified node with top padding. The top padding can
 // be specified through pixels or ratio. Pixels take precedence.
 const char* const kScrollIntoViewWithPaddingScript =
@@ -74,16 +65,62 @@
   })";
 
 // Scroll the window or any scrollable container as needed for the element to
-// appear, center if specified.
+// appear. Behave as specified according to |animation|, |verticalAlignment|
+// and |horizontalAlignment|.
 const char* const kScrollIntoViewScript =
-    R"(function(center) {
-      if (center) {
-        this.scrollIntoView({block: "center", inline: "center"});
-      } else {
-        this.scrollIntoViewIfNeeded();
+    R"(function(animation, verticalAlignment, horizontalAlignment) {
+      const options = {};
+      if (animation !== '') {
+        options.behavior = animation;
       }
+      if (verticalAlignment !== '') {
+        options.block = verticalAlignment;
+      }
+      if (horizontalAlignment !== '') {
+        options.inline = horizontalAlignment;
+      }
+      this.scrollIntoView(options);
   })";
 
+// Scroll the window or any scrollable container as needed for the element to
+// appear. Center the element if specified.
+const char* const kScrollIntoViewIfNeededScript =
+    R"(function(center) {
+      this.scrollIntoViewIfNeeded(center);
+    })";
+
+// Scroll the current window by a given amount of |pixels|. If |pixels| is 0,
+// take a ratio of the window's height instead.
+const char* const kScrollWindowScript =
+    R"(function(pixels, windowRatio, animation) {
+      let scrollDistance = pixels;
+      if (scrollDistance === 0) {
+        scrollDistance = window.innerHeight * windowRatio;
+      }
+      const options = {};
+      options.top = scrollDistance;
+      if (animation !== '') {
+        options.behavior = animation;
+      }
+      window.scrollBy(options);
+    })";
+
+// Scroll the container by a given amount of |pixels|. If |pixels| is 0,
+// take a ratio of the window's height instead.
+const char* const kScrollContainerScript =
+    R"(function(pixels, windowRatio, animation) {
+      let scrollDistance = pixels;
+      if (scrollDistance === 0) {
+        scrollDistance = window.innerHeight * windowRatio;
+      }
+      const options = {};
+      options.top = scrollDistance;
+      if (animation !== '') {
+        options.behavior = animation;
+      }
+      this.scrollBy(options);
+    })";
+
 // Javascript to select a value from a select box. Also fires a "change" event
 // to trigger any listeners. Changing the index directly does not trigger this.
 // See |WebController::OnSelectOptionJavascriptResult| for result handling.
@@ -453,6 +490,31 @@
 }
 
 void WebController::ScrollIntoView(
+    const std::string& animation,
+    const std::string& vertical_alignment,
+    const std::string& horizontal_alignment,
+    const ElementFinder::Result& element,
+    base::OnceCallback<void(const ClientStatus&)> callback) {
+  std::vector<std::unique_ptr<runtime::CallArgument>> arguments;
+  AddRuntimeCallArgument(animation, &arguments);
+  AddRuntimeCallArgument(vertical_alignment, &arguments);
+  AddRuntimeCallArgument(horizontal_alignment, &arguments);
+  devtools_client_->GetRuntime()->CallFunctionOn(
+      runtime::CallFunctionOnParams::Builder()
+          .SetObjectId(element.object_id())
+          .SetArguments(std::move(arguments))
+          .SetFunctionDeclaration(std::string(kScrollIntoViewScript))
+          .SetReturnByValue(true)
+          .Build(),
+      element.node_frame_id(),
+      base::BindOnce(
+          &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(),
+          base::BindOnce(&DecorateWebControllerStatus,
+                         WebControllerErrorInfoProto::SCROLL_INTO_VIEW,
+                         std::move(callback))));
+}
+
+void WebController::ScrollIntoViewIfNeeded(
     bool center,
     const ElementFinder::Result& element,
     base::OnceCallback<void(const ClientStatus&)> callback) {
@@ -462,14 +524,71 @@
       runtime::CallFunctionOnParams::Builder()
           .SetObjectId(element.object_id())
           .SetArguments(std::move(argument))
-          .SetFunctionDeclaration(std::string(kScrollIntoViewScript))
+          .SetFunctionDeclaration(std::string(kScrollIntoViewIfNeededScript))
+          .SetReturnByValue(true)
+          .Build(),
+      element.node_frame_id(),
+      base::BindOnce(
+          &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(),
+          base::BindOnce(
+              &DecorateWebControllerStatus,
+              WebControllerErrorInfoProto::SCROLL_INTO_VIEW_IF_NEEDED,
+              std::move(callback))));
+}
+
+void WebController::ScrollWindow(
+    const ScrollDistance& scroll_distance,
+    const std::string& animation,
+    const ElementFinder::Result& optional_frame,
+    base::OnceCallback<void(const ClientStatus&)> callback) {
+  std::string scroll_script = base::StrCat(
+      {"(", kScrollWindowScript, ")",
+       base::StringPrintf("(%d, %f, %s)", scroll_distance.pixels(),
+                          scroll_distance.window_ratio(), animation.c_str())});
+  // Note: An optional frame element will have an empty node_frame_id which
+  // will be considered as operating in the main frame.
+  devtools_client_->GetRuntime()->Evaluate(
+      runtime::EvaluateParams::Builder()
+          .SetExpression(scroll_script)
+          .SetReturnByValue(true)
+          .Build(),
+      optional_frame.node_frame_id(),
+      base::BindOnce(&WebController::OnScrollWindow,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     base::BindOnce(&DecorateWebControllerStatus,
+                                    WebControllerErrorInfoProto::SCROLL_WINDOW,
+                                    std::move(callback))));
+}
+
+void WebController::OnScrollWindow(
+    base::OnceCallback<void(const ClientStatus&)> callback,
+    const DevtoolsClient::ReplyStatus& reply_status,
+    std::unique_ptr<runtime::EvaluateResult> result) {
+  std::move(callback).Run(
+      CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__));
+}
+
+void WebController::ScrollContainer(
+    const ScrollDistance& scroll_distance,
+    const std::string& animation,
+    const ElementFinder::Result& element,
+    base::OnceCallback<void(const ClientStatus&)> callback) {
+  std::vector<std::unique_ptr<runtime::CallArgument>> arguments;
+  AddRuntimeCallArgument(scroll_distance.pixels(), &arguments);
+  AddRuntimeCallArgument(scroll_distance.window_ratio(), &arguments);
+  AddRuntimeCallArgument(animation, &arguments);
+  devtools_client_->GetRuntime()->CallFunctionOn(
+      runtime::CallFunctionOnParams::Builder()
+          .SetObjectId(element.object_id())
+          .SetArguments(std::move(arguments))
+          .SetFunctionDeclaration(std::string(kScrollContainerScript))
           .SetReturnByValue(true)
           .Build(),
       element.node_frame_id(),
       base::BindOnce(
           &WebController::OnJavaScriptResult, weak_ptr_factory_.GetWeakPtr(),
           base::BindOnce(&DecorateWebControllerStatus,
-                         WebControllerErrorInfoProto::SCROLL_INTO_VIEW,
+                         WebControllerErrorInfoProto::SCROLL_CONTAINER,
                          std::move(callback))));
 }
 
@@ -1299,51 +1418,6 @@
                                     std::move(wrapped_callback))));
 }
 
-void WebController::GetVisualViewport(
-    base::OnceCallback<void(const ClientStatus&, const RectF&)> callback) {
-  devtools_client_->GetRuntime()->Evaluate(
-      runtime::EvaluateParams::Builder()
-          .SetExpression(std::string(kGetVisualViewport))
-          .SetReturnByValue(true)
-          .Build(),
-      /* node_frame_id= */ std::string(),
-      base::BindOnce(&WebController::OnGetVisualViewport,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
-void WebController::OnGetVisualViewport(
-    base::OnceCallback<void(const ClientStatus&, const RectF&)> callback,
-    const DevtoolsClient::ReplyStatus& reply_status,
-    std::unique_ptr<runtime::EvaluateResult> result) {
-  ClientStatus status =
-      CheckJavaScriptResult(reply_status, result.get(), __FILE__, __LINE__);
-  if (!status.ok() || !result->GetResult()->HasValue() ||
-      !result->GetResult()->GetValue()->is_list() ||
-      result->GetResult()->GetValue()->GetList().size() != 4u) {
-    VLOG(1) << __func__ << " Failed to get visual viewport: " << status;
-    std::move(callback).Run(
-        JavaScriptErrorStatus(reply_status, __FILE__, __LINE__, nullptr),
-        RectF());
-    return;
-  }
-  const auto& list = result->GetResult()->GetValue()->GetList();
-  // Value::GetDouble() is safe to call without checking the value type; it'll
-  // return 0.0 if the value has the wrong type.
-
-  float left = static_cast<float>(list[0].GetDouble());
-  float top = static_cast<float>(list[1].GetDouble());
-  float width = static_cast<float>(list[2].GetDouble());
-  float height = static_cast<float>(list[3].GetDouble());
-
-  RectF rect;
-  rect.left = left;
-  rect.top = top;
-  rect.right = left + width;
-  rect.bottom = top + height;
-
-  std::move(callback).Run(OkClientStatus(), rect);
-}
-
 void WebController::GetElementRect(
     const ElementFinder::Result& element,
     ElementRectGetter::ElementRectCallback callback) {
@@ -1445,7 +1519,7 @@
 }
 
 void WebController::DispatchJsEvent(
-    base::OnceCallback<void(const ClientStatus&)> callback) const {
+    base::OnceCallback<void(const ClientStatus&)> callback) {
   devtools_client_->GetRuntime()->Evaluate(
       runtime::EvaluateParams::Builder()
           .SetExpression(kDispatchEventToDocumentScript)
diff --git a/components/autofill_assistant/browser/web/web_controller.h b/components/autofill_assistant/browser/web/web_controller.h
index a819038..d6bd2af 100644
--- a/components/autofill_assistant/browser/web/web_controller.h
+++ b/components/autofill_assistant/browser/web/web_controller.h
@@ -94,13 +94,41 @@
   virtual void FindAllElements(const Selector& selector,
                                ElementFinder::Callback callback);
 
-  // Scroll the |element| into view if needed, center the element on the screen
-  // if specified.
+  // Scroll the |element| into view. |animation| defines the transition
+  // animation, |vertical_alignment| defines the vertical alignment,
+  // |horizontal_alignment| defines the horizontal alignment.
   virtual void ScrollIntoView(
+      const std::string& animation,
+      const std::string& vertical_alignment,
+      const std::string& horizontal_alignment,
+      const ElementFinder::Result& element,
+      base::OnceCallback<void(const ClientStatus&)> callback);
+
+  // Scroll the |element| into view only if needed. |center| the element if
+  // requested.
+  virtual void ScrollIntoViewIfNeeded(
       bool center,
       const ElementFinder::Result& element,
       base::OnceCallback<void(const ClientStatus&)> callback);
 
+  // Scroll the window by |scroll_distance|. |animation| defines the transition
+  // animation. Specify |optional_frame| if an iFrame instead of the main
+  // window should be scrolled.
+  virtual void ScrollWindow(
+      const ScrollDistance& scroll_distance,
+      const std::string& animation,
+      const ElementFinder::Result& optional_frame,
+      base::OnceCallback<void(const ClientStatus&)> callback);
+
+  // Scroll the |element| by |scroll_distance|. |animation| defines the
+  // transition animation. Specify |optional_frame| if an iFrame instead of the
+  // main window should be scrolled.
+  virtual void ScrollContainer(
+      const ScrollDistance& scroll_distance,
+      const std::string& animation,
+      const ElementFinder::Result& element,
+      base::OnceCallback<void(const ClientStatus&)> callback);
+
   // Send a JS click to the |element|.
   virtual void JsClickElement(
       const ElementFinder::Result& element,
@@ -276,12 +304,6 @@
       base::OnceCallback<void(const ClientStatus&, const std::string&)>
           callback);
 
-  // Gets the visual viewport coordinates and size.
-  //
-  // The rectangle is expressed in absolute CSS coordinates.
-  virtual void GetVisualViewport(
-      base::OnceCallback<void(const ClientStatus&, const RectF&)> callback);
-
   // Gets the position of the |element|.
   //
   // If unsuccessful, the callback gets the failure status with an empty rect.
@@ -317,9 +339,9 @@
       const ElementFinder::Result& element,
       base::OnceCallback<void(const ClientStatus&)> callback);
 
-  // Dispatch a custom JS event 'duplexweb' with an optional payload.
+  // Dispatch a custom JS event 'duplexweb'.
   virtual void DispatchJsEvent(
-      base::OnceCallback<void(const ClientStatus&)> callback) const;
+      base::OnceCallback<void(const ClientStatus&)> callback);
 
   virtual base::WeakPtr<WebController> GetWeakPtr() const;
 
@@ -369,6 +391,9 @@
                               const std::vector<std::string>&)> callback,
       const DevtoolsClient::ReplyStatus& reply_status,
       std::unique_ptr<runtime::CallFunctionOnResult> result);
+  void OnScrollWindow(base::OnceCallback<void(const ClientStatus&)> callback,
+                      const DevtoolsClient::ReplyStatus& reply_status,
+                      std::unique_ptr<runtime::EvaluateResult> result);
   void OnCheckOnTop(CheckOnTopWorker* worker,
                     base::OnceCallback<void(const ClientStatus&)> callback,
                     const ClientStatus& status);
@@ -473,21 +498,14 @@
       ProcessedActionStatusProto status_if_zero,
       const DevtoolsClient::ReplyStatus& reply_status,
       std::unique_ptr<runtime::CallFunctionOnResult> result);
-
   void OnSendKeyboardInputDone(
       SendKeyboardInputWorker* worker_to_release,
       base::OnceCallback<void(const ClientStatus&)> callback,
       const ClientStatus& status);
-
   void OnGetElementRect(ElementRectGetter* getter_to_release,
                         ElementRectGetter::ElementRectCallback callback,
                         const ClientStatus& rect_status,
                         const RectF& element_rect);
-  void OnGetVisualViewport(
-      base::OnceCallback<void(const ClientStatus&, const RectF&)> callback,
-      const DevtoolsClient::ReplyStatus& reply_status,
-      std::unique_ptr<runtime::EvaluateResult> result);
-
   void OnWaitForDocumentReadyState(
       base::OnceCallback<void(const ClientStatus&,
                               DocumentReadyState,
@@ -495,7 +513,6 @@
       base::TimeTicks wait_start_time,
       const DevtoolsClient::ReplyStatus& reply_status,
       std::unique_ptr<runtime::EvaluateResult> result);
-
   void OnDispatchJsEvent(base::OnceCallback<void(const ClientStatus&)> callback,
                          const DevtoolsClient::ReplyStatus& reply_status,
                          std::unique_ptr<runtime::EvaluateResult> result) const;
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
index bfb0c921..bdcaf7c9 100644
--- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc
+++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -252,9 +252,10 @@
       actions->emplace_back(base::BindOnce(&WebController::JsClickElement,
                                            web_controller_->GetWeakPtr()));
     } else {
-      actions->emplace_back(base::BindOnce(&WebController::ScrollIntoView,
-                                           web_controller_->GetWeakPtr(),
-                                           /* center= */ true));
+      actions->emplace_back(base::BindOnce(
+          &WebController::ScrollIntoView, web_controller_->GetWeakPtr(),
+          /* animation= */ std::string(), /* vertical_alignment= */ "center",
+          /* horizontal_alignment= */ "center"));
       actions->emplace_back(base::BindOnce(&WebController::ClickOrTapElement,
                                            web_controller_->GetWeakPtr(),
                                            click_type));
@@ -611,9 +612,11 @@
           actions->emplace_back(
               base::BindOnce(&WebController::SetValueAttribute,
                              web_controller_->GetWeakPtr(), std::string()));
-          actions->emplace_back(base::BindOnce(&WebController::ScrollIntoView,
-                                               web_controller_->GetWeakPtr(),
-                                               /* center= */ true));
+          actions->emplace_back(base::BindOnce(
+              &WebController::ScrollIntoView, web_controller_->GetWeakPtr(),
+              /* animation= */ std::string(),
+              /* vertical_alignment= */ "center",
+              /* horizontal_alignment= */ "center"));
           actions->emplace_back(
               base::BindOnce(&WebController::ClickOrTapElement,
                              web_controller_->GetWeakPtr(), ClickType::CLICK));
@@ -654,9 +657,10 @@
       actions->emplace_back(base::BindOnce(&WebController::FocusField,
                                            web_controller_->GetWeakPtr()));
     } else {
-      actions->emplace_back(base::BindOnce(&WebController::ScrollIntoView,
-                                           web_controller_->GetWeakPtr(),
-                                           /* center= */ true));
+      actions->emplace_back(base::BindOnce(
+          &WebController::ScrollIntoView, web_controller_->GetWeakPtr(),
+          /* animation= */ std::string(), /* vertical_alignment= */ "center",
+          /* horizontal_alignment= */ "center"));
       actions->emplace_back(base::BindOnce(&WebController::ClickOrTapElement,
                                            web_controller_->GetWeakPtr(),
                                            ClickType::CLICK));
@@ -2664,4 +2668,118 @@
   ASSERT_EQ(PRECONDITION_FAILED, failing_option_status.proto_status());
 }
 
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ScrollIntoViewIfNeeded) {
+  EXPECT_EQ(content::EvalJs(shell(), "window.scrollY").ExtractInt(), 0);
+
+  // Make sure the target element is on top, such that no scrolling is
+  // necessary.
+  ClientStatus no_scroll_element_status;
+  ElementFinder::Result no_scroll_element;
+  FindElement(Selector({"#trigger-keyboard"}), &no_scroll_element_status,
+              &no_scroll_element);
+  EXPECT_EQ(ACTION_APPLIED, no_scroll_element_status.proto_status());
+
+  ClientStatus no_scroll_status;
+  base::RunLoop no_scroll_run_loop;
+  web_controller_->ScrollIntoViewIfNeeded(
+      true, no_scroll_element,
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), no_scroll_run_loop.QuitClosure(),
+                     &no_scroll_status));
+  no_scroll_run_loop.Run();
+  EXPECT_EQ(ACTION_APPLIED, no_scroll_status.proto_status());
+  EXPECT_EQ(content::EvalJs(shell(), "window.scrollY").ExtractInt(), 0);
+
+  // Make sure the target element is after the full height view.
+  ClientStatus scroll_element_status;
+  ElementFinder::Result scroll_element;
+  FindElement(Selector({"#touch_area_five"}), &scroll_element_status,
+              &scroll_element);
+  EXPECT_EQ(ACTION_APPLIED, scroll_element_status.proto_status());
+
+  ClientStatus scroll_status;
+  base::RunLoop scroll_run_loop;
+  web_controller_->ScrollIntoViewIfNeeded(
+      true, scroll_element,
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), scroll_run_loop.QuitClosure(),
+                     &scroll_status));
+  scroll_run_loop.Run();
+  EXPECT_EQ(ACTION_APPLIED, scroll_status.proto_status());
+  EXPECT_GT(content::EvalJs(shell(), "window.scrollY").ExtractDouble(), 0);
+}
+
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ScrollWindow) {
+  EXPECT_EQ(content::EvalJs(shell(), "window.scrollY").ExtractInt(), 0);
+
+  ScrollDistance scroll_distance;
+  scroll_distance.set_pixels(20);
+
+  ClientStatus status;
+  base::RunLoop run_loop;
+  web_controller_->ScrollWindow(
+      scroll_distance, /* animation= */ std::string(),
+      /* optional_frame= */ ElementFinder::Result(),
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), run_loop.QuitClosure(), &status));
+  run_loop.Run();
+  EXPECT_EQ(ACTION_APPLIED, status.proto_status());
+  EXPECT_NEAR(content::EvalJs(shell(), "window.scrollY").ExtractDouble(), 20.0,
+              0.5);
+}
+
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ScrollWindowOfIFrame) {
+  EXPECT_EQ(content::EvalJs(shell(), "window.scrollY").ExtractInt(), 0);
+
+  ScrollDistance scroll_distance;
+  scroll_distance.set_pixels(20);
+
+  // This needs to target an OOPIF, otherwise it will have the same `window`
+  // and the test will fail.
+  ClientStatus frame_status;
+  ElementFinder::Result frame;
+  FindElement(Selector({"#iframeExternal", "body"}), &frame_status, &frame);
+  EXPECT_EQ(ACTION_APPLIED, frame_status.proto_status());
+
+  ClientStatus status;
+  base::RunLoop run_loop;
+  web_controller_->ScrollWindow(
+      scroll_distance, /* animation= */ std::string(), frame,
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), run_loop.QuitClosure(), &status));
+  run_loop.Run();
+  EXPECT_EQ(ACTION_APPLIED, status.proto_status());
+  EXPECT_EQ(content::EvalJs(shell(), "window.scrollY").ExtractInt(), 0);
+}
+
+IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, ScrollContainer) {
+  EXPECT_EQ(
+      content::EvalJs(shell(),
+                      "document.getElementById('scroll_container').scrollTop")
+          .ExtractInt(),
+      0);
+
+  ScrollDistance scroll_distance;
+  scroll_distance.set_pixels(20);
+
+  ClientStatus element_status;
+  ElementFinder::Result element;
+  FindElement(Selector({"#scroll_container"}), &element_status, &element);
+  EXPECT_EQ(ACTION_APPLIED, element_status.proto_status());
+
+  ClientStatus status;
+  base::RunLoop run_loop;
+  web_controller_->ScrollContainer(
+      scroll_distance, /* animation= */ std::string(), element,
+      base::BindOnce(&WebControllerBrowserTest::OnClientStatus,
+                     base::Unretained(this), run_loop.QuitClosure(), &status));
+  run_loop.Run();
+  EXPECT_EQ(ACTION_APPLIED, status.proto_status());
+  EXPECT_NEAR(
+      content::EvalJs(shell(),
+                      "document.getElementById('scroll_container').scrollTop")
+          .ExtractDouble(),
+      20.0, 0.5);
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/website_login_manager.h b/components/autofill_assistant/browser/website_login_manager.h
index a15ede6..e1b017c5 100644
--- a/components/autofill_assistant/browser/website_login_manager.h
+++ b/components/autofill_assistant/browser/website_login_manager.h
@@ -46,6 +46,17 @@
       const Login& login,
       base::OnceCallback<void(bool, std::string)> callback) = 0;
 
+  // Deletes the password for |login|.
+  virtual void DeletePasswordForLogin(
+      const Login& login,
+      base::OnceCallback<void(bool)> callback) = 0;
+
+  // Edits the password for |login|.
+  virtual void EditPasswordForLogin(
+      const Login& login,
+      const std::string& new_password,
+      base::OnceCallback<void(bool)> callback) = 0;
+
   // Generates new strong password. |form/field_signature| are used to fetch
   // password requirements. |max_length| is the "max_length" attribute of input
   // field that limits the length of value.
diff --git a/components/autofill_assistant/browser/website_login_manager_impl.cc b/components/autofill_assistant/browser/website_login_manager_impl.cc
index 7f9d113c..7fe15fdf 100644
--- a/components/autofill_assistant/browser/website_login_manager_impl.cc
+++ b/components/autofill_assistant/browser/website_login_manager_impl.cc
@@ -10,6 +10,8 @@
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/password_manager/core/browser/form_fetcher_impl.h"
 #include "components/password_manager/core/browser/form_parsing/form_parser.h"
+#include "components/password_manager/core/browser/form_saver.h"
+#include "components/password_manager/core/browser/form_saver_impl.h"
 #include "components/password_manager/core/browser/password_form_metrics_recorder.h"
 #include "components/password_manager/core/browser/password_generation_frame_helper.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
@@ -36,6 +38,20 @@
   return form;
 }
 
+// Returns the first match that has same username.
+const password_manager::PasswordForm* FindPasswordForLogin(
+    const std::vector<const password_manager::PasswordForm*>& matches,
+    const WebsiteLoginManager::Login& login) {
+  auto result =
+      std::find_if(matches.begin(), matches.end(), [&](const auto& match) {
+        return base::UTF16ToUTF8(match->username_value) == login.username;
+      });
+  if (result == matches.end()) {
+    return nullptr;
+  }
+  return *result;
+}
+
 }  // namespace
 
 // Represents a pending form fetcher request which will notify the
@@ -143,13 +159,11 @@
   void OnFetchCompleted() override {
     std::vector<const password_manager::PasswordForm*> matches =
         form_fetcher_->GetNonFederatedMatches();
-    for (const auto* match : matches) {
-      if (base::UTF16ToUTF8(match->username_value) == login_.username) {
-        std::move(callback_).Run(true,
-                                 base::UTF16ToUTF8(match->password_value));
-        PendingRequest::OnFetchCompleted();
-        return;
-      }
+    const auto* match = FindPasswordForLogin(matches, login_);
+    if (match != nullptr) {
+      std::move(callback_).Run(true, base::UTF16ToUTF8(match->password_value));
+      PendingRequest::OnFetchCompleted();
+      return;
     }
     std::move(callback_).Run(false, std::string());
     PendingRequest::OnFetchCompleted();
@@ -160,6 +174,89 @@
   base::OnceCallback<void(bool, std::string)> callback_;
 };
 
+// A pending request to delete the password for the specified |login|.
+class WebsiteLoginManagerImpl::PendingDeletePasswordRequest
+    : public WebsiteLoginManagerImpl::PendingRequest {
+ public:
+  PendingDeletePasswordRequest(
+      const password_manager::PasswordFormDigest& form_digest,
+      const password_manager::PasswordManagerClient* client,
+      const Login& login,
+      base::OnceCallback<void(bool)> callback,
+      base::OnceCallback<void(const PendingRequest*)> notify_finished_callback)
+      : PendingRequest(form_digest,
+                       client,
+                       std::move(notify_finished_callback)),
+        login_(login),
+        callback_(std::move(callback)),
+        store_(client->GetProfilePasswordStore()) {}
+
+ protected:
+  // From PendingRequest:
+  void OnFetchCompleted() override {
+    std::vector<const password_manager::PasswordForm*> matches =
+        form_fetcher_->GetNonFederatedMatches();
+    const auto* match = FindPasswordForLogin(matches, login_);
+    if (match != nullptr) {
+      store_->RemoveLogin(*match);
+    }
+
+    std::move(callback_).Run(match != nullptr);
+    PendingRequest::OnFetchCompleted();
+  }
+
+ private:
+  Login login_;
+  base::OnceCallback<void(bool)> callback_;
+  password_manager::PasswordStoreInterface* store_;
+};
+
+// A pending request to edit the password for the specified |login|.
+class WebsiteLoginManagerImpl::PendingEditPasswordRequest
+    : public WebsiteLoginManagerImpl::PendingRequest {
+ public:
+  PendingEditPasswordRequest(
+      const password_manager::PasswordFormDigest& form_digest,
+      const password_manager::PasswordManagerClient* client,
+      const Login& login,
+      const std::string& new_password,
+      base::OnceCallback<void(bool)> callback,
+      base::OnceCallback<void(const PendingRequest*)> notify_finished_callback)
+      : PendingRequest(form_digest,
+                       client,
+                       std::move(notify_finished_callback)),
+        login_(login),
+        new_password_(new_password),
+        callback_(std::move(callback)),
+        form_saver_(std::make_unique<password_manager::FormSaverImpl>(
+            client->GetProfilePasswordStore())) {}
+
+ protected:
+  // From PendingRequest:
+  void OnFetchCompleted() override {
+    std::vector<const password_manager::PasswordForm*> matches =
+        form_fetcher_->GetNonFederatedMatches();
+    const auto* old_password_form = FindPasswordForLogin(matches, login_);
+    if (old_password_form != nullptr) {
+      password_manager::PasswordForm new_password_form = *old_password_form;
+      new_password_form.password_value = base::UTF8ToUTF16(new_password_);
+      form_saver_->Update(new_password_form, matches,
+                          /*old_password=*/old_password_form->password_value);
+    }
+    std::move(callback_).Run(old_password_form != nullptr);
+    PendingRequest::OnFetchCompleted();
+  }
+
+ private:
+  Login login_;
+  std::string new_password_;
+  base::OnceCallback<void(bool)> callback_;
+  // Using form saver instead store itself gives us benefit of updating
+  // password for all matches (i.e. m.domain.com and www.domain.com' passwords
+  // will stay synced)
+  std::unique_ptr<password_manager::FormSaver> form_saver_;
+};
+
 // A request to update store with new password for a login.
 class WebsiteLoginManagerImpl::UpdatePasswordRequest
     : public password_manager::FormFetcher::Consumer {
@@ -265,6 +362,34 @@
   pending_requests_.back()->Start();
 }
 
+void WebsiteLoginManagerImpl::DeletePasswordForLogin(
+    const Login& login,
+    base::OnceCallback<void(bool)> callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  password_manager::PasswordFormDigest digest(
+      password_manager::PasswordForm::Scheme::kHtml, login.origin.spec(),
+      GURL());
+  pending_requests_.push_back(std::make_unique<PendingDeletePasswordRequest>(
+      digest, client_, login, std::move(callback),
+      base::BindOnce(&WebsiteLoginManagerImpl::OnRequestFinished,
+                     weak_ptr_factory_.GetWeakPtr())));
+  pending_requests_.back()->Start();
+}
+
+void WebsiteLoginManagerImpl::EditPasswordForLogin(
+    const Login& login,
+    const std::string& new_password,
+    base::OnceCallback<void(bool)> callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  password_manager::PasswordFormDigest digest(
+      password_manager::PasswordForm::Scheme::kHtml, login.origin.spec(),
+      GURL());
+  pending_requests_.push_back(std::make_unique<PendingEditPasswordRequest>(
+      digest, client_, login, new_password, std::move(callback),
+      base::BindOnce(&WebsiteLoginManagerImpl::OnRequestFinished,
+                     weak_ptr_factory_.GetWeakPtr())));
+  pending_requests_.back()->Start();
+}
 std::string WebsiteLoginManagerImpl::GeneratePassword(
     autofill::FormSignature form_signature,
     autofill::FieldSignature field_signature,
diff --git a/components/autofill_assistant/browser/website_login_manager_impl.h b/components/autofill_assistant/browser/website_login_manager_impl.h
index b8656e2..dc66e0e555 100644
--- a/components/autofill_assistant/browser/website_login_manager_impl.h
+++ b/components/autofill_assistant/browser/website_login_manager_impl.h
@@ -31,6 +31,11 @@
   void GetPasswordForLogin(
       const Login& login,
       base::OnceCallback<void(bool, std::string)> callback) override;
+  void DeletePasswordForLogin(const Login& login,
+                              base::OnceCallback<void(bool)> callback) override;
+  void EditPasswordForLogin(const Login& login,
+                            const std::string& new_password,
+                            base::OnceCallback<void(bool)> callback) override;
   std::string GeneratePassword(autofill::FormSignature form_signature,
                                autofill::FieldSignature field_signature,
                                uint64_t max_length) override;
@@ -49,6 +54,8 @@
   class PendingFetchLoginsRequest;
   class PendingFetchPasswordRequest;
   class UpdatePasswordRequest;
+  class PendingDeletePasswordRequest;
+  class PendingEditPasswordRequest;
 
   void OnRequestFinished(const PendingRequest* request);
 
diff --git a/components/autofill_assistant/browser/website_login_manager_impl_unittest.cc b/components/autofill_assistant/browser/website_login_manager_impl_unittest.cc
index 2f8fffb..6b9f076e 100644
--- a/components/autofill_assistant/browser/website_login_manager_impl_unittest.cc
+++ b/components/autofill_assistant/browser/website_login_manager_impl_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "components/password_manager/core/browser/mock_password_store.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -33,7 +34,9 @@
 
 namespace {
 const char kFakeUrl[] = "http://www.example.com/";
+const char kFakeUrl2[] = "https://www.example2.com";
 const char kFakeUsername[] = "user@example.com";
+const char kFakeUsername2[] = "user2@example.com";
 const char16_t kFakeUsername16[] = u"user@example.com";
 const char16_t kFakePassword[] = u"old_password";
 const char kFakeNewPassword[] = "new_password";
@@ -120,6 +123,14 @@
       ON_CALL(client_, GetAccountPasswordStore())
           .WillByDefault(Return(account_store_.get()));
     }
+    ON_CALL(*store(), GetLogins(_, _))
+        .WillByDefault(
+            WithArg<1>([](password_manager::PasswordStoreConsumer* consumer) {
+              std::vector<std::unique_ptr<PasswordForm>> result;
+              result.push_back(
+                  std::make_unique<PasswordForm>(MakeSimplePasswordForm()));
+              consumer->OnGetPasswordStoreResults(std::move(result));
+            }));
 
     manager_ = std::make_unique<WebsiteLoginManagerImpl>(&client_,
                                                          web_contents_.get());
@@ -158,15 +169,6 @@
 }
 
 TEST_F(WebsiteLoginManagerImplTest, SaveGeneratedPassword) {
-  ON_CALL(*store(), GetLogins(_, _))
-      .WillByDefault(WithArg<1>(
-          Invoke([](password_manager::PasswordStoreConsumer* consumer) {
-            std::vector<std::unique_ptr<PasswordForm>> result;
-            result.push_back(
-                std::make_unique<PasswordForm>(MakeSimplePasswordForm()));
-            consumer->OnGetPasswordStoreResults(std::move(result));
-          })));
-
   password_manager::PasswordFormDigest form_digest(
       password_manager::PasswordForm::Scheme::kHtml, kFakeUrl, GURL(kFakeUrl));
   // Presave generated password. Form with empty username is presaved.
@@ -187,4 +189,55 @@
   WaitForPasswordStore();
 }
 
+TEST_F(WebsiteLoginManagerImplTest, DeletePasswordSuccess) {
+  password_manager::PasswordFormDigest form_digest(
+      password_manager::PasswordForm::Scheme::kHtml, kFakeUrl, GURL());
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_callback;
+  // |DeletePasswordForLogin| will first fetch all existing logins
+  EXPECT_CALL(*store(), GetLogins(form_digest, _));
+  EXPECT_CALL(*store(), RemoveLogin(FormMatches(MakeSimplePasswordForm())));
+  EXPECT_CALL(mock_callback, Run(true)).Times(1);
+  manager()->DeletePasswordForLogin({GURL(kFakeUrl), kFakeUsername},
+                                    mock_callback.Get());
+  WaitForPasswordStore();
+}
+
+TEST_F(WebsiteLoginManagerImplTest, DeletePasswordFailed) {
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_callback;
+  // |DeletePasswordForLogin| will first fetch all existing logins
+  EXPECT_CALL(*store(), GetLogins);
+  EXPECT_CALL(*store(), RemoveLogin).Times(0);
+  EXPECT_CALL(mock_callback, Run(false)).Times(1);
+  manager()->DeletePasswordForLogin({GURL(kFakeUrl2), kFakeUsername2},
+                                    mock_callback.Get());
+  WaitForPasswordStore();
+}
+
+TEST_F(WebsiteLoginManagerImplTest, EditPasswordSuccess) {
+  password_manager::PasswordFormDigest form_digest(
+      password_manager::PasswordForm::Scheme::kHtml, kFakeUrl, GURL());
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_callback;
+  // |EditPasswordForLogin| will first fetch all existing logins
+  EXPECT_CALL(*store(), GetLogins(form_digest, _));
+  PasswordForm new_form = MakeSimplePasswordForm();
+  new_form.password_value = kFakeNewPassword16;
+  // Check that additional data is populated correctly from matched form.
+  EXPECT_CALL(*store(), UpdateLogin(FormMatches(new_form)));
+  EXPECT_CALL(mock_callback, Run(true)).Times(1);
+  manager()->EditPasswordForLogin({GURL(kFakeUrl), kFakeUsername},
+                                  kFakeNewPassword, mock_callback.Get());
+  WaitForPasswordStore();
+}
+
+TEST_F(WebsiteLoginManagerImplTest, EditPasswordFailed) {
+  base::MockCallback<base::OnceCallback<void(bool)>> mock_callback;
+  // |EditPasswordForLogin| will first fetch all existing logins
+  EXPECT_CALL(*store(), GetLogins);
+  EXPECT_CALL(*store(), UpdateLogin).Times(0);
+  EXPECT_CALL(mock_callback, Run(false)).Times(1);
+  manager()->EditPasswordForLogin({GURL(kFakeUrl2), kFakeUsername2},
+                                  kFakeNewPassword, mock_callback.Get());
+  WaitForPasswordStore();
+}
+
 }  // namespace autofill_assistant
diff --git a/components/browser_ui/styles/android/java/res/values-night/styles.xml b/components/browser_ui/styles/android/java/res/values-night/styles.xml
index c08ed325..cd3d8a6 100644
--- a/components/browser_ui/styles/android/java/res/values-night/styles.xml
+++ b/components/browser_ui/styles/android/java/res/values-night/styles.xml
@@ -17,6 +17,7 @@
         <item name="colorSurface">@color/modern_grey_900</item>
         <item name="colorOnBackground">@color/modern_white</item>
         <item name="colorOnPrimary">@color/modern_blue_800</item>
+        <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item>
         <item name="colorOnSurface">@color/modern_grey_100</item>
         <item name="colorOnSurfaceVariant">@color/white_alpha_70</item>
         <item name="colorOnSurfaceInverse">@color/modern_grey_800</item>
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml
index 7b6d19f..9000b14 100644
--- a/components/browser_ui/styles/android/java/res/values/styles.xml
+++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -202,6 +202,7 @@
         <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item>
         <item name="colorOnBackground">@color/modern_grey_900</item>
         <item name="colorOnPrimary">@color/modern_white</item>
+        <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item>
         <item name="colorOnSurface">@color/modern_grey_900</item>
         <item name="colorOnSurfaceVariant">@color/modern_grey_700</item>
         <item name="colorOnSurfaceInverse">@color/modern_white</item>
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn
index 8b081c7a..e36d4878 100644
--- a/components/browser_ui/widget/android/BUILD.gn
+++ b/components/browser_ui/widget/android/BUILD.gn
@@ -18,6 +18,7 @@
     "java/src/org/chromium/components/browser_ui/widget/FadingShadow.java",
     "java/src/org/chromium/components/browser_ui/widget/FadingShadowView.java",
     "java/src/org/chromium/components/browser_ui/widget/InsetObserverView.java",
+    "java/src/org/chromium/components/browser_ui/widget/MaterialCardViewNoShadow.java",
     "java/src/org/chromium/components/browser_ui/widget/MaterialProgressBar.java",
     "java/src/org/chromium/components/browser_ui/widget/MenuOrKeyboardActionController.java",
     "java/src/org/chromium/components/browser_ui/widget/MoreProgressButton.java",
diff --git a/components/browser_ui/widget/android/java/res/layout/promo_card_view_compact.xml b/components/browser_ui/widget/android/java/res/layout/promo_card_view_compact.xml
index 272645b..5c4b05d 100644
--- a/components/browser_ui/widget/android/java/res/layout/promo_card_view_compact.xml
+++ b/components/browser_ui/widget/android/java/res/layout/promo_card_view_compact.xml
@@ -8,74 +8,80 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:background="@drawable/hairline_border_card_background"
-    android:paddingTop="@dimen/promo_compact_padding"
-    android:paddingHorizontal="@dimen/promo_compact_padding"
-    android:paddingBottom="@dimen/promo_compact_padding_bottom">
+    app:cardElevation="@dimen/default_elevation_1"
+    style="@style/MaterialCardStyle">
 
-  <!-- Promo Header-->
   <LinearLayout
-      android:id="@+id/promo_header"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
-      android:orientation="horizontal"
-      android:layout_marginBottom="@dimen/promo_compact_header_margin_vertical">
+      android:orientation="vertical"
+      android:paddingTop="@dimen/promo_compact_padding"
+      android:paddingHorizontal="@dimen/promo_compact_padding"
+      android:paddingBottom="@dimen/promo_compact_padding_bottom">
 
-    <ImageView
-        android:id="@+id/promo_image"
-        android:layout_width="@dimen/promo_image_size"
-        android:layout_height="@dimen/promo_image_size"
-        android:layout_gravity="top"
-        android:scaleType="fitCenter"
-        android:importantForAccessibility="no" />
-
+    <!-- Promo Header-->
     <LinearLayout
-        android:id="@+id/promo_text_group"
-        android:layout_height="wrap_content"
+        android:id="@+id/promo_header"
         android:layout_width="match_parent"
-        android:layout_marginStart="@dimen/promo_compact_header_margin_vertical"
-        android:orientation="vertical">
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginBottom="@dimen/promo_compact_header_margin_vertical">
 
-      <org.chromium.ui.widget.TextViewWithLeading
-          android:id="@+id/promo_title"
-          android:layout_width="match_parent"
-          android:layout_height="wrap_content"
-          android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-          android:layout_marginBottom="@dimen/promo_between_text_margin"
-          app:leading="@dimen/text_size_large_leading"/>
+      <ImageView
+          android:id="@+id/promo_image"
+          android:layout_width="@dimen/promo_image_size"
+          android:layout_height="@dimen/promo_image_size"
+          android:layout_gravity="top"
+          android:scaleType="fitCenter"
+          android:importantForAccessibility="no" />
 
-      <org.chromium.ui.widget.TextViewWithLeading
-          android:id="@+id/promo_description"
-          android:layout_width="match_parent"
+      <LinearLayout
+          android:id="@+id/promo_text_group"
           android:layout_height="wrap_content"
-          android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-          app:leading="@dimen/text_size_small_leading"/>
+          android:layout_width="match_parent"
+          android:layout_marginStart="@dimen/promo_compact_header_margin_vertical"
+          android:orientation="vertical">
+
+        <org.chromium.ui.widget.TextViewWithLeading
+            android:id="@+id/promo_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.TextLarge.Primary"
+            android:layout_marginBottom="@dimen/promo_between_text_margin"
+            app:leading="@dimen/text_size_large_leading"/>
+
+        <org.chromium.ui.widget.TextViewWithLeading
+            android:id="@+id/promo_description"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+            app:leading="@dimen/text_size_small_leading"/>
+      </LinearLayout>
     </LinearLayout>
+
+    <org.chromium.components.browser_ui.widget.DualControlLayout
+        android:id="@+id/promo_button_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:buttonAlignment="end">
+
+      <org.chromium.ui.widget.ButtonCompat
+          android:id="@+id/promo_primary_button"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:singleLine="true"
+          android:ellipsize="end"
+          android:layout_gravity="top|end"
+          style="@style/FilledButton.Flat" />
+
+      <org.chromium.ui.widget.ButtonCompat
+          android:id="@+id/promo_secondary_button"
+          style="@style/TextButton"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:ellipsize="end"
+          android:singleLine="true"/>
+
+    </org.chromium.components.browser_ui.widget.DualControlLayout>
   </LinearLayout>
-
-  <org.chromium.components.browser_ui.widget.DualControlLayout
-      android:id="@+id/promo_button_group"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      app:buttonAlignment="end">
-
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/promo_primary_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:ellipsize="end"
-        android:layout_gravity="top|end"
-        style="@style/FilledButton.Flat" />
-
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/promo_secondary_button"
-        style="@style/TextButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:ellipsize="end"
-        android:singleLine="true"/>
-
-  </org.chromium.components.browser_ui.widget.DualControlLayout>
-</org.chromium.components.browser_ui.widget.promo.PromoCardView>
+</org.chromium.components.browser_ui.widget.promo.PromoCardView>
\ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/res/layout/promo_card_view_large.xml b/components/browser_ui/widget/android/java/res/layout/promo_card_view_large.xml
index 3c28512f..44d824f 100644
--- a/components/browser_ui/widget/android/java/res/layout/promo_card_view_large.xml
+++ b/components/browser_ui/widget/android/java/res/layout/promo_card_view_large.xml
@@ -8,61 +8,67 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:gravity="center_horizontal"
-    android:orientation="vertical"
-    android:background="@drawable/hairline_border_card_background"
-    android:paddingVertical="@dimen/promo_large_padding_vertical">
+    app:cardElevation="@dimen/default_elevation_1"
+    style="@style/MaterialCardStyle">
 
-  <!-- Promo Illustration-->
-  <ImageView
-      android:id="@+id/promo_image"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_marginBottom="@dimen/promo_large_illustration_margin_bottom"
-      android:adjustViewBounds="true"
-      android:layout_gravity="center"
-      android:scaleType="fitCenter"
-      android:importantForAccessibility="no"/>
-
-  <!-- Promo body -->
   <LinearLayout
       android:layout_width="match_parent"
-      android:layout_height="match_parent"
+      android:layout_height="wrap_content"
+      android:gravity="center_horizontal"
       android:orientation="vertical"
-      android:paddingHorizontal="@dimen/promo_large_padding_horizontal">
+      android:paddingVertical="@dimen/promo_large_padding_vertical">
 
-    <org.chromium.ui.widget.TextViewWithLeading
-        android:id="@+id/promo_title"
+    <!-- Promo Illustration-->
+    <ImageView
+        android:id="@+id/promo_image"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/promo_between_text_margin"
-        android:gravity="center"
-        android:textAppearance="@style/TextAppearance.TextLarge.Primary"
-        app:leading="@dimen/text_size_large_leading"/>
+        android:layout_marginBottom="@dimen/promo_large_illustration_margin_bottom"
+        android:adjustViewBounds="true"
+        android:layout_gravity="center"
+        android:scaleType="fitCenter"
+        android:importantForAccessibility="no"/>
 
-    <org.chromium.ui.widget.TextViewWithLeading
-        android:id="@+id/promo_description"
+    <!-- Promo body -->
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/promo_large_text_group_bottom_margin"
-        android:gravity="center"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
-        app:leading="@dimen/text_size_small_leading" />
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:paddingHorizontal="@dimen/promo_large_padding_horizontal">
 
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/promo_primary_button"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:ellipsize="end"
-        android:singleLine="true"
-        style="@style/FilledButton.Flat" />
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/promo_secondary_button"
-        style="@style/TextButton"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:ellipsize="end"
-        android:singleLine="true"/>
+      <org.chromium.ui.widget.TextViewWithLeading
+          android:id="@+id/promo_title"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:layout_marginBottom="@dimen/promo_between_text_margin"
+          android:gravity="center"
+          android:textAppearance="@style/TextAppearance.TextLarge.Primary"
+          app:leading="@dimen/text_size_large_leading"/>
 
+      <org.chromium.ui.widget.TextViewWithLeading
+          android:id="@+id/promo_description"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:layout_marginBottom="@dimen/promo_large_text_group_bottom_margin"
+          android:gravity="center"
+          android:textAppearance="@style/TextAppearance.TextSmall.Secondary"
+          app:leading="@dimen/text_size_small_leading" />
+
+      <org.chromium.ui.widget.ButtonCompat
+          android:id="@+id/promo_primary_button"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:ellipsize="end"
+          android:singleLine="true"
+          style="@style/FilledButton.Flat" />
+      <org.chromium.ui.widget.ButtonCompat
+          android:id="@+id/promo_secondary_button"
+          style="@style/TextButton"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:ellipsize="end"
+          android:singleLine="true"/>
+
+    </LinearLayout>
   </LinearLayout>
 </org.chromium.components.browser_ui.widget.promo.PromoCardView>
diff --git a/components/browser_ui/widget/android/java/res/layout/promo_card_view_slim.xml b/components/browser_ui/widget/android/java/res/layout/promo_card_view_slim.xml
index 3b0e229..a1ca1b4 100644
--- a/components/browser_ui/widget/android/java/res/layout/promo_card_view_slim.xml
+++ b/components/browser_ui/widget/android/java/res/layout/promo_card_view_slim.xml
@@ -8,38 +8,44 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:gravity="center_vertical|center_horizontal"
-    android:orientation="horizontal"
-    android:background="@drawable/hairline_border_card_background"
-    android:paddingVertical="@dimen/promo_slim_padding_vertical"
-    android:paddingHorizontal="@dimen/promo_compact_padding">
+    app:cardElevation="@dimen/default_elevation_1"
+    style="@style/MaterialCardStyle">
 
-  <!-- Promo Header-->
-  <ImageView
-      android:id="@+id/promo_image"
-      android:layout_width="@dimen/promo_image_size"
-      android:layout_height="@dimen/promo_image_size"
-      android:layout_gravity="center"
-      android:scaleType="fitCenter"
-      android:importantForAccessibility="no" />
-
-  <org.chromium.ui.widget.TextViewWithLeading
-      android:id="@+id/promo_title"
-      android:layout_width="0dp"
-      android:layout_weight="1"
+  <LinearLayout
+      android:layout_width="match_parent"
       android:layout_height="wrap_content"
-      android:layout_marginStart="@dimen/promo_slim_text_margin_horizontal"
-      android:layout_marginEnd="@dimen/promo_slim_text_margin_horizontal"
-      android:textAppearance="@style/TextAppearance.TextMedium.Primary"
-      app:leading="@dimen/text_size_medium_leading" />
+      android:gravity="center_vertical|center_horizontal"
+      android:orientation="horizontal"
+      android:paddingVertical="@dimen/promo_slim_padding_vertical"
+      android:paddingHorizontal="@dimen/promo_compact_padding">
 
-  <org.chromium.ui.widget.ButtonCompat
-      android:id="@+id/promo_primary_button"
-      android:layout_width="wrap_content"
-      android:maxWidth="@dimen/promo_slim_button_max_width"
-      android:layout_height="wrap_content"
-      android:ellipsize="end"
-      android:singleLine="true"
-      android:layout_gravity="center|end"
-      style="@style/TextButton" />
+    <!-- Promo Header-->
+    <ImageView
+        android:id="@+id/promo_image"
+        android:layout_width="@dimen/promo_image_size"
+        android:layout_height="@dimen/promo_image_size"
+        android:layout_gravity="center"
+        android:scaleType="fitCenter"
+        android:importantForAccessibility="no" />
+
+    <org.chromium.ui.widget.TextViewWithLeading
+        android:id="@+id/promo_title"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/promo_slim_text_margin_horizontal"
+        android:layout_marginEnd="@dimen/promo_slim_text_margin_horizontal"
+        android:textAppearance="@style/TextAppearance.TextMedium.Primary"
+        app:leading="@dimen/text_size_medium_leading" />
+
+    <org.chromium.ui.widget.ButtonCompat
+        android:id="@+id/promo_primary_button"
+        android:layout_width="wrap_content"
+        android:maxWidth="@dimen/promo_slim_button_max_width"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:singleLine="true"
+        android:layout_gravity="center|end"
+        style="@style/TextButton" />
+  </LinearLayout>
 </org.chromium.components.browser_ui.widget.promo.PromoCardView>
diff --git a/components/browser_ui/widget/android/java/res/values/styles.xml b/components/browser_ui/widget/android/java/res/values/styles.xml
index 1e6d292..353b449 100644
--- a/components/browser_ui/widget/android/java/res/values/styles.xml
+++ b/components/browser_ui/widget/android/java/res/values/styles.xml
@@ -12,6 +12,13 @@
         <item name="android:background">@drawable/hairline_border_card_dark_transparent_bg</item>
     </style>
 
+    <style name="MaterialCardStyle" parent="Widget.MaterialComponents.CardView">
+        <item name="shapeAppearance">@style/MaterialCardShape</item>
+    </style>
+
+    <style name="MaterialCardShape" parent="ShapeAppearance.MaterialComponents.MediumComponent">
+        <item name="cornerSize">16dp</item>
+    </style>
 
     <style name="ListActionButton" parent="@style/TextButton">
         <item name="android:minHeight">48dp</item>
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MaterialCardViewNoShadow.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MaterialCardViewNoShadow.java
new file mode 100644
index 0000000..d854b311
--- /dev/null
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/MaterialCardViewNoShadow.java
@@ -0,0 +1,33 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.browser_ui.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.google.android.material.card.MaterialCardView;
+
+/**
+ * Extension of {@link MaterialCardView} that set outline provider to null
+ * in order to remove shadow.
+ */
+public class MaterialCardViewNoShadow extends MaterialCardView {
+    /**
+     * Constructs an instance of MaterialCardViewNoShadow,
+     * which is an extension of {@link MaterialCardView} with shadow removed.
+     */
+    public MaterialCardViewNoShadow(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.materialCardViewStyle);
+    }
+
+    /**
+     * Constructs an instance of MaterialCardViewNoShadow,
+     * which is an extension of {@link MaterialCardView} with shadow removed.
+     */
+    public MaterialCardViewNoShadow(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        this.setOutlineProvider(null);
+    }
+}
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java
index 861f8a5..f7a5d13 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.support.test.InstrumentationRegistry;
+import android.view.ContextThemeWrapper;
 import android.view.View;
 
 import androidx.appcompat.content.res.AppCompatResources;
@@ -49,8 +50,15 @@
     }
 
     private void setupCoordinator(@LayoutStyle int layoutStyle) {
+        // TODO(https://crbug.com/1217140): Remove this theme wrapper after dummy ui activity
+        //  is based on material theme. For now we need the theme wrapper to inflate the layout;
+        //  because we are not setting our theme overlay for the test apk
+        ContextThemeWrapper wrapperColor = new ContextThemeWrapper(
+                mContext, org.chromium.components.browser_ui.widget.R.style.ColorOverlay);
+        ContextThemeWrapper wrapperTheme = new ContextThemeWrapper(
+                wrapperColor, org.chromium.components.browser_ui.widget.R.style.Theme_BrowserUI);
         mPromoCardCoordinator =
-                new PromoCardCoordinator(mContext, mModel, "test-feature", layoutStyle);
+                new PromoCardCoordinator(wrapperTheme, mModel, "test-feature", layoutStyle);
         mView = (PromoCardView) mPromoCardCoordinator.getView();
 
         Assert.assertNotNull("PromoCardView is null", mView);
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardView.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardView.java
index bc19877..0552374 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardView.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardView.java
@@ -7,11 +7,11 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.annotation.Nullable;
 
+import org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow;
 import org.chromium.components.browser_ui.widget.R;
 import org.chromium.ui.widget.ButtonCompat;
 
@@ -19,7 +19,7 @@
  * A promo card view that contains an image view in the top center, a block of short description,
  * two button compat and a close button.
  */
-class PromoCardView extends LinearLayout {
+class PromoCardView extends MaterialCardViewNoShadow {
     ImageView mPromoImage;
     TextView mTitle;
     ButtonCompat mPrimaryButton;
diff --git a/components/browsing_data/core/counters/history_counter.cc b/components/browsing_data/core/counters/history_counter.cc
index 94c008e..c0906a13 100644
--- a/components/browsing_data/core/counters/history_counter.cc
+++ b/components/browsing_data/core/counters/history_counter.cc
@@ -152,8 +152,8 @@
   // may have history items stored in Sync. Otherwise, we expect at least one
   // entry in the "event" list.
   const base::ListValue* events;
-  has_synced_visits_ =
-      !result || (result->GetList("event", &events) && !events->empty());
+  has_synced_visits_ = !result || (result->GetList("event", &events) &&
+                                   !events->GetList().empty());
   web_counting_finished_ = true;
   MergeResults();
 }
diff --git a/components/cloud_devices/common/printer_description.cc b/components/cloud_devices/common/printer_description.cc
index 62dbd9a..e79631c 100644
--- a/components/cloud_devices/common/printer_description.cc
+++ b/components/cloud_devices/common/printer_description.cc
@@ -961,6 +961,8 @@
 
 Media::Media(const Media& other) = default;
 
+Media& Media::operator=(const Media& other) = default;
+
 bool Media::MatchBySize() {
   const MediaDefinition* media = FindMediaBySize(width_um, height_um);
   if (!media)
diff --git a/components/cloud_devices/common/printer_description.h b/components/cloud_devices/common/printer_description.h
index 33da6fda..0b127a1 100644
--- a/components/cloud_devices/common/printer_description.h
+++ b/components/cloud_devices/common/printer_description.h
@@ -464,6 +464,7 @@
         int32_t height_um);
 
   Media(const Media& other);
+  Media& operator=(const Media& other);
 
   bool MatchBySize();
 
diff --git a/components/component_updater/android/component_loader_policy.cc b/components/component_updater/android/component_loader_policy.cc
index 67acfb31..ba95ef2 100644
--- a/components/component_updater/android/component_loader_policy.cc
+++ b/components/component_updater/android/component_loader_policy.cc
@@ -6,7 +6,6 @@
 
 #include <jni.h>
 #include <stdio.h>
-#include <unistd.h>
 
 #include <map>
 #include <memory>
@@ -104,18 +103,19 @@
 
   // Construct the file_name->file_descriptor map excluding the manifest file
   // as it's parsed and passed separately.
-  base::flat_map<std::string, int> fd_map;
+  base::flat_map<std::string, base::ScopedFD> fd_map;
   int manifest_fd = -1;
   for (size_t i = 0; i < file_names.size(); ++i) {
     const std::string& file_name = file_names[i];
     if (file_name == kManifestFileName) {
       manifest_fd = fds[i];
     } else {
-      fd_map[file_name] = fds[i];
+      fd_map[file_name] = base::ScopedFD(fds[i]);
     }
   }
+
   if (manifest_fd == -1) {
-    CloseFdsAndFail(fd_map);
+    loader_policy_->ComponentLoadFailed();
     return;
   }
 
@@ -124,7 +124,7 @@
       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
       base::BindOnce(ReadManifestFromFd, manifest_fd),
       base::BindOnce(&AndroidComponentLoaderPolicy::NotifyNewVersion,
-                     base::Owned(this), fd_map));
+                     base::Owned(this), base::OwnedRef(std::move(fd_map))));
 }
 
 void AndroidComponentLoaderPolicy::ComponentLoadFailed(JNIEnv* env) {
@@ -142,33 +142,24 @@
 }
 
 void AndroidComponentLoaderPolicy::NotifyNewVersion(
-    const base::flat_map<std::string, int>& fd_map,
+    base::flat_map<std::string, base::ScopedFD>& fd_map,
     std::unique_ptr<base::DictionaryValue> manifest) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!manifest) {
-    CloseFdsAndFail(fd_map);
+    loader_policy_->ComponentLoadFailed();
     return;
   }
   std::string version_ascii;
   manifest->GetStringASCII("version", &version_ascii);
   base::Version version(version_ascii);
   if (!version.IsValid()) {
-    CloseFdsAndFail(fd_map);
+    loader_policy_->ComponentLoadFailed();
     return;
   }
   loader_policy_->ComponentLoaded(version, fd_map, std::move(manifest));
 }
 
-void AndroidComponentLoaderPolicy::CloseFdsAndFail(
-    const base::flat_map<std::string, int>& fd_map) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  for (auto& iter : fd_map) {
-    close(iter.second);
-  }
-  loader_policy_->ComponentLoadFailed();
-}
-
 // static
 base::android::ScopedJavaLocalRef<jobjectArray>
 AndroidComponentLoaderPolicy::ToJavaArrayOfAndroidComponentLoaderPolicy(
diff --git a/components/component_updater/android/component_loader_policy.h b/components/component_updater/android/component_loader_policy.h
index ab66fc4..9a15f2c 100644
--- a/components/component_updater/android/component_loader_policy.h
+++ b/components/component_updater/android/component_loader_policy.h
@@ -14,6 +14,7 @@
 
 #include "base/android/scoped_java_ref.h"
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
 #include "components/component_updater/android/component_loader_policy_forward.h"
@@ -58,7 +59,7 @@
   // `manifest` is the manifest for this version of the component.
   virtual void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) = 0;
 
   // Called if connection to the service fails, components files are not found
@@ -113,9 +114,8 @@
   // `org.chromium.components.component_updater.ComponentLoaderPolicy`.
   base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
 
-  void NotifyNewVersion(const base::flat_map<std::string, int>& fd_map,
+  void NotifyNewVersion(base::flat_map<std::string, base::ScopedFD>& fd_map,
                         std::unique_ptr<base::DictionaryValue> manifest);
-  void CloseFdsAndFail(const base::flat_map<std::string, int>& fd_map);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/components/component_updater/android/component_loader_policy_unittests.cc b/components/component_updater/android/component_loader_policy_unittests.cc
index b5547f1a..500f2df 100644
--- a/components/component_updater/android/component_loader_policy_unittests.cc
+++ b/components/component_updater/android/component_loader_policy_unittests.cc
@@ -24,6 +24,7 @@
 #include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
@@ -58,7 +59,7 @@
 
 using OnLoadedTestCallBack =
     base::OnceCallback<void(const base::Version&,
-                            const base::flat_map<std::string, int>&,
+                            base::flat_map<std::string, base::ScopedFD>&,
                             std::unique_ptr<base::DictionaryValue>)>;
 
 class MockLoaderPolicy : public ComponentLoaderPolicy {
@@ -70,7 +71,7 @@
   MockLoaderPolicy()
       : on_loaded_(
             base::DoNothing::Once<const base::Version&,
-                                  const base::flat_map<std::string, int>&,
+                                  base::flat_map<std::string, base::ScopedFD>&,
                                   std::unique_ptr<base::DictionaryValue>>()),
         on_failed_(base::DoNothing::Once()) {}
 
@@ -81,7 +82,7 @@
 
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override {
     std::move(on_loaded_).Run(version, fd_map, std::move(manifest));
   }
@@ -97,7 +98,7 @@
 
 void VerifyComponentLoaded(base::OnceClosure on_done,
                            const base::Version& version,
-                           const base::flat_map<std::string, int>& fd_map,
+                           base::flat_map<std::string, base::ScopedFD>& fd_map,
                            std::unique_ptr<base::DictionaryValue> manifest) {
   EXPECT_EQ(version.GetString(), "123.456.789");
   EXPECT_EQ(fd_map.size(), 2u);
@@ -172,7 +173,7 @@
       new AndroidComponentLoaderPolicy(std::make_unique<MockLoaderPolicy>(
           base::BindOnce(
               [](const base::Version& version,
-                 const base::flat_map<std::string, int>& fd_map,
+                 base::flat_map<std::string, base::ScopedFD>& fd_map,
                  std::unique_ptr<base::DictionaryValue> manifest) { FAIL(); }),
           run_loop.QuitClosure()));
 
@@ -194,7 +195,7 @@
       new AndroidComponentLoaderPolicy(std::make_unique<MockLoaderPolicy>(
           base::BindOnce(
               [](const base::Version& version,
-                 const base::flat_map<std::string, int>& fd_map,
+                 base::flat_map<std::string, base::ScopedFD>& fd_map,
                  std::unique_ptr<base::DictionaryValue> manifest) { FAIL(); }),
           run_loop.QuitClosure()));
 
@@ -215,7 +216,7 @@
       new AndroidComponentLoaderPolicy(std::make_unique<MockLoaderPolicy>(
           base::BindOnce(
               [](const base::Version& version,
-                 const base::flat_map<std::string, int>& fd_map,
+                 base::flat_map<std::string, base::ScopedFD>& fd_map,
                  std::unique_ptr<base::DictionaryValue> manifest) { FAIL(); }),
           run_loop.QuitClosure()));
 
diff --git a/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc b/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc
index cde932a5..a7f5834 100644
--- a/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc
+++ b/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 #include <stdio.h>
-#include <unistd.h>
 
 #include <memory>
 #include <string>
@@ -17,6 +16,7 @@
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/values.h"
 #include "base/version.h"
@@ -28,8 +28,9 @@
 // Attempts to load key commitments as raw JSON from their storage file,
 // returning the loaded commitments on success and nullopt on failure.
 // TODO(crbug.com/1180964) move reading string from fd to base/file_util.h
-absl::optional<std::string> LoadKeyCommitmentsFromDisk(int fd) {
-  base::ScopedFILE file_stream(fdopen(fd, "r"));
+absl::optional<std::string> LoadKeyCommitmentsFromDisk(base::ScopedFD fd) {
+  // Transfer the ownership of the file from `fd` to `file_stream`.
+  base::ScopedFILE file_stream(fdopen(fd.release(), "r"));
   if (!file_stream.get()) {
     return absl::nullopt;
   }
@@ -54,18 +55,10 @@
 
 void TrustTokenKeyCommitmentsComponentLoaderPolicy::ComponentLoaded(
     const base::Version& version,
-    const base::flat_map<std::string, int>& fd_map,
+    base::flat_map<std::string, base::ScopedFD>& fd_map,
     std::unique_ptr<base::DictionaryValue> manifest) {
-  int keys_fd = -1;
-  for (auto& key_value : fd_map) {
-    if (key_value.first == kTrustTokenKeyCommitmentsFileName) {
-      keys_fd = key_value.second;
-    } else {
-      // Close unused fds.
-      close(key_value.second);
-    }
-  }
-  if (keys_fd == -1) {
+  auto keys_fd_iterator = fd_map.find(kTrustTokenKeyCommitmentsFileName);
+  if (keys_fd_iterator == fd_map.end()) {
     VLOG(1) << "TrustTokenKeyCommitmentsComponentLoaderPolicy#ComponentLoaded "
                "failed because keys.json is not found in the fd map";
     ComponentLoadFailed();
@@ -73,7 +66,8 @@
   }
   component_updater::TrustTokenKeyCommitmentsComponentInstallerPolicy::
       LoadTrustTokensFromString(
-          base::BindOnce(&LoadKeyCommitmentsFromDisk, keys_fd),
+          base::BindOnce(&LoadKeyCommitmentsFromDisk,
+                         std::move(keys_fd_iterator->second)),
           on_commitments_ready_);
 }
 
diff --git a/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h b/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h
index 9652cdb1..4f10a4e 100644
--- a/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h
+++ b/components/component_updater/android/loader_policies/trust_token_key_commitments_component_loader_policy.h
@@ -13,6 +13,7 @@
 
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
 #include "components/component_updater/android/component_loader_policy.h"
 
 namespace base {
@@ -43,7 +44,7 @@
   // The following methods override ComponentLoaderPolicy.
   void ComponentLoaded(
       const base::Version& version,
-      const base::flat_map<std::string, int>& fd_map,
+      base::flat_map<std::string, base::ScopedFD>& fd_map,
       std::unique_ptr<base::DictionaryValue> manifest) override;
   void ComponentLoadFailed() override;
   void GetHash(std::vector<uint8_t>* hash) const override;
diff --git a/components/content_creation/notes/core/templates/template_constants.cc b/components/content_creation/notes/core/templates/template_constants.cc
index 78889773..8b0e302 100644
--- a/components/content_creation/notes/core/templates/template_constants.cc
+++ b/components/content_creation/notes/core/templates/template_constants.cc
@@ -14,6 +14,7 @@
 const uint16_t k700Weight = 700;
 
 const int kDefaultMinTextSizeSP = 14;
+const int kFriendlyMinTextSizeSP = 9;
 const int kDefaultMaxTextSizeSP = 48;
 const int kFriendlyMaxSizeSP = 32;
 const int kBiggerMaxTextSizeSP = 60;
@@ -85,7 +86,7 @@
       TextStyle(kRockSaltFontName,
                 /*font_color=*/kGrey900Color, k400Weight,
                 /*all_caps=*/false, TextAlignment::kStart,
-                kDefaultMinTextSizeSP, kFriendlyMaxSizeSP),
+                kFriendlyMinTextSizeSP, kFriendlyMaxSizeSP),
       /*footer_style=*/CreateLightBackgroundFooterStyle());
 }
 
diff --git a/components/enterprise/BUILD.gn b/components/enterprise/BUILD.gn
index 8c58791..7774b6b 100644
--- a/components/enterprise/BUILD.gn
+++ b/components/enterprise/BUILD.gn
@@ -6,16 +6,21 @@
 
 static_library("enterprise") {
   sources = [
-    "browser/controller/browser_dm_token_storage.cc",
-    "browser/controller/browser_dm_token_storage.h",
-    "browser/controller/chrome_browser_cloud_management_helper.cc",
-    "browser/controller/chrome_browser_cloud_management_helper.h",
-    "browser/enterprise_switches.cc",
-    "browser/enterprise_switches.h",
     "browser/reporting/common_pref_names.cc",
     "browser/reporting/common_pref_names.h",
   ]
 
+  if (!is_chromeos_ash) {
+    sources += [
+      "browser/controller/browser_dm_token_storage.cc",
+      "browser/controller/browser_dm_token_storage.h",
+      "browser/controller/chrome_browser_cloud_management_helper.cc",
+      "browser/controller/chrome_browser_cloud_management_helper.h",
+      "browser/enterprise_switches.cc",
+      "browser/enterprise_switches.h",
+    ]
+  }
+
   deps = [
     "//base",
     "//build:chromeos_buildflags",
@@ -72,44 +77,49 @@
 
 static_library("test_support") {
   testonly = true
-  sources = [
-    "browser/controller/fake_browser_dm_token_storage.cc",
-    "browser/controller/fake_browser_dm_token_storage.h",
-  ]
-  deps = [
-    ":enterprise",
-    "//base",
-  ]
+
+  if (!is_chromeos_ash) {
+    sources = [
+      "browser/controller/fake_browser_dm_token_storage.cc",
+      "browser/controller/fake_browser_dm_token_storage.h",
+    ]
+    deps = [
+      ":enterprise",
+      "//base",
+    ]
+  }
 }
 
 source_set("unit_tests") {
   testonly = true
 
-  sources = [ "browser/controller/browser_dm_token_storage_unittest.cc" ]
+  if (!is_chromeos_ash) {
+    sources = [ "browser/controller/browser_dm_token_storage_unittest.cc" ]
 
-  deps = [
-    ":enterprise",
-    ":test_support",
-    "//base",
-    "//base/test:test_support",
-    "//testing/gmock",
-    "//testing/gtest",
-  ]
-
-  if (!is_android) {
-    sources += [
-      "browser/reporting/cloud_reporting_policy_handler_unittest.cc",
-      "browser/reporting/real_time_uploader_unittest.cc",
-      "browser/reporting/report_uploader_unittest.cc",
+    deps = [
+      ":enterprise",
+      ":test_support",
+      "//base",
+      "//base/test:test_support",
+      "//testing/gmock",
+      "//testing/gtest",
     ]
 
-    deps += [
-      "//build:chromeos_buildflags",
-      "//components/enterprise/common/proto:extensions_workflow_events_proto",
-      "//components/policy/core/browser:test_support",
-      "//components/policy/core/common:test_support",
-      "//components/prefs:test_support",
-      "//components/reporting/client:test_support",
-    ]
+    if (!is_android) {
+      sources += [
+        "browser/reporting/cloud_reporting_policy_handler_unittest.cc",
+        "browser/reporting/real_time_uploader_unittest.cc",
+        "browser/reporting/report_uploader_unittest.cc",
+      ]
+
+      deps += [
+        "//build:chromeos_buildflags",
+        "//components/enterprise/common/proto:extensions_workflow_events_proto",
+        "//components/policy/core/browser:test_support",
+        "//components/policy/core/common:test_support",
+        "//components/prefs:test_support",
+        "//components/reporting/client:test_support",
+      ]
+    }
   }
 }
diff --git a/components/enterprise/browser/controller/browser_dm_token_storage.cc b/components/enterprise/browser/controller/browser_dm_token_storage.cc
index 2f4b9729..e618bb03 100644
--- a/components/enterprise/browser/controller/browser_dm_token_storage.cc
+++ b/components/enterprise/browser/controller/browser_dm_token_storage.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
+#include <stddef.h>
 
 #include <memory>
 #include <string>
@@ -21,6 +22,7 @@
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h"
 
 namespace policy {
 
@@ -154,6 +156,13 @@
 
   is_initialized_ = true;
 
+  // When CBCM is not enabled, set the DM token to empty directly withtout
+  // actually read it.
+  if (!ChromeBrowserCloudManagementController::IsEnabled()) {
+    dm_token_ = CreateEmptyToken();
+    return;
+  }
+
   // Only supported in official builds.
   client_id_ = delegate_->InitClientId();
   DVLOG(1) << "Client ID = " << client_id_;
diff --git a/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.cc b/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.cc
index ce258973..54e273f 100644
--- a/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.cc
+++ b/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.cc
@@ -91,6 +91,7 @@
     cloud_policy_client_->RemoveObserver(this);
 }
 
+// static
 bool ChromeBrowserCloudManagementController::IsEnabled() {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   return true;
diff --git a/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h b/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h
index f5f2990..c993538d 100644
--- a/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h
+++ b/components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h
@@ -191,7 +191,7 @@
   // The Chrome browser cloud management is only enabled on Chrome by default.
   // However, it can be enabled on Chromium by command line switch for test and
   // development purpose.
-  bool IsEnabled();
+  static bool IsEnabled();
 
   // Returns a MachineLevelUserCloudPolicyManager instance if cloud management
   // is enabled, or nullptr otherwise.
diff --git a/components/enterprise/browser/controller/fake_browser_dm_token_storage.cc b/components/enterprise/browser/controller/fake_browser_dm_token_storage.cc
index 8659734c..90e7cce 100644
--- a/components/enterprise/browser/controller/fake_browser_dm_token_storage.cc
+++ b/components/enterprise/browser/controller/fake_browser_dm_token_storage.cc
@@ -5,12 +5,16 @@
 #include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/task/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "components/enterprise/browser/enterprise_switches.h"
 
 namespace policy {
 
 FakeBrowserDMTokenStorage::FakeBrowserDMTokenStorage() {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableChromeBrowserCloudManagement);
   BrowserDMTokenStorage::SetForTesting(this);
   delegate_ = std::make_unique<MockDelegate>();
 }
@@ -20,6 +24,8 @@
     const std::string& enrollment_token,
     const std::string& dm_token,
     bool enrollment_error_option) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      switches::kEnableChromeBrowserCloudManagement);
   BrowserDMTokenStorage::SetForTesting(this);
   delegate_ = std::make_unique<MockDelegate>(client_id, enrollment_token,
                                              dm_token, enrollment_error_option);
diff --git a/components/enterprise/browser/reporting/policy_info.cc b/components/enterprise/browser/reporting/policy_info.cc
index 3b4daed..f699733 100644
--- a/components/enterprise/browser/reporting/policy_info.cc
+++ b/components/enterprise/browser/reporting/policy_info.cc
@@ -54,8 +54,9 @@
       return em::Policy_PolicySource_SOURCE_CLOUD;
     case policy::POLICY_SOURCE_ACTIVE_DIRECTORY:
       return em::Policy_PolicySource_SOURCE_ACTIVE_DIRECTORY;
-    case policy::POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE:
-      return em::Policy_PolicySource_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE;
+    case policy::POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED:
+      return em::
+          Policy_PolicySource_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED;
     case policy::POLICY_SOURCE_PLATFORM:
       return em::Policy_PolicySource_SOURCE_PLATFORM;
     case policy::POLICY_SOURCE_PRIORITY_CLOUD:
diff --git a/components/enterprise/browser/reporting/report_scheduler.cc b/components/enterprise/browser/reporting/report_scheduler.cc
index 226d4d6..e412bdd 100644
--- a/components/enterprise/browser/reporting/report_scheduler.cc
+++ b/components/enterprise/browser/reporting/report_scheduler.cc
@@ -172,6 +172,7 @@
   if (cloud_policy_client_->is_registered())
     return true;
 
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
   policy::DMToken browser_dm_token =
       policy::BrowserDMTokenStorage::Get()->RetrieveDMToken();
   std::string client_id =
@@ -186,6 +187,10 @@
   cloud_policy_client_->SetupRegistration(browser_dm_token.value(), client_id,
                                           std::vector<std::string>());
   return true;
+#else
+  NOTREACHED();
+  return true;
+#endif
 }
 
 void ReportScheduler::Start(base::Time last_upload_time) {
diff --git a/components/favicon/core/favicon_database.cc b/components/favicon/core/favicon_database.cc
index dedb4f2..940014c 100644
--- a/components/favicon/core/favicon_database.cc
+++ b/components/favicon/core/favicon_database.cc
@@ -512,8 +512,7 @@
 
   statement.BindInt64(0, icon_id);
   if (icon_data.get() && icon_data->size()) {
-    statement.BindBlob(1, icon_data->front(),
-                       static_cast<int>(icon_data->size()));
+    statement.BindBlob(1, *icon_data);
   } else {
     statement.BindNull(1);
   }
@@ -553,8 +552,7 @@
                              "UPDATE favicon_bitmaps SET image_data=?, "
                              "last_updated=?, last_requested=? WHERE id=?"));
   if (bitmap_data.get() && bitmap_data->size()) {
-    statement.BindBlob(0, bitmap_data->front(),
-                       static_cast<int>(bitmap_data->size()));
+    statement.BindBlob(0, *bitmap_data);
   } else {
     statement.BindNull(0);
   }
diff --git a/components/favicon_base/favicon_url_parser.cc b/components/favicon_base/favicon_url_parser.cc
index 2b557403..83a7b5f6 100644
--- a/components/favicon_base/favicon_url_parser.cc
+++ b/components/favicon_base/favicon_url_parser.cc
@@ -137,6 +137,9 @@
 
 ParsedFaviconPath::ParsedFaviconPath(const ParsedFaviconPath& other) = default;
 
+ParsedFaviconPath& ParsedFaviconPath::operator=(
+    const ParsedFaviconPath& other) = default;
+
 bool ParseFaviconPath(const std::string& path,
                       FaviconUrlFormat format,
                       ParsedFaviconPath* parsed) {
diff --git a/components/favicon_base/favicon_url_parser.h b/components/favicon_base/favicon_url_parser.h
index dc8108a..58c5b297 100644
--- a/components/favicon_base/favicon_url_parser.h
+++ b/components/favicon_base/favicon_url_parser.h
@@ -16,6 +16,7 @@
 struct ParsedFaviconPath {
   ParsedFaviconPath();
   ParsedFaviconPath(const ParsedFaviconPath& other);
+  ParsedFaviconPath& operator=(const ParsedFaviconPath& other);
 
   // URL pointing to the page whose favicon we want.
   std::string page_url;
diff --git a/components/feature_engagement/internal/condition_validator.cc b/components/feature_engagement/internal/condition_validator.cc
index 454df1d0..5b9bdd2 100644
--- a/components/feature_engagement/internal/condition_validator.cc
+++ b/components/feature_engagement/internal/condition_validator.cc
@@ -21,19 +21,10 @@
       availability_ok(initial_values),
       display_lock_ok(initial_values) {}
 
-ConditionValidator::Result::Result(const Result& other) {
-  event_model_ready_ok = other.event_model_ready_ok;
-  currently_showing_ok = other.currently_showing_ok;
-  feature_enabled_ok = other.feature_enabled_ok;
-  config_ok = other.config_ok;
-  used_ok = other.used_ok;
-  trigger_ok = other.trigger_ok;
-  preconditions_ok = other.preconditions_ok;
-  session_rate_ok = other.session_rate_ok;
-  availability_model_ready_ok = other.availability_model_ready_ok;
-  availability_ok = other.availability_ok;
-  display_lock_ok = other.display_lock_ok;
-}
+ConditionValidator::Result::Result(const Result& other) = default;
+
+ConditionValidator::Result& ConditionValidator::Result::operator=(
+    const Result& other) = default;
 
 bool ConditionValidator::Result::NoErrors() const {
   return event_model_ready_ok && currently_showing_ok && feature_enabled_ok &&
diff --git a/components/feature_engagement/internal/condition_validator.h b/components/feature_engagement/internal/condition_validator.h
index 1d49a52..b2a096a 100644
--- a/components/feature_engagement/internal/condition_validator.h
+++ b/components/feature_engagement/internal/condition_validator.h
@@ -35,6 +35,7 @@
   struct Result {
     explicit Result(bool initial_values);
     Result(const Result& other);
+    Result& operator=(const Result& other);
 
     // Whether the event model was ready.
     bool event_model_ready_ok;
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index 86ae898..e228310 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
-#include "base/stl_util.h"
 #include "build/build_config.h"
 #include "components/feature_engagement/public/feature_constants.h"
 #include "components/flags_ui/feature_entry.h"
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc
index d034b2af0..107257c 100644
--- a/components/history/core/browser/download_database.cc
+++ b/components/history/core/browser/download_database.cc
@@ -588,7 +588,7 @@
   statement.BindInt(column++, DownloadDangerTypeToInt(data.danger_type));
   statement.BindInt(column++,
                     DownloadInterruptReasonToInt(data.interrupt_reason));
-  statement.BindBlob(column++, data.hash.data(), data.hash.size());
+  statement.BindBlob(column++, data.hash);
   statement.BindInt64(column++, data.end_time.ToInternalValue());
   statement.BindInt64(column++, data.total_bytes);
   statement.BindInt(column++, (data.opened ? 1 : 0));
@@ -681,7 +681,7 @@
                              DownloadDangerTypeToInt(info.danger_type));
     statement_insert.BindInt(
         column++, DownloadInterruptReasonToInt(info.interrupt_reason));
-    statement_insert.BindBlob(column++, info.hash.data(), info.hash.size());
+    statement_insert.BindBlob(column++, info.hash);
     statement_insert.BindInt64(column++, info.end_time.ToInternalValue());
     statement_insert.BindInt(column++, info.opened ? 1 : 0);
     statement_insert.BindInt64(column++,
diff --git a/components/history_clusters/core/BUILD.gn b/components/history_clusters/core/BUILD.gn
index 3b50047..e56f431a 100644
--- a/components/history_clusters/core/BUILD.gn
+++ b/components/history_clusters/core/BUILD.gn
@@ -68,7 +68,10 @@
 
 source_set("unit_tests") {
   testonly = true
-  sources = [ "history_clusters_service_unittest.cc" ]
+  sources = [
+    "history_clusters_service_unittest.cc",
+    "remote_clustering_backend_unittest.cc",
+  ]
   deps = [
     ":clustering_backend",
     ":core",
@@ -85,7 +88,10 @@
 
 source_set("test_support") {
   testonly = true
-  sources = [ "history_clusters_service_test_api.h" ]
+  sources = [
+    "history_clusters_service_test_api.cc",
+    "history_clusters_service_test_api.h",
+  ]
   deps = [
     ":clustering_backend",
     ":core",
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc
index 1cd3168f..b2cba14 100644
--- a/components/history_clusters/core/history_clusters_service.cc
+++ b/components/history_clusters/core/history_clusters_service.cc
@@ -159,7 +159,7 @@
   }
 #endif
 
-  if (!backend_ && RemoteModelEndpoint().is_valid()) {
+  if (!backend_ && RemoteModelEndpoint().is_valid() && url_loader_factory) {
     backend_ = std::make_unique<RemoteClusteringBackend>(
         url_loader_factory,
         base::BindRepeating(&HistoryClustersService::NotifyDebugMessage,
diff --git a/components/history_clusters/core/history_clusters_service.h b/components/history_clusters/core/history_clusters_service.h
index 1127326..5848b134 100644
--- a/components/history_clusters/core/history_clusters_service.h
+++ b/components/history_clusters/core/history_clusters_service.h
@@ -35,6 +35,9 @@
     virtual void OnMemoriesDebugMessage(const std::string& message) = 0;
   };
 
+  // `url_loader_factory` is allowed to be nullptr, like in unit tests.
+  // In that case, HistoryClustersService will never instantiate a clustering
+  // backend that requires it, such as the RemoteClusteringBackend.
   explicit HistoryClustersService(
       history::HistoryService* history_service,
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
diff --git a/components/history_clusters/core/history_clusters_service_test_api.cc b/components/history_clusters/core/history_clusters_service_test_api.cc
new file mode 100644
index 0000000..ad1f79b
--- /dev/null
+++ b/components/history_clusters/core/history_clusters_service_test_api.cc
@@ -0,0 +1,50 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/history_clusters/core/history_clusters_service_test_api.h"
+
+#include "base/time/time.h"
+#include "components/history/core/browser/history_types.h"
+
+namespace history_clusters {
+
+// static
+std::vector<history::AnnotatedVisit> GetHardcodedTestVisits() {
+  std::vector<history::AnnotatedVisit> visits;
+
+  {
+    history::AnnotatedVisit visit;
+    visit.url_row.set_id(1);
+    visit.url_row.set_url(GURL("https://google.com/"));
+    visit.url_row.set_title(u"Google title");
+    visit.visit_row.visit_id = 1;
+    // Choose a recent time, as otherwise History will discard the visit.
+    visit.visit_row.visit_time =
+        base::Time::Now() - base::TimeDelta::FromDays(2);
+    visit.visit_row.visit_duration = base::TimeDelta::FromMilliseconds(5600);
+    visit.context_annotations.page_end_reason = 3;
+    visit.context_annotations.is_new_bookmark = true;
+    visits.push_back(visit);
+  }
+
+  {
+    history::AnnotatedVisit visit;
+    visit.url_row.set_id(2);
+    visit.url_row.set_url(GURL("https://github.com/"));
+    visit.url_row.set_title(u"Github title");
+    visit.visit_row.visit_id = 2;
+    // Choose a recent time, as otherwise History will discard the visit.
+    visit.visit_row.visit_time =
+        base::Time::Now() - base::TimeDelta::FromDays(1);
+    visit.visit_row.visit_duration = base::TimeDelta::FromSeconds(20);
+    visit.visit_row.referring_visit = 1;
+    visit.context_annotations.page_end_reason = 5;
+    visit.context_annotations.is_existing_part_of_tab_group = true;
+    visits.push_back(visit);
+  }
+
+  return visits;
+}
+
+}  // namespace history_clusters
diff --git a/components/history_clusters/core/history_clusters_service_test_api.h b/components/history_clusters/core/history_clusters_service_test_api.h
index 1cda0aca..ecb4741 100644
--- a/components/history_clusters/core/history_clusters_service_test_api.h
+++ b/components/history_clusters/core/history_clusters_service_test_api.h
@@ -56,6 +56,9 @@
   history::HistoryService* const history_service_;
 };
 
+// Fetches two hardcoded test visits.
+std::vector<history::AnnotatedVisit> GetHardcodedTestVisits();
+
 }  // namespace history_clusters
 
 #endif  // COMPONENTS_HISTORY_CLUSTERS_CORE_HISTORY_CLUSTERS_SERVICE_TEST_API_H_
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc
index 669e1df0..b08038c 100644
--- a/components/history_clusters/core/history_clusters_service_unittest.cc
+++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -7,12 +7,8 @@
 #include <memory>
 #include <string>
 
-#include "base/base64.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/json/json_reader.h"
-#include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/cancelable_task_tracker.h"
@@ -21,7 +17,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
-#include "base/values.h"
 #include "build/build_config.h"
 #include "components/history/core/browser/history_context.h"
 #include "components/history/core/browser/history_types.h"
@@ -31,12 +26,7 @@
 #include "components/history_clusters/core/history_clusters.mojom.h"
 #include "components/history_clusters/core/history_clusters_service_test_api.h"
 #include "components/history_clusters/core/memories_features.h"
-#include "components/history_clusters/core/proto/clusters.pb.h"
 #include "components/history_clusters/core/visit_data.h"
-#include "services/network/public/cpp/data_element.h"
-#include "services/network/public/cpp/resource_request_body.h"
-#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "services/network/test/test_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -85,9 +75,6 @@
   HistoryClustersServiceTest()
       : task_environment_(
             base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
-        shared_url_loader_factory_(
-            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
-                &test_url_loader_factory_)),
         run_loop_quit_(run_loop_.QuitClosure()) {
     scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
     scoped_feature_list_->InitAndEnableFeature(kMemories);
@@ -96,7 +83,7 @@
     history_service_ =
         history::CreateHistoryService(history_dir_.GetPath(), true);
     history_clusters_service_ = std::make_unique<HistoryClustersService>(
-        history_service_.get(), shared_url_loader_factory_);
+        history_service_.get(), nullptr);
     history_clusters_service_test_api_ =
         std::make_unique<HistoryClustersServiceTestApi>(
             history_clusters_service_.get(), history_service_.get());
@@ -110,103 +97,35 @@
   HistoryClustersServiceTest& operator=(const HistoryClustersServiceTest&) =
       delete;
 
-  // TODO(tommycli): Move this to a separate test subclass to separate tests
-  // that validate the remote backend vs. the tests that validate the service.
-  void EnableRemoteClusteringBackend(
-      const std::string& endpoint_url = kFakeEndpoint,
-      const std::string& endpoint_experiment = "") {
-    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
-    scoped_feature_list_->InitWithFeaturesAndParameters(
-        {
-            {
-                kMemories,
-                {
-                    {"MemoriesExperimentName", endpoint_experiment},
-                    // We have to disable the on-device backend to get the
-                    // remote backend.
-                    {"MemoriesOnDeviceClusteringBackend", "false"},
-                },
-            },
-            {
-                kRemoteModelForDebugging,
-                {
-                    {"MemoriesRemoteModelEndpoint", endpoint_url},
-                },
-            },
-        },
-        {});
-
-    // Re-create service after changing flags.
-    history_clusters_service_ = std::make_unique<HistoryClustersService>(
-        history_service_.get(), shared_url_loader_factory_);
-    history_clusters_service_test_api_ =
-        std::make_unique<HistoryClustersServiceTestApi>(
-            history_clusters_service_.get(), history_service_.get());
-    test_clustering_backend_ = nullptr;
-  }
-
-  void AddVisit(const history::AnnotatedVisit& visit) {
-    history::ContextID context_id = reinterpret_cast<history::ContextID>(1);
-    history::HistoryAddPageArgs add_page_args;
-    add_page_args.context_id = context_id;
-    add_page_args.nav_entry_id = next_navigation_id_;
-    add_page_args.url = visit.url_row.url();
-    add_page_args.title = visit.url_row.title();
-    add_page_args.time = visit.visit_row.visit_time;
-    history_service_->AddPage(add_page_args);
-    history_service_->UpdateWithPageEndTime(
-        context_id, next_navigation_id_, visit.url_row.url(),
-        visit.visit_row.visit_time + visit.visit_row.visit_duration);
-
-    auto& incomplete_visit_context_annotations =
-        history_clusters_service_->GetOrCreateIncompleteVisitContextAnnotations(
-            next_navigation_id_);
-    incomplete_visit_context_annotations.visit_row = visit.visit_row;
-    incomplete_visit_context_annotations.url_row = visit.url_row;
-    incomplete_visit_context_annotations.context_annotations =
-        visit.context_annotations;
-    incomplete_visit_context_annotations.status.history_rows = true;
-    incomplete_visit_context_annotations.status.navigation_ended = true;
-    incomplete_visit_context_annotations.status.navigation_end_signals = true;
-    history_clusters_service_->CompleteVisitContextAnnotationsIfReady(
-        next_navigation_id_);
-    next_navigation_id_++;
-  }
-
-  // Helper to get the most recent remote request body.
-  std::string GetPendingRequestBody() {
-    const scoped_refptr<network::ResourceRequestBody>& request_body =
-        test_url_loader_factory_.GetPendingRequest(0)->request.request_body;
-    const network::DataElement& element = (*request_body->elements())[0];
-    return std::string(element.As<network::DataElementBytes>().AsStringPiece());
-  }
-
   void AddHardcodedTestDataToHistoryService() {
-    {
-      history::AnnotatedVisit visit;
-      visit.url_row.set_id(1);
-      visit.url_row.set_url(GURL("https://google.com/"));
-      visit.url_row.set_title(u"Google title");
-      visit.visit_row.visit_id = 1;
-      visit.visit_row.visit_time = visit_1_time_;
-      visit.visit_row.visit_duration = base::TimeDelta::FromMilliseconds(5600);
-      visit.context_annotations.page_end_reason = 3;
-      visit.context_annotations.is_new_bookmark = true;
-      AddVisit(visit);
-    }
+    history::ContextID context_id = reinterpret_cast<history::ContextID>(1);
 
-    {
-      history::AnnotatedVisit visit;
-      visit.url_row.set_id(2);
-      visit.url_row.set_url(GURL("https://github.com/"));
-      visit.url_row.set_title(u"Github title");
-      visit.visit_row.visit_id = 2;
-      visit.visit_row.visit_time = visit_2_time_;
-      visit.visit_row.visit_duration = base::TimeDelta::FromSeconds(20);
-      visit.visit_row.referring_visit = 1;
-      visit.context_annotations.page_end_reason = 5;
-      visit.context_annotations.is_existing_part_of_tab_group = true;
-      AddVisit(visit);
+    for (auto& visit : GetHardcodedTestVisits()) {
+      history::HistoryAddPageArgs add_page_args;
+      add_page_args.context_id = context_id;
+      add_page_args.nav_entry_id = next_navigation_id_;
+      add_page_args.url = visit.url_row.url();
+      add_page_args.title = visit.url_row.title();
+      add_page_args.time = visit.visit_row.visit_time;
+      history_service_->AddPage(add_page_args);
+      history_service_->UpdateWithPageEndTime(
+          context_id, next_navigation_id_, visit.url_row.url(),
+          visit.visit_row.visit_time + visit.visit_row.visit_duration);
+
+      auto& incomplete_visit_context_annotations =
+          history_clusters_service_
+              ->GetOrCreateIncompleteVisitContextAnnotations(
+                  next_navigation_id_);
+      incomplete_visit_context_annotations.visit_row = visit.visit_row;
+      incomplete_visit_context_annotations.url_row = visit.url_row;
+      incomplete_visit_context_annotations.context_annotations =
+          visit.context_annotations;
+      incomplete_visit_context_annotations.status.history_rows = true;
+      incomplete_visit_context_annotations.status.navigation_ended = true;
+      incomplete_visit_context_annotations.status.navigation_end_signals = true;
+      history_clusters_service_->CompleteVisitContextAnnotationsIfReady(
+          next_navigation_id_);
+      next_navigation_id_++;
     }
   }
 
@@ -217,14 +136,16 @@
     ASSERT_EQ(visits.size(), 2u);
     auto& visit = visits[0];
     EXPECT_EQ(visit.visit_row.visit_id, 2);
-    EXPECT_EQ(visit.visit_row.visit_time, visit_2_time_);
+    EXPECT_EQ(visit.visit_row.visit_time,
+              GetHardcodedTestVisits()[1].visit_row.visit_time);
     EXPECT_EQ(visit.visit_row.visit_duration, base::TimeDelta::FromSeconds(20));
     EXPECT_EQ(visit.url_row.url(), "https://github.com/");
     EXPECT_EQ(visit.context_annotations.page_end_reason, 5);
 
     visit = visits[1];
     EXPECT_EQ(visit.visit_row.visit_id, 1);
-    EXPECT_EQ(visit.visit_row.visit_time, visit_1_time_);
+    EXPECT_EQ(visit.visit_row.visit_time,
+              GetHardcodedTestVisits()[0].visit_row.visit_time);
     EXPECT_EQ(visit.visit_row.visit_duration,
               base::TimeDelta::FromMilliseconds(5600));
     EXPECT_EQ(visit.url_row.url(), "https://google.com/");
@@ -240,11 +161,8 @@
   base::ScopedTempDir history_dir_;
   std::unique_ptr<history::HistoryService> history_service_;
 
-  static constexpr char kFakeEndpoint[] = "https://endpoint.com/";
   std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
 
-  network::TestURLLoaderFactory test_url_loader_factory_;
-  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
   std::unique_ptr<HistoryClustersService> history_clusters_service_;
   std::unique_ptr<HistoryClustersServiceTestApi>
       history_clusters_service_test_api_;
@@ -258,108 +176,10 @@
   base::RunLoop run_loop_;
   base::RepeatingClosure run_loop_quit_;
 
-  // Must not be too old otherwise the history layer will ignore the visit.
-  base::Time visit_1_time_ = base::Time::Now() - base::TimeDelta::FromDays(2);
-  base::Time visit_2_time_ = base::Time::Now() - base::TimeDelta::FromDays(1);
-
   // Tracks the next available navigation ID to be associated with visits.
   int64_t next_navigation_id_ = 0;
 };
 
-// Useless, but required by the C++14 standard. Please deliver us, C++17.
-constexpr char HistoryClustersServiceTest::kFakeEndpoint[];
-
-TEST_F(HistoryClustersServiceTest, Remote_RemoteClusteringBackend_EndToEnd) {
-  std::string experiment_name = "someExperiment";
-  EnableRemoteClusteringBackend(kFakeEndpoint, experiment_name);
-  AddHardcodedTestDataToHistoryService();
-
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        ASSERT_EQ(clusters.size(), 2u);
-
-        ASSERT_EQ(clusters[0]->visits.size(), 2u);
-        EXPECT_EQ(clusters[0]->visits[0]->normalized_url,
-                  "https://github.com/");
-        EXPECT_FLOAT_EQ(clusters[0]->visits[0]->score, 0.66);
-        EXPECT_EQ(clusters[0]->visits[1]->normalized_url,
-                  "https://google.com/");
-        EXPECT_FLOAT_EQ(clusters[0]->visits[1]->score, 0.66);
-
-        ASSERT_EQ(clusters[1]->visits.size(), 1u);
-        EXPECT_EQ(clusters[1]->visits[0]->normalized_url,
-                  "https://github.com/");
-        EXPECT_FLOAT_EQ(clusters[1]->visits[0]->score, 0.66);
-
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-
-  // This below block verifies the proto request sent to the remote endpoint.
-  {
-    EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-    absl::optional<base::Value> value =
-        base::JSONReader::Read(GetPendingRequestBody());
-    ASSERT_TRUE(value);
-    std::string* encoded = value->FindStringKey("data");
-    ASSERT_TRUE(encoded);
-
-    std::string decoded;
-    ASSERT_TRUE(base::Base64Decode(*encoded, &decoded));
-
-    proto::GetClustersRequest request;
-    ASSERT_TRUE(request.ParseFromString(decoded));
-
-    EXPECT_EQ(request.experiment_name(), experiment_name);
-    ASSERT_EQ(request.visits_size(), 2);
-    auto visit = request.visits().at(0);
-    EXPECT_EQ(visit.visit_id(), 2);
-    EXPECT_EQ(visit.navigation_time_ms(),
-              visit_2_time_.ToDeltaSinceWindowsEpoch().InMilliseconds());
-    EXPECT_EQ(visit.foreground_time_secs(), 20);
-    EXPECT_EQ(visit.url(), "https://github.com/");
-    EXPECT_EQ(visit.page_end_reason(), 5);
-    visit = request.visits().at(1);
-    EXPECT_EQ(visit.visit_id(), 1);
-    EXPECT_EQ(visit.navigation_time_ms(),
-              visit_1_time_.ToDeltaSinceWindowsEpoch().InMilliseconds());
-    EXPECT_EQ(visit.foreground_time_secs(), 5);
-    EXPECT_EQ(visit.url(), "https://google.com/");
-    EXPECT_EQ(visit.page_end_reason(), 3);
-    // TODO(tommycli): Add back visit.referring_visit_id() check after updating
-    //  the HistoryService test methods to support that field.
-  }
-
-  // This block sends a fake proto response back via the URL loader.
-  {
-    proto::GetClustersResponse response;
-
-    auto* cluster = response.add_clusters();
-    auto* visit = cluster->add_cluster_visits();
-    visit->set_visit_id(1);
-    visit->set_score(0.66);
-    visit = cluster->add_cluster_visits();
-    visit->set_visit_id(2);
-    visit->set_score(0.66);
-
-    cluster = response.add_clusters();
-    visit = cluster->add_cluster_visits();
-    visit->set_visit_id(2);
-    visit->set_score(0.66);
-
-    test_url_loader_factory_.AddResponse(kFakeEndpoint,
-                                         response.SerializeAsString());
-    EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  }
-
-  // Verify the callback is invoked.
-  run_loop_.Run();
-}
-
 TEST_F(HistoryClustersServiceTest, ClusterAndVisitSorting) {
   AddHardcodedTestDataToHistoryService();
 
@@ -462,8 +282,10 @@
                 EXPECT_EQ(cluster->visits[0]->normalized_url,
                           "https://github.com/");
                 EXPECT_EQ(cluster->visits[0]->raw_urls.size(), 1u);
-                EXPECT_EQ(cluster->visits[0]->last_visit_time, visit_2_time_);
-                EXPECT_EQ(cluster->visits[0]->first_visit_time, visit_2_time_);
+                EXPECT_EQ(cluster->visits[0]->last_visit_time,
+                          GetHardcodedTestVisits()[1].visit_row.visit_time);
+                EXPECT_EQ(cluster->visits[0]->first_visit_time,
+                          GetHardcodedTestVisits()[1].visit_row.visit_time);
                 EXPECT_EQ(cluster->visits[0]->page_title, "Github title");
                 EXPECT_FALSE(base::Contains(
                     cluster->visits[0]->annotations,
@@ -476,8 +298,10 @@
                 EXPECT_EQ(cluster->visits[1]->normalized_url,
                           "https://google.com/");
                 EXPECT_EQ(cluster->visits[1]->raw_urls.size(), 1u);
-                EXPECT_EQ(cluster->visits[1]->last_visit_time, visit_1_time_);
-                EXPECT_EQ(cluster->visits[1]->first_visit_time, visit_1_time_);
+                EXPECT_EQ(cluster->visits[1]->last_visit_time,
+                          GetHardcodedTestVisits()[0].visit_row.visit_time);
+                EXPECT_EQ(cluster->visits[1]->first_visit_time,
+                          GetHardcodedTestVisits()[0].visit_row.visit_time);
                 EXPECT_EQ(cluster->visits[1]->page_title, "Google title");
                 EXPECT_TRUE(base::Contains(
                     cluster->visits[1]->annotations,
@@ -500,8 +324,10 @@
                 EXPECT_EQ(cluster->visits[0]->normalized_url,
                           "https://github.com/");
                 EXPECT_EQ(cluster->visits[0]->raw_urls.size(), 1u);
-                EXPECT_EQ(cluster->visits[0]->last_visit_time, visit_2_time_);
-                EXPECT_EQ(cluster->visits[0]->first_visit_time, visit_2_time_);
+                EXPECT_EQ(cluster->visits[0]->last_visit_time,
+                          GetHardcodedTestVisits()[1].visit_row.visit_time);
+                EXPECT_EQ(cluster->visits[0]->first_visit_time,
+                          GetHardcodedTestVisits()[1].visit_row.visit_time);
                 EXPECT_EQ(cluster->visits[0]->page_title, "Github title");
                 EXPECT_TRUE(cluster->keywords.empty());
               }
@@ -534,146 +360,6 @@
   }
 }
 
-TEST_F(HistoryClustersServiceTest, Remote_QueryClustersWithEmptyVisits) {
-  EnableRemoteClusteringBackend();
-
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_TRUE(clusters.empty());
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  // Verify no request is made.
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Verify the callback is invoked.
-  run_loop_.Run();
-}
-
-TEST_F(HistoryClustersServiceTest, Remote_QueryClustersWithEmptyResponse) {
-  EnableRemoteClusteringBackend();
-  AddHardcodedTestDataToHistoryService();
-
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_TRUE(clusters.empty());
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  // Verify a request is made.
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Fake an empty but valid response from the endpoint.
-  test_url_loader_factory_.AddResponse(
-      kFakeEndpoint, proto::GetClustersResponse().SerializeAsString());
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Verify the callback is invoked.
-  run_loop_.Run();
-}
-
-TEST_F(HistoryClustersServiceTest,
-       Remote_QueryClustersWithInvalidJsonResponse) {
-  EnableRemoteClusteringBackend();
-  AddHardcodedTestDataToHistoryService();
-
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_TRUE(clusters.empty());
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  // Verify a request is made.
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Fake a junk response from the endpoint.
-  test_url_loader_factory_.AddResponse(kFakeEndpoint,
-                                       "{waka404woko.weke) !*(&,");
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Verify the callback is invoked.
-  run_loop_.Run();
-}
-
-TEST_F(HistoryClustersServiceTest, Remote_QueryClustersWithEmptyJsonResponse) {
-  EnableRemoteClusteringBackend();
-  AddHardcodedTestDataToHistoryService();
-
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_TRUE(clusters.empty());
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  // Verify a request is made.
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Fake an empty but valid response from the endpoint.
-  test_url_loader_factory_.AddResponse(
-      kFakeEndpoint, proto::GetClustersResponse().SerializeAsString());
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Verify the callback is invoked.
-  run_loop_.Run();
-}
-
-TEST_F(HistoryClustersServiceTest, Remote_QueryClustersWithPendingRequest) {
-  EnableRemoteClusteringBackend();
-  AddHardcodedTestDataToHistoryService();
-
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_EQ(clusters.size(), 2u);
-      }),
-      &task_tracker_);
-
-  // Verify there's a single request to the endpoint.
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
-
-  history_clusters_service_->QueryClusters(
-      /*query=*/"", /*max_time=*/base::Time::Now(), /* max_count=*/0,
-      base::BindLambdaForTesting([&](std::vector<mojom::ClusterPtr> clusters) {
-        EXPECT_EQ(clusters.size(), 2u);
-        run_loop_quit_.Run();
-      }),
-      &task_tracker_);
-
-  // Verify there are two requests to the endpoint.
-  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
-  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-  EXPECT_EQ(test_url_loader_factory_.NumPending(), 2);
-
-  // Fake a response from the endpoint with two clusters.
-  proto::GetClustersResponse response;
-  response.add_clusters();
-  response.add_clusters();
-  test_url_loader_factory_.AddResponse(kFakeEndpoint,
-                                       response.SerializeAsString());
-  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
-
-  // Verify both callbacks are invoked.
-  run_loop_.Run();
-}
-
 TEST_F(HistoryClustersServiceTest, CompleteVisitContextAnnotationsIfReady) {
   auto test = [&](RecordingStatus status, bool expected_complete) {
     auto& incomplete_visit_context_annotations =
diff --git a/components/history_clusters/core/remote_clustering_backend_unittest.cc b/components/history_clusters/core/remote_clustering_backend_unittest.cc
new file mode 100644
index 0000000..94e53b9
--- /dev/null
+++ b/components/history_clusters/core/remote_clustering_backend_unittest.cc
@@ -0,0 +1,315 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/history_clusters/core/history_clusters_service.h"
+
+#include <memory>
+#include <string>
+
+#include "base/base64.h"
+#include "base/json/json_reader.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/gtest_util.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
+#include "base/values.h"
+#include "components/history/core/browser/history_types.h"
+#include "components/history/core/browser/url_row.h"
+#include "components/history_clusters/core/history_clusters_service_test_api.h"
+#include "components/history_clusters/core/memories_features.h"
+#include "components/history_clusters/core/proto/clusters.pb.h"
+#include "components/history_clusters/core/remote_clustering_backend.h"
+#include "services/network/public/cpp/data_element.h"
+#include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace history_clusters {
+
+namespace {
+
+static constexpr char kFakeExperimentName[] = "FakeExperimentName";
+static constexpr char kFakeEndpoint[] = "https://endpoint.com/";
+
+class RemoteClusteringBackendTest : public testing::Test {
+ public:
+  RemoteClusteringBackendTest()
+      : task_environment_(
+            base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
+        shared_url_loader_factory_(
+            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+                &test_url_loader_factory_)),
+        run_loop_quit_(run_loop_.QuitClosure()) {
+    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
+    scoped_feature_list_->InitWithFeaturesAndParameters(
+        {
+            {
+                kMemories,
+                {
+                    {"MemoriesExperimentName", kFakeExperimentName},
+                },
+            },
+            {
+                kRemoteModelForDebugging,
+                {
+                    {"MemoriesRemoteModelEndpoint", kFakeEndpoint},
+                },
+            },
+        },
+        {});
+
+    remote_clustering_backend_ = std::make_unique<RemoteClusteringBackend>(
+        shared_url_loader_factory_, absl::nullopt);
+  }
+
+  RemoteClusteringBackendTest(const RemoteClusteringBackendTest&) = delete;
+  RemoteClusteringBackendTest& operator=(const RemoteClusteringBackendTest&) =
+      delete;
+
+  // Helper to get the most recent remote request body.
+  std::string GetPendingRequestBody() {
+    const scoped_refptr<network::ResourceRequestBody>& request_body =
+        test_url_loader_factory_.GetPendingRequest(0)->request.request_body;
+    const network::DataElement& element = (*request_body->elements())[0];
+    return std::string(element.As<network::DataElementBytes>().AsStringPiece());
+  }
+
+ protected:
+  base::test::TaskEnvironment task_environment_;
+
+  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
+
+  network::TestURLLoaderFactory test_url_loader_factory_;
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
+
+  std::unique_ptr<RemoteClusteringBackend> remote_clustering_backend_;
+
+  // Used to verify the async callback is invoked.
+  base::RunLoop run_loop_;
+  base::RepeatingClosure run_loop_quit_;
+};
+
+TEST_F(RemoteClusteringBackendTest, EndToEnd) {
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            ASSERT_EQ(clusters.size(), 2u);
+
+            ASSERT_EQ(clusters[0].scored_annotated_visits.size(), 2u);
+            EXPECT_EQ(clusters[0]
+                          .scored_annotated_visits[0]
+                          .annotated_visit.url_row.url(),
+                      "https://google.com/");
+            EXPECT_FLOAT_EQ(clusters[0].scored_annotated_visits[0].score, 0.66);
+            EXPECT_EQ(clusters[0]
+                          .scored_annotated_visits[1]
+                          .annotated_visit.url_row.url(),
+                      "https://github.com/");
+            EXPECT_FLOAT_EQ(clusters[0].scored_annotated_visits[1].score, 0.66);
+
+            ASSERT_EQ(clusters[1].scored_annotated_visits.size(), 1u);
+            EXPECT_EQ(clusters[1]
+                          .scored_annotated_visits[0]
+                          .annotated_visit.url_row.url(),
+                      "https://github.com/");
+            EXPECT_FLOAT_EQ(clusters[1].scored_annotated_visits[0].score, 0.66);
+
+            run_loop_quit_.Run();
+          }),
+      GetHardcodedTestVisits());
+
+  // This below block verifies the proto request sent to the remote endpoint.
+  {
+    EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+    absl::optional<base::Value> value =
+        base::JSONReader::Read(GetPendingRequestBody());
+    ASSERT_TRUE(value);
+    std::string* encoded = value->FindStringKey("data");
+    ASSERT_TRUE(encoded);
+
+    std::string decoded;
+    ASSERT_TRUE(base::Base64Decode(*encoded, &decoded));
+
+    proto::GetClustersRequest request;
+    ASSERT_TRUE(request.ParseFromString(decoded));
+
+    EXPECT_EQ(request.experiment_name(), kFakeExperimentName);
+    ASSERT_EQ(request.visits_size(), 2);
+
+    auto visit = request.visits().at(0);
+    EXPECT_EQ(visit.visit_id(), 1);
+    EXPECT_EQ(visit.navigation_time_ms(),
+              GetHardcodedTestVisits()[0]
+                  .visit_row.visit_time.ToDeltaSinceWindowsEpoch()
+                  .InMilliseconds());
+    EXPECT_EQ(visit.foreground_time_secs(), 5);
+    EXPECT_EQ(visit.url(), "https://google.com/");
+    EXPECT_EQ(visit.page_end_reason(), 3);
+
+    visit = request.visits().at(1);
+    EXPECT_EQ(visit.visit_id(), 2);
+    EXPECT_EQ(visit.navigation_time_ms(),
+              GetHardcodedTestVisits()[1]
+                  .visit_row.visit_time.ToDeltaSinceWindowsEpoch()
+                  .InMilliseconds());
+    EXPECT_EQ(visit.foreground_time_secs(), 20);
+    EXPECT_EQ(visit.url(), "https://github.com/");
+    EXPECT_EQ(visit.page_end_reason(), 5);
+    // TODO(tommycli): Add back visit.referring_visit_id() check after updating
+    //  the HistoryService test methods to support that field.
+  }
+
+  // This block sends a fake proto response back via the URL loader.
+  {
+    proto::GetClustersResponse response;
+
+    auto* cluster = response.add_clusters();
+    auto* visit = cluster->add_cluster_visits();
+    visit->set_visit_id(1);
+    visit->set_score(0.66);
+    visit = cluster->add_cluster_visits();
+    visit->set_visit_id(2);
+    visit->set_score(0.66);
+
+    cluster = response.add_clusters();
+    visit = cluster->add_cluster_visits();
+    visit->set_visit_id(2);
+    visit->set_score(0.66);
+
+    test_url_loader_factory_.AddResponse(kFakeEndpoint,
+                                         response.SerializeAsString());
+    EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  }
+
+  // Verify the callback is invoked.
+  run_loop_.Run();
+}
+
+TEST_F(RemoteClusteringBackendTest, EmptyVisitsRequest) {
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_TRUE(clusters.empty());
+            run_loop_quit_.Run();
+          }),
+      std::vector<history::AnnotatedVisit>());
+
+  // Verify no request is made.
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Verify the callback is invoked.
+  run_loop_.Run();
+}
+
+TEST_F(RemoteClusteringBackendTest, EmptyResponse) {
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_TRUE(clusters.empty());
+            run_loop_quit_.Run();
+          }),
+      GetHardcodedTestVisits());
+
+  // Verify a request is made.
+  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Fake an empty but valid response from the endpoint.
+  test_url_loader_factory_.AddResponse(
+      kFakeEndpoint, proto::GetClustersResponse().SerializeAsString());
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Verify the callback is invoked.
+  run_loop_.Run();
+}
+
+TEST_F(RemoteClusteringBackendTest, InvalidJsonResponse) {
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_TRUE(clusters.empty());
+            run_loop_quit_.Run();
+          }),
+      GetHardcodedTestVisits());
+
+  // Verify a request is made.
+  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Fake a junk response from the endpoint.
+  test_url_loader_factory_.AddResponse(kFakeEndpoint,
+                                       "{waka404woko.weke) !*(&,");
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Verify the callback is invoked.
+  run_loop_.Run();
+}
+
+TEST_F(RemoteClusteringBackendTest, EmptyJsonResponse) {
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_TRUE(clusters.empty());
+            run_loop_quit_.Run();
+          }),
+      GetHardcodedTestVisits());
+
+  // Verify a request is made.
+  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Fake an empty but valid response from the endpoint.
+  test_url_loader_factory_.AddResponse(
+      kFakeEndpoint, proto::GetClustersResponse().SerializeAsString());
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Verify the callback is invoked.
+  run_loop_.Run();
+}
+
+TEST_F(RemoteClusteringBackendTest, TwoSimultaneousRequests) {
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_EQ(clusters.size(), 2u);
+            // Don't quit the run loop. We want to use the second request's
+            // response as the complete-condition for this test.
+          }),
+      GetHardcodedTestVisits());
+
+  // Verify there's a single request to the endpoint.
+  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+  remote_clustering_backend_->GetClusters(
+      base::BindLambdaForTesting(
+          [&](const std::vector<history::Cluster>& clusters) {
+            EXPECT_EQ(clusters.size(), 2u);
+            run_loop_quit_.Run();
+          }),
+      GetHardcodedTestVisits());
+
+  // Verify there are two requests to the endpoint.
+  EXPECT_TRUE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 2);
+
+  // Fake a response from the endpoint with two clusters.
+  proto::GetClustersResponse response;
+  response.add_clusters();
+  response.add_clusters();
+  test_url_loader_factory_.AddResponse(kFakeEndpoint,
+                                       response.SerializeAsString());
+  EXPECT_FALSE(test_url_loader_factory_.IsPending(kFakeEndpoint));
+
+  // Verify both callbacks are invoked.
+  run_loop_.Run();
+}
+
+}  // namespace
+
+}  // namespace history_clusters
diff --git a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
index 68bc1b1..dd98d81 100644
--- a/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
+++ b/components/image_fetcher/ios/ios_image_data_fetcher_wrapper_unittest.mm
@@ -8,8 +8,8 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
-#include "base/stl_util.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/components/image_fetcher/ios/webp_decoder_unittest.mm b/components/image_fetcher/ios/webp_decoder_unittest.mm
index 5c1d798..3a5774d 100644
--- a/components/image_fetcher/ios/webp_decoder_unittest.mm
+++ b/components/image_fetcher/ios/webp_decoder_unittest.mm
@@ -13,12 +13,12 @@
 #include <memory>
 
 #include "base/base_paths.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/memory/ref_counted.h"
 #include "base/path_service.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index 756ecc1e..acd4f2c 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -930,7 +930,7 @@
 
   ListPrefUpdate list_value(pref_service_,
                             metrics::prefs::kMetricsFileMetricsMetadata);
-  if (list_value->empty())
+  if (list_value->GetList().empty())
     return false;
 
   base::Value::ListView mutable_list = list_value->GetList();
diff --git a/components/metrics/unsent_log_store.cc b/components/metrics/unsent_log_store.cc
index 92e493e..bc8139d 100644
--- a/components/metrics/unsent_log_store.cc
+++ b/components/metrics/unsent_log_store.cc
@@ -238,7 +238,7 @@
 }
 
 void UnsentLogStore::ReadLogsFromPrefList(const base::ListValue& list_value) {
-  if (list_value.empty()) {
+  if (list_value.GetList().empty()) {
     metrics_->RecordLogReadStatus(UnsentLogStoreMetrics::LIST_EMPTY);
     return;
   }
diff --git a/components/ntp_tiles/metrics.cc b/components/ntp_tiles/metrics.cc
index 198de53..736859f 100644
--- a/components/ntp_tiles/metrics.cc
+++ b/components/ntp_tiles/metrics.cc
@@ -34,12 +34,6 @@
 const char kTileTypeSuffixIconGray[] = "IconsGray";
 const char kTileTypeSuffixIconReal[] = "IconsReal";
 
-void LogUmaHistogramAge(const std::string& name, const base::TimeDelta& value) {
-  // Log the value in number of seconds.
-  base::UmaHistogramCustomCounts(name, value.InSeconds(), 5,
-                                 base::TimeDelta::FromDays(14).InSeconds(), 20);
-}
-
 std::string GetSourceHistogramName(TileSource source) {
   switch (source) {
     case TileSource::TOP_SITES:
@@ -92,16 +86,6 @@
                          source_name.c_str()),
       impression.index, kMaxNumTiles);
 
-  if (!impression.data_generation_time.is_null()) {
-    const base::TimeDelta age =
-        base::Time::Now() - impression.data_generation_time;
-    LogUmaHistogramAge("NewTabPage.SuggestionsImpressionAge", age);
-    LogUmaHistogramAge(
-        base::StringPrintf("NewTabPage.SuggestionsImpressionAge.%s",
-                           source_name.c_str()),
-        age);
-  }
-
   UMA_HISTOGRAM_ENUMERATION("NewTabPage.TileTitle",
                             static_cast<int>(impression.title_source),
                             kLastTitleSource + 1);
@@ -153,15 +137,6 @@
       base::StringPrintf("NewTabPage.MostVisited.%s", source_name.c_str()),
       impression.index, kMaxNumTiles);
 
-  if (!impression.data_generation_time.is_null()) {
-    const base::TimeDelta age =
-        base::Time::Now() - impression.data_generation_time;
-    LogUmaHistogramAge("NewTabPage.MostVisitedAge", age);
-    LogUmaHistogramAge(
-        base::StringPrintf("NewTabPage.MostVisitedAge.%s", source_name.c_str()),
-        age);
-  }
-
   const char* tile_type_suffix = GetTileTypeSuffix(impression.visual_type);
   if (tile_type_suffix) {
     base::UmaHistogramExactLinear(
diff --git a/components/ntp_tiles/metrics_unittest.cc b/components/ntp_tiles/metrics_unittest.cc
index ab860ef..12ff8e9 100644
--- a/components/ntp_tiles/metrics_unittest.cc
+++ b/components/ntp_tiles/metrics_unittest.cc
@@ -60,10 +60,6 @@
     impression_.icon_type = icon_type;
     return *this;
   }
-  Builder& WithDataGenerationTime(base::Time data_generation_time) {
-    impression_.data_generation_time = data_generation_time;
-    return *this;
-  }
   Builder& WithUrl(const GURL& url) {
     impression_.url_for_rappor = url;
     return *this;
@@ -222,30 +218,6 @@
                           base::Bucket(kInferredTitleSource, /*count=*/1)));
 }
 
-TEST(RecordTileImpressionTest, ShouldRecordAge) {
-  const base::TimeDelta kSuggestionAge = base::TimeDelta::FromMinutes(1);
-  const base::TimeDelta kBucketTolerance = base::TimeDelta::FromSeconds(20);
-  base::HistogramTester histogram_tester;
-  RecordTileImpression(
-      Builder()
-          .WithSource(TileSource::TOP_SITES)
-          .WithDataGenerationTime(base::Time::Now() - kSuggestionAge)
-          .Build());
-
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples("NewTabPage.SuggestionsImpressionAge"),
-      ElementsAre(
-          IsBucketBetween((kSuggestionAge - kBucketTolerance).InSeconds(),
-                          (kSuggestionAge + kBucketTolerance).InSeconds(),
-                          /*count=*/1)));
-  EXPECT_THAT(histogram_tester.GetAllSamples(
-                  "NewTabPage.SuggestionsImpressionAge.client"),
-              ElementsAre(IsBucketBetween(
-                  (kSuggestionAge - kBucketTolerance).InSeconds(),
-                  (kSuggestionAge + kBucketTolerance).InSeconds(),
-                  /*count=*/1)));
-}
-
 TEST(RecordTileImpressionTest, ShouldRecordUmaForIconType) {
   base::HistogramTester histogram_tester;
 
@@ -369,29 +341,6 @@
                           base::Bucket(kTitleTagTitleSource, /*count=*/3)));
 }
 
-TEST(RecordTileClickTest, ShouldRecordClickAge) {
-  const base::TimeDelta kSuggestionAge = base::TimeDelta::FromMinutes(1);
-  const base::TimeDelta kBucketTolerance = base::TimeDelta::FromSeconds(20);
-  base::HistogramTester histogram_tester;
-  RecordTileClick(
-      Builder()
-          .WithSource(TileSource::TOP_SITES)
-          .WithDataGenerationTime(base::Time::Now() - kSuggestionAge)
-          .Build());
-
-  EXPECT_THAT(histogram_tester.GetAllSamples("NewTabPage.MostVisitedAge"),
-              ElementsAre(IsBucketBetween(
-                  (kSuggestionAge - kBucketTolerance).InSeconds(),
-                  (kSuggestionAge + kBucketTolerance).InSeconds(),
-                  /*count=*/1)));
-  EXPECT_THAT(
-      histogram_tester.GetAllSamples("NewTabPage.MostVisitedAge.client"),
-      ElementsAre(
-          IsBucketBetween((kSuggestionAge - kBucketTolerance).InSeconds(),
-                          (kSuggestionAge + kBucketTolerance).InSeconds(),
-                          /*count=*/1)));
-}
-
 TEST(RecordTileClickTest, ShouldRecordClicksForIconType) {
   base::HistogramTester histogram_tester;
 
diff --git a/components/ntp_tiles/ntp_tile_impression.cc b/components/ntp_tiles/ntp_tile_impression.cc
index acf49a7..99401e5 100644
--- a/components/ntp_tiles/ntp_tile_impression.cc
+++ b/components/ntp_tiles/ntp_tile_impression.cc
@@ -12,7 +12,6 @@
                         /*title_source=*/TileTitleSource::UNKNOWN,
                         /*visual_type=*/TileVisualType::UNKNOWN_TILE_TYPE,
                         /*icon_type=*/favicon_base::IconType::kInvalid,
-                        /*data_generation_time=*/base::Time(),
                         /*url_for_rappor=*/GURL()) {}
 
 NTPTileImpression::NTPTileImpression(int index,
@@ -20,14 +19,12 @@
                                      TileTitleSource title_source,
                                      TileVisualType visual_type,
                                      favicon_base::IconType icon_type,
-                                     base::Time data_generation_time,
                                      const GURL& url_for_rappor)
     : index(index),
       source(source),
       title_source(title_source),
       visual_type(visual_type),
       icon_type(icon_type),
-      data_generation_time(data_generation_time),
       url_for_rappor(url_for_rappor) {}
 
 NTPTileImpression::~NTPTileImpression() {}
diff --git a/components/ntp_tiles/ntp_tile_impression.h b/components/ntp_tiles/ntp_tile_impression.h
index f7d00e79..7501a55 100644
--- a/components/ntp_tiles/ntp_tile_impression.h
+++ b/components/ntp_tiles/ntp_tile_impression.h
@@ -22,7 +22,6 @@
                     TileTitleSource title_source,
                     TileVisualType visual_type,
                     favicon_base::IconType icon_type,
-                    base::Time data_generation_time,
                     const GURL& url_for_rappor);
   ~NTPTileImpression();
 
@@ -32,10 +31,6 @@
   TileTitleSource title_source;
   TileVisualType visual_type;
   favicon_base::IconType icon_type;
-  // The timestamp representing when the tile data (e.g. URL) was generated
-  // originally, regardless of the impression timestamp or the time when it
-  // was fetched (for server-side suggestions).
-  base::Time data_generation_time;
   // URL the tile points to, formerly used to report Rappor metrics. Currently
   // completely ignored but this code remains to leave the ability to port to
   // UKM in the future.
diff --git a/components/offline_pages/core/auto_fetch.cc b/components/offline_pages/core/auto_fetch.cc
index c81308d..f02fce0b 100644
--- a/components/offline_pages/core/auto_fetch.cc
+++ b/components/offline_pages/core/auto_fetch.cc
@@ -13,6 +13,8 @@
 namespace auto_fetch {
 ClientIdMetadata::ClientIdMetadata() = default;
 ClientIdMetadata::ClientIdMetadata(const ClientIdMetadata&) = default;
+ClientIdMetadata& ClientIdMetadata::operator=(const ClientIdMetadata&) =
+    default;
 
 ClientId MakeClientId(const ClientIdMetadata& metadata) {
   // Here, the 'A' prefix is used so that future versions can easily change the
diff --git a/components/offline_pages/core/auto_fetch.h b/components/offline_pages/core/auto_fetch.h
index 791d070..f12ca23 100644
--- a/components/offline_pages/core/auto_fetch.h
+++ b/components/offline_pages/core/auto_fetch.h
@@ -18,6 +18,7 @@
 struct ClientIdMetadata {
   ClientIdMetadata();
   ClientIdMetadata(const ClientIdMetadata&);
+  ClientIdMetadata& operator=(const ClientIdMetadata&);
   explicit ClientIdMetadata(int android_tab_id)
       : android_tab_id(android_tab_id) {}
   // ID of the Android tab that initiated the request.
diff --git a/components/offline_pages/core/model/store_visuals_task.cc b/components/offline_pages/core/model/store_visuals_task.cc
index 94022b1..cfdf120f 100644
--- a/components/offline_pages/core/model/store_visuals_task.cc
+++ b/components/offline_pages/core/model/store_visuals_task.cc
@@ -44,7 +44,7 @@
       "UPDATE page_thumbnails SET expiration=?,thumbnail=? WHERE offline_id=?";
   sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kUpdateSql));
   statement.BindInt64(0, store_utils::ToDatabaseTime(expiration));
-  statement.BindBlob(1, thumbnail.data(), thumbnail.length());
+  statement.BindBlob(1, thumbnail);
   statement.BindInt64(2, offline_id);
   return statement.Run();
 }
@@ -57,7 +57,7 @@
       "UPDATE page_thumbnails SET expiration=?,favicon=? WHERE offline_id=?";
   sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kUpdateSql));
   statement.BindInt64(0, store_utils::ToDatabaseTime(expiration));
-  statement.BindBlob(1, favicon.data(), favicon.length());
+  statement.BindBlob(1, favicon);
   statement.BindInt64(2, offline_id);
   return statement.Run();
 }
diff --git a/components/offline_pages/core/offline_page_metadata_store_unittest.cc b/components/offline_pages/core/offline_page_metadata_store_unittest.cc
index f06a5535..a55248f4 100644
--- a/components/offline_pages/core/offline_page_metadata_store_unittest.cc
+++ b/components/offline_pages/core/offline_page_metadata_store_unittest.cc
@@ -491,7 +491,7 @@
       db->GetCachedStatement(SQL_FROM_HERE, kInsertVisualsSql));
   statement.BindInt64(0, visuals.offline_id);
   statement.BindInt64(1, store_utils::ToDatabaseTime(visuals.expiration));
-  statement.BindBlob(2, visuals.thumbnail.data(), visuals.thumbnail.size());
+  statement.BindBlob(2, visuals.thumbnail);
   return statement.Run();
 }
 
diff --git a/components/omnibox/browser/document_suggestions_service.cc b/components/omnibox/browser/document_suggestions_service.cc
index c1929d8..a71b91a 100644
--- a/components/omnibox/browser/document_suggestions_service.cc
+++ b/components/omnibox/browser/document_suggestions_service.cc
@@ -43,9 +43,13 @@
 //            searchApplicationId: "searchapplications/chrome",
 //            clientId: 6,
 //            languageCode: "|locale|",
+//            debugOptions: {
+//              optsParams: "enable_aso_search:|ASO enabled|"
+//            }
 //       }
 //     }
-std::string BuildDocumentSuggestionRequest(const std::u16string& query) {
+std::string BuildDocumentSuggestionRequest(const std::u16string& query,
+                                           bool enable_aso_search) {
   base::Value root(base::Value::Type::DICTIONARY);
   root.SetKey("query", base::Value(query));
   // The API supports pagination. We're always concerned with the first N
@@ -62,6 +66,11 @@
   request_options.SetKey("clientId", base::Value(chromeOmniboxClientId));
   request_options.SetKey("languageCode",
                          base::Value(base::i18n::GetConfiguredLocale()));
+  base::Value debug_options(base::Value::Type::DICTIONARY);
+  debug_options.SetStringKey(
+      "optsParams", base::StringPrintf("enable_aso_search:%s",
+                                       enable_aso_search ? "true" : "false"));
+  request_options.SetKey("debugOptions", std::move(debug_options));
   root.SetKey("requestOptions", std::move(request_options));
 
   std::string result;
@@ -121,7 +130,8 @@
   auto request = std::make_unique<network::ResourceRequest>();
   request->url = suggest_url;
   request->method = "POST";
-  std::string request_body = BuildDocumentSuggestionRequest(query);
+  std::string request_body = BuildDocumentSuggestionRequest(
+      query, base::FeatureList::IsEnabled(omnibox::kDocumentProviderAso));
   request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES;
   // It is expected that the user is signed in here. But we only care about
   // experiment IDs from the variations server, which do not require the
diff --git a/components/omnibox/browser/document_suggestions_service_unittest.cc b/components/omnibox/browser/document_suggestions_service_unittest.cc
index 81b3597..cd21fbd 100644
--- a/components/omnibox/browser/document_suggestions_service_unittest.cc
+++ b/components/omnibox/browser/document_suggestions_service_unittest.cc
@@ -5,13 +5,17 @@
 #include "components/omnibox/browser/document_suggestions_service.h"
 
 #include "base/bind.h"
+#include "base/json/json_reader.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece_forward.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "components/omnibox/common/omnibox_features.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/variations/net/variations_http_headers.h"
@@ -23,6 +27,7 @@
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -88,4 +93,49 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(DocumentSuggestionsServiceTest, AsoParamInRequest) {
+  auto expect_aso_param = [&](const std::string& expected_value,
+                              const network::ResourceRequest& request) {
+    base::StringPiece request_string(request.request_body->elements()
+                                         ->at(0)
+                                         .As<network::DataElementBytes>()
+                                         .AsStringPiece());
+    absl::optional<base::Value> request_value =
+        base::JSONReader::Read(request_string);
+    ASSERT_TRUE(request_value) << expected_value;
+    std::string* param =
+        request_value->FindStringPath("requestOptions.debugOptions.optsParams");
+    ASSERT_NE(param, nullptr) << expected_value;
+    EXPECT_EQ(*param, expected_value) << expected_value;
+  };
+
+  {
+    // ASO disabled.
+    base::test::ScopedFeatureList feature_list;
+    feature_list.InitAndEnableFeature(omnibox::kDocumentProviderAso);
+    test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
+        [&](const network::ResourceRequest& request) {
+          expect_aso_param("enable_aso_search:true", request);
+        }));
+    document_suggestions_service_->CreateDocumentSuggestionsRequest(
+        u"", false, base::BindOnce(OnDocumentSuggestionsLoaderAvailable),
+        base::BindOnce(OnURLLoadComplete));
+    base::RunLoop().RunUntilIdle();
+  }
+
+  {
+    // ASO enabled.
+    base::test::ScopedFeatureList feature_list;
+    feature_list.InitAndDisableFeature(omnibox::kDocumentProviderAso);
+    test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
+        [&](const network::ResourceRequest& request) {
+          expect_aso_param("enable_aso_search:false", request);
+        }));
+    document_suggestions_service_->CreateDocumentSuggestionsRequest(
+        u"", false, base::BindOnce(OnDocumentSuggestionsLoaderAvailable),
+        base::BindOnce(OnURLLoadComplete));
+    base::RunLoop().RunUntilIdle();
+  }
+}
+
 }  // namespace
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index cd37042..ffbb8cb8 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -44,12 +44,6 @@
 //     base::FEATURE_DISABLED_BY_DEFAULT;
 // #endif
 
-// Allows Omnibox to dynamically adjust number of offered suggestions to fill in
-// the space between Omnibox an the soft keyboard. The number of suggestions
-// shown will be no less than minimum for the platform (eg. 5 for Android).
-const base::Feature kAdaptiveSuggestionsCount{
-    "OmniboxAdaptiveSuggestionsCount", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Feature that enables the tab-switch suggestions corresponding to an open
 // tab, for a button or dedicated suggestion. Enabled by default on Desktop
 // and iOS.
@@ -78,18 +72,10 @@
 const base::Feature kDisplayTitleForCurrentUrl{
     "OmniboxDisplayTitleForCurrentUrl", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Feature used to fetch document suggestions.
-const base::Feature kDocumentProvider{"OmniboxDocumentProvider",
-                                      base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Feature used to allow users to remove suggestions from clipboard.
 const base::Feature kOmniboxRemoveSuggestionsFromClipboard{
     "OmniboxRemoveSuggestionsFromClipboard", enabled_by_default_android_only};
 
-// Feature to debounce drive requests from the document provider.
-const base::Feature kDebounceDocumentProvider{
-    "OmniboxDebounceDocumentProvider", base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Demotes the relevance scores when comparing suggestions based on the
 // suggestion's |AutocompleteMatchType| and the user's |PageClassification|.
 // This feature's main job is to contain the DemoteByType parameter.
@@ -223,6 +209,23 @@
 const base::Feature kBookmarkPaths{"OmniboxBookmarkPaths",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to fetch document suggestions.
+const base::Feature kDocumentProvider{"OmniboxDocumentProvider",
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
+// Feature to debounce drive requests from the document provider.
+const base::Feature kDebounceDocumentProvider{
+    "OmniboxDebounceDocumentProvider", base::FEATURE_DISABLED_BY_DEFAULT};
+// Feature to determine a value in the drive request indicating whether the
+// request should be served by the  ASO backend.
+const base::Feature kDocumentProviderAso{"OmniboxDocumentProviderAso",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Allows Omnibox to dynamically adjust number of offered suggestions to fill in
+// the space between Omnibox and the soft keyboard. The number of suggestions
+// shown will be no less than minimum for the platform (eg. 5 for Android).
+const base::Feature kAdaptiveSuggestionsCount{
+    "OmniboxAdaptiveSuggestionsCount", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // If enabled, clipboard suggestion will not show the clipboard content until
 // the user clicks the reveal button.
 const base::Feature kClipboardSuggestionContentHidden = {
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index f315b4ad..518f34f 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -17,9 +17,7 @@
 extern const base::Feature kImageSearchSuggestionThumbnail;
 extern const base::Feature kSearchProviderWarmUpOnFocus;
 extern const base::Feature kDisplayTitleForCurrentUrl;
-extern const base::Feature kDocumentProvider;
 extern const base::Feature kOmniboxRemoveSuggestionsFromClipboard;
-extern const base::Feature kDebounceDocumentProvider;
 
 // Flags that affect the "twiddle" step of AutocompleteResult, i.e. SortAndCull.
 // TODO(tommycli): There are more flags above that belong in this category.
@@ -56,10 +54,15 @@
 extern const base::Feature kDisableCGIParamMatching;
 extern const base::Feature kShortBookmarkSuggestions;
 extern const base::Feature kShortBookmarkSuggestionsByTotalInputLength;
+extern const base::Feature kBookmarkPaths;
+
+// Document provider
+extern const base::Feature kDocumentProvider;
+extern const base::Feature kDebounceDocumentProvider;
+extern const base::Feature kDocumentProviderAso;
 
 // Suggestions UI - these affect the UI or function of the suggestions popup.
 extern const base::Feature kAdaptiveSuggestionsCount;
-extern const base::Feature kBookmarkPaths;
 extern const base::Feature kClipboardSuggestionContentHidden;
 extern const base::Feature kCompactSuggestions;
 extern const base::Feature kMostVisitedTiles;
diff --git a/components/open_from_clipboard/clipboard_recent_content_ios.mm b/components/open_from_clipboard/clipboard_recent_content_ios.mm
index 7de70fd5..e77ad2c 100644
--- a/components/open_from_clipboard/clipboard_recent_content_ios.mm
+++ b/components/open_from_clipboard/clipboard_recent_content_ios.mm
@@ -9,9 +9,9 @@
 #include <stdint.h>
 #import <UIKit/UIKit.h>
 
+#include "base/cxx17_backports.h"
 #include "base/metrics/user_metrics.h"
 #include "base/notreached.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/system/sys_info.h"
 #include "base/threading/sequenced_task_runner_handle.h"
diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h
index c9e9d65..983f475 100644
--- a/components/page_info/page_info.h
+++ b/components/page_info/page_info.h
@@ -276,6 +276,8 @@
   // Exposed for testing.
   static std::vector<ContentSettingsType> GetAllPermissionsForTesting();
 
+  PageInfoUI* ui_for_testing() const { return ui_; }
+
  private:
   FRIEND_TEST_ALL_PREFIXES(PageInfoTest,
                            NonFactoryDefaultAndRecentlyChangedPermissionsShown);
diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc
index 82065d6..69a540d3 100644
--- a/components/page_info/page_info_ui.cc
+++ b/components/page_info/page_info_ui.cc
@@ -16,6 +16,7 @@
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/page_info/features.h"
 #include "components/page_info/page_info_ui_delegate.h"
+#include "components/permissions/features.h"
 #include "components/permissions/permission_manager.h"
 #include "components/permissions/permission_result.h"
 #include "components/permissions/permission_util.h"
@@ -244,6 +245,25 @@
   return effective_setting;
 }
 
+void SetTargetContentSetting(PageInfo::PermissionInfo& permission,
+                             ContentSetting target_setting) {
+  // If content setting's default setting matches target setting, set
+  // default setting to avoid crearing a site exception.
+  permission.setting = permission.default_setting == target_setting
+                           ? CONTENT_SETTING_DEFAULT
+                           : target_setting;
+}
+
+void CreateOppositeToDefaultSiteException(
+    PageInfo::PermissionInfo& permission,
+    ContentSetting opposite_to_block_setting) {
+  // For guard content settings opposite to block setting is ask, for the
+  // rest opposite is allow.
+  permission.setting = permission.default_setting == opposite_to_block_setting
+                           ? CONTENT_SETTING_BLOCK
+                           : opposite_to_block_setting;
+}
+
 }  // namespace
 
 PageInfoUI::CookieInfo::CookieInfo() : allowed(-1), blocked(-1) {}
@@ -489,23 +509,117 @@
 }
 
 // static
-std::u16string PageInfoUI::PermissionDecisionReasonToUIString(
+std::u16string PageInfoUI::PermissionStateToUIString(
     PageInfoUiDelegate* delegate,
     const PageInfo::PermissionInfo& permission) {
+  int message_id = kInvalidResourceID;
   ContentSetting effective_setting = GetEffectiveSetting(
       permission.type, permission.setting, permission.default_setting);
+  switch (effective_setting) {
+    case CONTENT_SETTING_ALLOW:
+#if !defined(OS_ANDROID)
+      if (permission.type == ContentSettingsType::SOUND &&
+          delegate->IsBlockAutoPlayEnabled() &&
+          permission.setting == CONTENT_SETTING_DEFAULT) {
+        message_id = IDS_PAGE_INFO_BUTTON_TEXT_AUTOMATIC_BY_DEFAULT;
+        break;
+      }
+#endif
+      if (permission.setting == CONTENT_SETTING_DEFAULT) {
+        message_id = IDS_PAGE_INFO_STATE_TEXT_ALLOWED_BY_DEFAULT;
+#if !defined(OS_ANDROID)
+      } else if (permission.is_one_time) {
+        DCHECK_EQ(permission.source, content_settings::SETTING_SOURCE_USER);
+        DCHECK(permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+            permission.type));
+        message_id = delegate->IsMultipleTabsOpen()
+                         ? IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_MULTIPLE_TAB
+                         : IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_ONE_TAB;
+#endif
+      } else {
+        message_id = IDS_PAGE_INFO_STATE_TEXT_ALLOWED;
+      }
+      break;
+    case CONTENT_SETTING_BLOCK:
+      if (permission.setting == CONTENT_SETTING_DEFAULT) {
+#if !defined(OS_ANDROID)
+        if (permission.type == ContentSettingsType::SOUND) {
+          message_id = IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_DEFAULT;
+          break;
+        }
+#endif
+        message_id = IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED_BY_DEFAULT;
+      } else {
+#if !defined(OS_ANDROID)
+        if (permission.type == ContentSettingsType::SOUND) {
+          message_id = IDS_PAGE_INFO_STATE_TEXT_MUTED;
+          break;
+        }
+#endif
+        message_id = IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED;
+      }
+      break;
+    case CONTENT_SETTING_ASK:
+      if (permissions::PermissionUtil::IsGuardContentSetting(permission.type)) {
+        message_id = permission.setting == CONTENT_SETTING_DEFAULT
+                         ? IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT
+                         : IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER;
+      } else if (permission.setting == CONTENT_SETTING_DEFAULT) {
+        // TODO(crbug.com/1225563): Replace with actual strings.
+        return u"This site will ask before accessing";
+      } else {
+        message_id = IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED;
+      }
+      break;
+    default:
+      NOTREACHED();
+  }
+
+  return l10n_util::GetStringUTF16(message_id);
+}
+
+// static
+std::u16string PageInfoUI::PermissionMainPageStateToUIString(
+    PageInfoUiDelegate* delegate,
+    const PageInfo::PermissionInfo& permission) {
+  std::u16string auto_blocked_text =
+      PermissionAutoBlockedToUIString(delegate, permission);
+  if (!auto_blocked_text.empty())
+    return auto_blocked_text;
+
+  if (permission.is_one_time || permission.setting == CONTENT_SETTING_DEFAULT) {
+    return PermissionStateToUIString(delegate, permission);
+  }
+
+  return std::u16string();
+}
+
+// static
+std::u16string PageInfoUI::PermissionManagedTooltipToUIString(
+    PageInfoUiDelegate* delegate,
+    const PageInfo::PermissionInfo& permission) {
   int message_id = kInvalidResourceID;
   switch (permission.source) {
     case content_settings::SettingSource::SETTING_SOURCE_POLICY:
-      message_id = kPermissionButtonTextIDPolicyManaged[effective_setting];
+      message_id = IDS_PAGE_INFO_PERMISSION_MANAGED_BY_POLICY;
       break;
     case content_settings::SettingSource::SETTING_SOURCE_EXTENSION:
-      message_id = kPermissionButtonTextIDExtensionManaged[effective_setting];
+      message_id = IDS_PAGE_INFO_PERMISSION_MANAGED_BY_EXTENSION;
       break;
     default:
       break;
   }
 
+  if (message_id == kInvalidResourceID)
+    return std::u16string();
+  return l10n_util::GetStringUTF16(message_id);
+}
+
+// static
+std::u16string PageInfoUI::PermissionAutoBlockedToUIString(
+    PageInfoUiDelegate* delegate,
+    const PageInfo::PermissionInfo& permission) {
+  int message_id = kInvalidResourceID;
   // TODO(crbug.com/1063023): PageInfo::PermissionInfo should be modified
   // to contain all needed information regarding Automatically Blocked flag.
   if (permission.setting == CONTENT_SETTING_BLOCK &&
@@ -523,9 +637,32 @@
         break;
     }
   }
+  if (message_id == kInvalidResourceID)
+    return std::u16string();
+  return l10n_util::GetStringUTF16(message_id);
+}
 
-  if (permission.type == ContentSettingsType::ADS)
-    message_id = IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE;
+// static
+std::u16string PageInfoUI::PermissionDecisionReasonToUIString(
+    PageInfoUiDelegate* delegate,
+    const PageInfo::PermissionInfo& permission) {
+  ContentSetting effective_setting = GetEffectiveSetting(
+      permission.type, permission.setting, permission.default_setting);
+  int message_id = kInvalidResourceID;
+  switch (permission.source) {
+    case content_settings::SettingSource::SETTING_SOURCE_POLICY:
+      message_id = kPermissionButtonTextIDPolicyManaged[effective_setting];
+      break;
+    case content_settings::SettingSource::SETTING_SOURCE_EXTENSION:
+      message_id = kPermissionButtonTextIDExtensionManaged[effective_setting];
+      break;
+    default:
+      break;
+  }
+
+  auto auto_block_text = PermissionAutoBlockedToUIString(delegate, permission);
+  if (!auto_block_text.empty())
+    return auto_block_text;
 
   if (message_id == kInvalidResourceID)
     return std::u16string();
@@ -533,6 +670,96 @@
 }
 
 // static
+void PageInfoUI::ToggleBetweenAllowAndBlock(
+    PageInfo::PermissionInfo& permission) {
+  auto opposite_to_block_setting =
+      permissions::PermissionUtil::IsGuardContentSetting(permission.type)
+          ? CONTENT_SETTING_ASK
+          : CONTENT_SETTING_ALLOW;
+  switch (permission.setting) {
+    case CONTENT_SETTING_ALLOW:
+      DCHECK_EQ(opposite_to_block_setting, CONTENT_SETTING_ALLOW);
+      if (permission.is_one_time) {
+        permission.setting = CONTENT_SETTING_DEFAULT;
+      } else {
+        SetTargetContentSetting(permission, CONTENT_SETTING_BLOCK);
+      }
+      permission.is_one_time = false;
+      break;
+    case CONTENT_SETTING_BLOCK:
+      SetTargetContentSetting(permission, opposite_to_block_setting);
+      permission.is_one_time = false;
+      break;
+    case CONTENT_SETTING_DEFAULT: {
+      CreateOppositeToDefaultSiteException(permission,
+                                           opposite_to_block_setting);
+      // If one-time permissions are supported, permission should go from
+      // default state to allow once state, not directly to allow.
+      if (permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+              permission.type)) {
+        permission.is_one_time = true;
+      }
+      break;
+    }
+    case CONTENT_SETTING_ASK:
+      DCHECK_EQ(opposite_to_block_setting, CONTENT_SETTING_ASK);
+      SetTargetContentSetting(permission, CONTENT_SETTING_BLOCK);
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+// static
+void PageInfoUI::ToggleBetweenRememberAndForget(
+    PageInfo::PermissionInfo& permission) {
+  DCHECK(permissions::PermissionUtil::IsPermission(permission.type));
+  switch (permission.setting) {
+    case CONTENT_SETTING_ALLOW: {
+      // If one-time permissions are supported, toggle is_one_time.
+      // Otherwise, go directly to default.
+      if (permissions::PermissionUtil::CanPermissionBeAllowedOnce(
+              permission.type)) {
+        permission.is_one_time = !permission.is_one_time;
+      } else {
+        permission.setting = CONTENT_SETTING_DEFAULT;
+      }
+      break;
+    }
+    case CONTENT_SETTING_BLOCK:
+      // TODO(olesiamarukhno): If content setting is in the blocklist, setting
+      // it to default, doesn't do anything. Fix this before introducing
+      // subpages for content settings (not permissions).
+      permission.setting = CONTENT_SETTING_DEFAULT;
+      permission.is_one_time = false;
+      break;
+    case CONTENT_SETTING_DEFAULT:
+      // When user checks the checkbox to remember the permission setting,
+      // it should go to the "allow" state, only if default setting is
+      // explicitly allow.
+      if (permission.default_setting == CONTENT_SETTING_ALLOW) {
+        permission.setting = CONTENT_SETTING_ALLOW;
+      } else {
+        permission.setting = CONTENT_SETTING_BLOCK;
+      }
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+// static
+bool PageInfoUI::IsToggleOn(const PageInfo::PermissionInfo& permission) {
+  ContentSetting effective_setting = GetEffectiveSetting(
+      permission.type, permission.setting, permission.default_setting);
+  return permissions::PermissionUtil::IsGuardContentSetting(permission.type)
+             ? effective_setting == CONTENT_SETTING_ASK
+             : effective_setting == CONTENT_SETTING_ALLOW;
+}
+
+// static
 SkColor PageInfoUI::GetSecondaryTextColor() {
   return SK_ColorGRAY;
 }
diff --git a/components/page_info/page_info_ui.h b/components/page_info/page_info_ui.h
index 05e02323..90d0e0b 100644
--- a/components/page_info/page_info_ui.h
+++ b/components/page_info/page_info_ui.h
@@ -179,6 +179,29 @@
       PageInfoUiDelegate* delegate,
       const PageInfo::PermissionInfo& permission);
 
+  static std::u16string PermissionStateToUIString(
+      PageInfoUiDelegate* delegate,
+      const PageInfo::PermissionInfo& permission);
+
+  static std::u16string PermissionMainPageStateToUIString(
+      PageInfoUiDelegate* delegate,
+      const PageInfo::PermissionInfo& permission);
+
+  static std::u16string PermissionManagedTooltipToUIString(
+      PageInfoUiDelegate* delegate,
+      const PageInfo::PermissionInfo& permission);
+
+  static std::u16string PermissionAutoBlockedToUIString(
+      PageInfoUiDelegate* delegate,
+      const PageInfo::PermissionInfo& permission);
+
+  static void ToggleBetweenAllowAndBlock(PageInfo::PermissionInfo& permission);
+
+  static void ToggleBetweenRememberAndForget(
+      PageInfo::PermissionInfo& permission);
+
+  static bool IsToggleOn(const PageInfo::PermissionInfo& permission);
+
   // Returns the color to use for the permission decision reason strings.
   static SkColor GetSecondaryTextColor();
 
diff --git a/components/page_info/page_info_ui_delegate.h b/components/page_info/page_info_ui_delegate.h
index 6dd91870..bc257c8 100644
--- a/components/page_info/page_info_ui_delegate.h
+++ b/components/page_info/page_info_ui_delegate.h
@@ -14,6 +14,7 @@
   virtual ~PageInfoUiDelegate() = default;
 #if !defined(OS_ANDROID)
   virtual bool IsBlockAutoPlayEnabled() = 0;
+  virtual bool IsMultipleTabsOpen() = 0;
 #endif
   virtual permissions::PermissionResult GetPermissionStatus(
       ContentSettingsType type) = 0;
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp
index c06f686..6ab2378 100644
--- a/components/page_info_strings.grdp
+++ b/components/page_info_strings.grdp
@@ -404,9 +404,11 @@
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to block by the user.">
       Block
     </message>
+    <if expr="not is_android">
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the button controls the sound permission and was explicitly set to mute by the user.">
       Mute
     </message>
+    </if>
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_USER" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button was explicitly set to ask by the user.">
       Ask
     </message>
@@ -417,18 +419,20 @@
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_ALLOWED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is allow.">
       Allow (default)
     </message>
-    <message name="IDS_PAGE_INFO_BUTTON_TEXT_AUTOMATIC_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the button controls the sound permission and is set to the default setting and the default setting is automatic.">
-      Automatic (default)
-    </message>
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_BLOCKED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is block.">
       Block (default)
     </message>
-    <message name="IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the button controls the sound permission and is set to the default setting and the default setting is mute.">
-      Mute (default)
-    </message>
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_ASK_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is ask.">
       Ask (default)
     </message>
+    <if expr="not is_android">
+    <message name="IDS_PAGE_INFO_BUTTON_TEXT_AUTOMATIC_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the button controls the sound permission and is set to the default setting and the default setting is automatic.">
+      Automatic (default)
+    </message>
+    <message name="IDS_PAGE_INFO_BUTTON_TEXT_MUTED_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the button controls the sound permission and is set to the default setting and the default setting is mute.">
+      Mute (default)
+    </message>
+    </if>
     <message name="IDS_PAGE_INFO_BUTTON_TEXT_DETECT_IMPORTANT_CONTENT_BY_DEFAULT" desc="The Page Info popup contains several buttons for opening dropdown menus and changing site permissions. This is the text of such a button if the permission controlled by the button is set to the default setting and the default settings is detect important content.">
       Detect (default)
     </message>
@@ -462,6 +466,29 @@
       Block on this site
     </message>
 
+    <message name="IDS_PAGE_INFO_STATE_TEXT_ALLOWED" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission is allowed by any source (the user, the administrator, etc.).">
+      Allowed
+    </message>
+    <message name="IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_ONE_TAB" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission is allowed once by any source (the user, the administrator, etc.) and there is only one tab opened for the site.">
+      Allowed until you close this tab
+    </message>
+    <message name="IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_MULTIPLE_TAB" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission is allowed once by any source (the user, the administrator, etc.) and there are nultiple tabs opened for the site.">
+      Allowed until you close tabs for this site
+    </message>
+    <message name="IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission is not allowed (blocked or ask state) by any source (the user, the administrator, etc.).">
+      Not allowed
+    </message>
+    <message name="IDS_PAGE_INFO_STATE_TEXT_MUTED" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the sound permission is blocked by any source (the user, the administrator, etc.).">
+      Muted
+    </message>
+
+    <message name="IDS_PAGE_INFO_STATE_TEXT_ALLOWED_BY_DEFAULT" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission controlled is set to the default setting and the default settings is allow.">
+      Allowed (default)
+    </message>
+    <message name="IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED_BY_DEFAULT" desc="The Page Info permission subpage and the main page info page contain a label which shows the state of the site permission. This is the text shown if the permission is set to the default setting and the default settings is block.">
+      Not allowed (default)
+    </message>
+
     <message name="IDS_PAGE_INFO_SELECTOR_TOOLTIP" desc="The text of the tooltip on the page info selector.">
       Select permission for <ph name="PERMISSION_NAME">$1<ex>Location</ex></ph>
     </message>
@@ -531,6 +558,12 @@
     <message name="IDS_PAGE_INFO_PERMISSION_ADS_SUBTITLE" desc="A subtitle shown under the ‘Ads’ setting indicating that a site has, in the past, shown intrusive or misleading ads. Shown when user clicks/taps the lock/'Danger' icon in the address bar. Used on both desktop and Android platforms" formatter_data="android_java">
       Site shows intrusive or misleading ads
     </message>
+    <message name="IDS_PAGE_INFO_PERMISSION_MANAGED_BY_POLICY" desc="The label used in the toolip for a permission listed in the Page Info bubble if the permission was explicitly set by the user's enterprise policy.">
+      Managed by your organisation
+    </message>
+    <message name="IDS_PAGE_INFO_PERMISSION_MANAGED_BY_EXTENSION" desc="The label used in the toolip for a permission listed in the Page Info bubble if the permission was explicitly set by one of the user's extensions.">
+      Managed by an extension
+    </message>
 
     <!-- Permission change infobar. -->
     <if expr="not is_android">
@@ -696,4 +729,7 @@
   <message name="IDS_PAGE_INFO_PERMISSIONS_SUBPAGE_REMEMBER_THIS_SETTING" desc="The text near the checkbox, that controls if user's decision will be remembered for this permission, in permission's subpage in page info bubble.">
     Remember this setting
   </message>
+  <message name="IDS_PAGE_INFO_RESET_PERMISSIONS" desc="The label of the button to reset permissions for a site.">
+    {NUM_PERMISSIONS, plural, =1 {Reset permission} other {Reset permissions}}
+  </message>
 </grit-part>
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_EXTENSION.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_EXTENSION.png.sha1
new file mode 100644
index 0000000..365dc52
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_EXTENSION.png.sha1
@@ -0,0 +1 @@
+682c3fabac5ea231146bb145891bba3e8f12e61a
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_POLICY.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_POLICY.png.sha1
new file mode 100644
index 0000000..929fb08d
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_PERMISSION_MANAGED_BY_POLICY.png.sha1
@@ -0,0 +1 @@
+632c80e4474b8d4ac1ce4de2950620efc2f7a73f
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_RESET_PERMISSIONS.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_RESET_PERMISSIONS.png.sha1
new file mode 100644
index 0000000..0fcc146
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_RESET_PERMISSIONS.png.sha1
@@ -0,0 +1 @@
+b06a834b136e72513db0e1800964882f11cc501a
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED.png.sha1
new file mode 100644
index 0000000..7761df9
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED.png.sha1
@@ -0,0 +1 @@
+6200f6ee6715354fb1a577804a89bbf980a8a903
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_BY_DEFAULT.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_BY_DEFAULT.png.sha1
new file mode 100644
index 0000000..1a8b845
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_BY_DEFAULT.png.sha1
@@ -0,0 +1 @@
+659bae41b1485f51a85728b48bfd9cf97a430d03
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_MULTIPLE_TAB.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_MULTIPLE_TAB.png.sha1
new file mode 100644
index 0000000..2bc7a04
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_MULTIPLE_TAB.png.sha1
@@ -0,0 +1 @@
+75a6b7c99d1f70d1768c2b98032918a955491798
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_ONE_TAB.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_ONE_TAB.png.sha1
new file mode 100644
index 0000000..dfd0fb6
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_ALLOWED_ONCE_ONE_TAB.png.sha1
@@ -0,0 +1 @@
+a90caed6175691be713d887c5ec41329e6950b5b
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_AUTOMATIC.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_AUTOMATIC.png.sha1
new file mode 100644
index 0000000..6164b777
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_AUTOMATIC.png.sha1
@@ -0,0 +1 @@
+75686d7cb2a8cd7e04a0dcd3ce029e7d5f77e2eb
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_MUTED.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_MUTED.png.sha1
new file mode 100644
index 0000000..9ba4408
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_MUTED.png.sha1
@@ -0,0 +1 @@
+f9cc046e9f21e2125f5ae97c0f9ceeca290bcb66
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED.png.sha1
new file mode 100644
index 0000000..177fd076
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED.png.sha1
@@ -0,0 +1 @@
+b3dddb34b30a4a9c2f332c185df40259707de386
\ No newline at end of file
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED_BY_DEFAULT.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED_BY_DEFAULT.png.sha1
new file mode 100644
index 0000000..bae2fd5f
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_STATE_TEXT_NOT_ALLOWED_BY_DEFAULT.png.sha1
@@ -0,0 +1 @@
+22fc83eeb8c7a976425cf89addc615d64daf786c
\ No newline at end of file
diff --git a/components/page_load_metrics/browser/observers/core/uma_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/core/uma_page_load_metrics_observer.cc
index bfbd3cf..aa0ed8ee 100644
--- a/components/page_load_metrics/browser/observers/core/uma_page_load_metrics_observer.cc
+++ b/components/page_load_metrics/browser/observers/core/uma_page_load_metrics_observer.cc
@@ -523,6 +523,7 @@
 
 void UmaPageLoadMetricsObserver::OnFirstContentfulPaintInPage(
     const page_load_metrics::mojom::PageLoadTiming& timing) {
+  DCHECK(timing.paint_timing->first_contentful_paint);
   if (page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
           timing.paint_timing->first_contentful_paint, GetDelegate())) {
     PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstContentfulPaint,
@@ -537,7 +538,7 @@
 
     // Emit a trace event to highlight a long navigation to first contentful
     // paint.
-    if (timing.paint_timing->first_contentful_paint >
+    if (timing.paint_timing->first_contentful_paint.value() >
         kFirstContentfulPaintTraceThreshold) {
       base::TimeTicks navigation_start = GetDelegate().GetNavigationStart();
       TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
diff --git a/components/page_load_metrics/common/page_load_metrics_util.cc b/components/page_load_metrics/common/page_load_metrics_util.cc
index 52431f6..a15ed60 100644
--- a/components/page_load_metrics/common/page_load_metrics_util.cc
+++ b/components/page_load_metrics/common/page_load_metrics_util.cc
@@ -15,8 +15,12 @@
 
 namespace {
 
-// Default timer delay value. Can be overridden by field trial.
-const int kDefaultBufferTimerDelayMillis = 1000;
+// Default timer delay when the PageLoadMetricsTimerDelay feature is disabled.
+const int kDefaultDisabledBufferTimerDelayMillis = 1000;
+
+// Default timer delay when the PageLoadMetricsTimerDelay feature is enabled.
+// Can be overridden by the BufferTimerDelayMillis field trial parameter.
+const int kDefaultEnabledBufferTimerDelayMillis = 100;
 
 // Maximum timer delay value.
 const int kMaxBufferTimerDelayMillis = 1000;
@@ -83,9 +87,13 @@
 }
 
 int GetBufferTimerDelayMillis(TimerType timer_type) {
-  int result = base::GetFieldTrialParamByFeatureAsInt(
-      kPageLoadMetricsTimerDelayFeature, kBufferTimerDelayParamName,
-      kDefaultBufferTimerDelayMillis /* default value */);
+  int result = kDefaultDisabledBufferTimerDelayMillis;
+
+  if (base::FeatureList::IsEnabled(kPageLoadMetricsTimerDelayFeature)) {
+    result = base::GetFieldTrialParamByFeatureAsInt(
+        kPageLoadMetricsTimerDelayFeature, kBufferTimerDelayParamName,
+        kDefaultEnabledBufferTimerDelayMillis /* default value */);
+  }
 
   DCHECK(timer_type == TimerType::kBrowser ||
          timer_type == TimerType::kRenderer);
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index 2598d2c..887e6fb 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -105,6 +105,8 @@
     "import/password_importer.h",
     "insecure_credentials_consumer.cc",
     "insecure_credentials_consumer.h",
+    "insecure_credentials_helper.cc",
+    "insecure_credentials_helper.h",
     "insecure_credentials_table.cc",
     "insecure_credentials_table.h",
     "leak_detection_delegate.cc",
@@ -646,6 +648,7 @@
     "http_auth_manager_unittest.cc",
     "http_password_store_migrator_unittest.cc",
     "import/password_importer_unittest.cc",
+    "insecure_credentials_helper_unittest.cc",
     "insecure_credentials_table_unittest.cc",
     "leak_detection_delegate_helper_unittest.cc",
     "leak_detection_delegate_unittest.cc",
diff --git a/components/password_manager/core/browser/insecure_credentials_helper.cc b/components/password_manager/core/browser/insecure_credentials_helper.cc
new file mode 100644
index 0000000..4623c68
--- /dev/null
+++ b/components/password_manager/core/browser/insecure_credentials_helper.cc
@@ -0,0 +1,129 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/insecure_credentials_helper.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_reuse_detector.h"
+#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "components/password_manager/core/browser/password_store_interface.h"
+
+namespace password_manager {
+
+namespace {
+
+// Helper object which is used to update `PasswordForm::password_issues` for the
+// affected credentials.
+class InsecureCredentialsHelper : public PasswordStoreConsumer {
+ public:
+  explicit InsecureCredentialsHelper(PasswordStoreInterface* store);
+  ~InsecureCredentialsHelper() override;
+
+  void AddPhishedCredentials(const MatchingReusedCredential& credential);
+
+  void RemovePhishedCredentials(const MatchingReusedCredential& credential);
+
+ private:
+  using LoginsResult = std::vector<std::unique_ptr<PasswordForm>>;
+
+  // PasswordStoreConsumer:
+  void OnGetPasswordStoreResults(LoginsResult results) override;
+
+  void AddPhishedCredentialsInternal(const MatchingReusedCredential& credential,
+                                     LoginsResult results);
+
+  void RemovePhishedCredentialsInternal(
+      const MatchingReusedCredential& credential,
+      LoginsResult results);
+
+  base::OnceCallback<void(LoginsResult)> operation_;
+
+  PasswordStoreInterface* store_;
+};
+
+InsecureCredentialsHelper::InsecureCredentialsHelper(
+    PasswordStoreInterface* store)
+    : store_(store) {}
+
+InsecureCredentialsHelper::~InsecureCredentialsHelper() = default;
+
+void InsecureCredentialsHelper::AddPhishedCredentials(
+    const MatchingReusedCredential& credential) {
+  PasswordFormDigest digest = {PasswordForm::Scheme::kHtml,
+                               credential.signon_realm,
+                               GURL(credential.signon_realm)};
+  store_->GetLogins(digest, this);
+  operation_ =
+      base::BindOnce(&InsecureCredentialsHelper::AddPhishedCredentialsInternal,
+                     base::Owned(this), credential);
+}
+
+void InsecureCredentialsHelper::RemovePhishedCredentials(
+    const MatchingReusedCredential& credential) {
+  PasswordFormDigest digest = {PasswordForm::Scheme::kHtml,
+                               credential.signon_realm,
+                               GURL(credential.signon_realm)};
+  store_->GetLogins(digest, this);
+  operation_ = base::BindOnce(
+      &InsecureCredentialsHelper::RemovePhishedCredentialsInternal,
+      base::Owned(this), credential);
+}
+
+void InsecureCredentialsHelper::OnGetPasswordStoreResults(
+    LoginsResult results) {
+  std::move(operation_).Run(std::move(results));
+}
+
+void InsecureCredentialsHelper::AddPhishedCredentialsInternal(
+    const MatchingReusedCredential& credential,
+    LoginsResult results) {
+  for (auto& form : results) {
+    if (form->username_value == credential.username) {
+      DCHECK(form->password_issues.has_value());
+      if (form->password_issues->find(InsecureType::kPhished) ==
+          form->password_issues->end()) {
+        form->password_issues->insert(
+            {InsecureType::kPhished,
+             InsecurityMetadata(base::Time::Now(), IsMuted(false))});
+        store_->UpdateLogin(*form);
+      }
+    }
+  }
+}
+
+void InsecureCredentialsHelper::RemovePhishedCredentialsInternal(
+    const MatchingReusedCredential& credential,
+    LoginsResult results) {
+  for (auto& form : results) {
+    if (form->username_value == credential.username) {
+      DCHECK(form->password_issues.has_value());
+      if (form->password_issues->find(InsecureType::kPhished) !=
+          form->password_issues->end()) {
+        form->password_issues->erase(InsecureType::kPhished);
+        store_->UpdateLogin(*form);
+      }
+    }
+  }
+}
+
+}  // namespace
+
+void AddPhishedCredentials(PasswordStoreInterface* store,
+                           const MatchingReusedCredential& credential) {
+  InsecureCredentialsHelper* helper = new InsecureCredentialsHelper(store);
+  helper->AddPhishedCredentials(credential);
+}
+
+void RemovePhishedCredentials(PasswordStoreInterface* store,
+                              const MatchingReusedCredential& credential) {
+  InsecureCredentialsHelper* helper = new InsecureCredentialsHelper(store);
+  helper->RemovePhishedCredentials(credential);
+}
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/insecure_credentials_helper.h b/components/password_manager/core/browser/insecure_credentials_helper.h
new file mode 100644
index 0000000..9d80d839
--- /dev/null
+++ b/components/password_manager/core/browser/insecure_credentials_helper.h
@@ -0,0 +1,25 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_INSECURE_CREDENTIALS_HELPER_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_INSECURE_CREDENTIALS_HELPER_H_
+
+namespace password_manager {
+
+class PasswordStoreInterface;
+struct MatchingReusedCredential;
+
+// Adds PhishedCredentials for matching PasswordForms from the |store| if it was
+// not marked as phished already.
+void AddPhishedCredentials(PasswordStoreInterface* store,
+                           const MatchingReusedCredential& credential);
+
+// Removes PhishedCredentials for matching PasswordForms from the |store| if it
+// was marked as phished.
+void RemovePhishedCredentials(PasswordStoreInterface* store,
+                              const MatchingReusedCredential& credential);
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_INSECURE_CREDENTIALS_HELPER_H_
diff --git a/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc b/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc
new file mode 100644
index 0000000..0bd194f3
--- /dev/null
+++ b/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc
@@ -0,0 +1,182 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/insecure_credentials_helper.h"
+
+#include "base/callback.h"
+#include "base/test/task_environment.h"
+
+#include "components/password_manager/core/browser/mock_password_store_interface.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_manager_test_utils.h"
+#include "components/password_manager/core/browser/password_store_consumer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace password_manager {
+
+namespace {
+
+using ::testing::_;
+
+// Creates a form.
+PasswordForm CreateForm(base::StringPiece signon_realm,
+                        base::StringPiece16 username,
+                        base::StringPiece16 password = base::StringPiece16()) {
+  PasswordForm form;
+  form.signon_realm = std::string(signon_realm);
+  form.username_value = std::u16string(username);
+  form.password_value = std::u16string(password);
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  return form;
+}
+
+MatchingReusedCredential MakeCredential(base::StringPiece signon_realm,
+                                        base::StringPiece16 username) {
+  MatchingReusedCredential credential;
+  credential.signon_realm = std::string(signon_realm);
+  credential.username = std::u16string(username);
+  return credential;
+}
+
+}  // namespace
+
+class InsecureCredentialsHelperTest : public testing::Test {
+ public:
+  InsecureCredentialsHelperTest()
+      : store_(base::MakeRefCounted<MockPasswordStoreInterface>()) {}
+
+  MockPasswordStoreInterface* store() { return store_.get(); }
+
+  void ExpectGetLogins(const std::string& signon_realm) {
+    PasswordFormDigest digest = {PasswordForm::Scheme::kHtml, signon_realm,
+                                 GURL(signon_realm)};
+
+    EXPECT_CALL(*store_, GetLogins(digest, _))
+        .WillOnce(testing::WithArg<1>(
+            [this](PasswordStoreConsumer* consumer) { consumer_ = consumer; }));
+  }
+
+  void SimulateStoreRepliedWithResults(
+      const std::vector<PasswordForm>& password_forms) {
+    std::vector<std::unique_ptr<PasswordForm>> results;
+    for (auto& form : password_forms)
+      results.push_back(std::make_unique<PasswordForm>(std::move(form)));
+    consumer_->OnGetPasswordStoreResults(std::move(results));
+  }
+
+  void TearDown() override { store()->ShutdownOnUIThread(); }
+
+ private:
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  scoped_refptr<MockPasswordStoreInterface> store_;
+  PasswordStoreConsumer* consumer_ = nullptr;
+};
+
+TEST_F(InsecureCredentialsHelperTest, UpdateLoginCalledForTheRightFormAdd) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username1"),
+      CreateForm("http://example.com", u"username2"),
+  };
+  PasswordForm expected_form = forms[0];
+  expected_form.password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata(base::Time::Now(), IsMuted(false));
+  ExpectGetLogins("http://example.com");
+  AddPhishedCredentials(store(),
+                        MakeCredential("http://example.com", u"username1"));
+  EXPECT_CALL(*store(), UpdateLogin(expected_form));
+  SimulateStoreRepliedWithResults(forms);
+}
+
+TEST_F(InsecureCredentialsHelperTest, UpdateLoginCalledForTheRightFormRemove) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username1"),
+      CreateForm("http://example.com", u"username2"),
+  };
+  forms.at(0).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata(base::Time::Now(), IsMuted(false));
+
+  ExpectGetLogins("http://example.com");
+  RemovePhishedCredentials(store(),
+                           MakeCredential("http://example.com", u"username1"));
+  EXPECT_CALL(*store(),
+              UpdateLogin(CreateForm("http://example.com", u"username1")));
+  SimulateStoreRepliedWithResults(forms);
+}
+
+TEST_F(InsecureCredentialsHelperTest, UpdateLoginCalledForAllMatchingFormsAdd) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username", u"password1"),
+      CreateForm("http://example.com", u"username", u"password2"),
+  };
+  ExpectGetLogins("http://example.com");
+  AddPhishedCredentials(store(),
+                        MakeCredential("http://example.com", u"username"));
+  forms.at(0).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata(base::Time::Now(), IsMuted(false));
+  forms.at(1).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata(base::Time::Now(), IsMuted(false));
+  EXPECT_CALL(*store(), UpdateLogin(forms[1]));
+  EXPECT_CALL(*store(), UpdateLogin(forms[0]));
+  SimulateStoreRepliedWithResults(
+      {CreateForm("http://example.com", u"username", u"password1"),
+       CreateForm("http://example.com", u"username", u"password2")});
+}
+
+TEST_F(InsecureCredentialsHelperTest,
+       UpdateLoginCalledForAllMatchingFormsRemove) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username", u"password1"),
+      CreateForm("http://example.com", u"username", u"password2"),
+  };
+
+  ExpectGetLogins("http://example.com");
+  RemovePhishedCredentials(store(),
+                           MakeCredential("http://example.com", u"username"));
+  forms.at(0).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata();
+  forms.at(1).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata();
+  EXPECT_CALL(*store(), UpdateLogin(CreateForm("http://example.com",
+                                               u"username", u"password2")));
+  EXPECT_CALL(*store(), UpdateLogin(CreateForm("http://example.com",
+                                               u"username", u"password1")));
+  SimulateStoreRepliedWithResults(forms);
+}
+
+TEST_F(InsecureCredentialsHelperTest,
+       UpdateCalledOnlyIfIssueWasNotPhishedBeforeAdd) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username1"),
+      CreateForm("http://example.com", u"username2"),
+  };
+
+  ExpectGetLogins("http://example.com");
+  AddPhishedCredentials(store(),
+                        MakeCredential("http://example.com", u"username1"));
+  forms.at(0).password_issues.value()[InsecureType::kPhished] =
+      InsecurityMetadata();
+  EXPECT_CALL(*store(), UpdateLogin).Times(0);
+  SimulateStoreRepliedWithResults(forms);
+}
+
+TEST_F(InsecureCredentialsHelperTest,
+       UpdateCalledOnlyIfIssueWasPhishedBeforeRemove) {
+  std::vector<PasswordForm> forms = {
+      CreateForm("http://example.com", u"username1"),
+      CreateForm("http://example.com", u"username2"),
+  };
+
+  ExpectGetLogins("http://example.com");
+  RemovePhishedCredentials(store(),
+                           MakeCredential("http://example.com", u"username1"));
+  EXPECT_CALL(*store(), UpdateLogin).Times(0);
+  SimulateStoreRepliedWithResults(forms);
+}
+
+}  // namespace password_manager
diff --git a/components/password_manager/core/browser/insecure_credentials_table.cc b/components/password_manager/core/browser/insecure_credentials_table.cc
index 1127ec985..44ecee5 100644
--- a/components/password_manager/core/browser/insecure_credentials_table.cc
+++ b/components/password_manager/core/browser/insecure_credentials_table.cc
@@ -8,6 +8,8 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/stringprintf.h"
+#include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_store_sync.h"
 #include "sql/database.h"
 #include "sql/statement.h"
 
@@ -61,6 +63,11 @@
 
 InsecureCredential::~InsecureCredential() = default;
 
+bool InsecureCredential::SameMetadata(
+    const InsecurityMetadata& metadata) const {
+  return create_time == metadata.create_time && is_muted == metadata.is_muted;
+}
+
 bool operator==(const InsecureCredential& lhs, const InsecureCredential& rhs) {
   return lhs.signon_realm == rhs.signon_realm && lhs.username == rhs.username &&
          lhs.create_time == rhs.create_time &&
@@ -115,6 +122,47 @@
   return result && db_->GetLastChangeCount();
 }
 
+bool InsecureCredentialsTable::InsertOrReplace(FormPrimaryKey parent_key,
+                                               InsecureType type,
+                                               InsecurityMetadata metadata) {
+  DCHECK(db_);
+  DCHECK(db_->DoesTableExist(kTableName));
+
+  sql::Statement s(db_->GetCachedStatement(
+      SQL_FROM_HERE,
+      base::StringPrintf("INSERT OR REPLACE INTO %s (parent_id, "
+                         "insecurity_type, create_time, is_muted) "
+                         "VALUES (?, ?, ?, ?)",
+                         kTableName)
+          .c_str()));
+  s.BindInt(0, parent_key.value());
+  s.BindInt(1, static_cast<int>(type));
+  s.BindInt64(2,
+              metadata.create_time.ToDeltaSinceWindowsEpoch().InMicroseconds());
+  s.BindBool(3, metadata.is_muted.value());
+
+  bool result = s.Run();
+  return result && db_->GetLastChangeCount();
+}
+
+bool InsecureCredentialsTable::RemoveRow(FormPrimaryKey parent_key,
+                                         InsecureType insecure_type) {
+  DCHECK(db_);
+  DCHECK(db_->DoesTableExist(kTableName));
+
+  sql::Statement s(db_->GetCachedStatement(
+      SQL_FROM_HERE,
+      base::StringPrintf(
+          "DELETE FROM %s WHERE parent_id = ? AND insecurity_type = ?",
+          kTableName)
+          .c_str()));
+  s.BindInt(0, parent_key.value());
+  s.BindInt(1, static_cast<int>(insecure_type));
+
+  bool result = s.Run();
+  return result && db_->GetLastChangeCount();
+}
+
 bool InsecureCredentialsTable::RemoveRows(
     const std::string& signon_realm,
     const std::u16string& username,
diff --git a/components/password_manager/core/browser/insecure_credentials_table.h b/components/password_manager/core/browser/insecure_credentials_table.h
index 53067d1..38918bc 100644
--- a/components/password_manager/core/browser/insecure_credentials_table.h
+++ b/components/password_manager/core/browser/insecure_credentials_table.h
@@ -47,6 +47,8 @@
   InsecureCredential& operator=(InsecureCredential&& rhs);
   ~InsecureCredential();
 
+  bool SameMetadata(const InsecurityMetadata& metadata) const;
+
   // The primary key of an affected Login.
   FormPrimaryKey parent_key{-1};
   // The signon_realm of the website where the credentials were compromised.
@@ -80,6 +82,15 @@
   // if the SQL completed successfully and an item was created.
   bool AddRow(const InsecureCredential& compromised_credentials);
 
+  // Adds information about the insecure credential if it doesn't exist.
+  // If it does, it removes the previous entry and adds the new one.
+  bool InsertOrReplace(FormPrimaryKey parent_key,
+                       InsecureType type,
+                       InsecurityMetadata metadata);
+
+  // Removes the row corresponding to |parent_key| and |insecure_type|.
+  bool RemoveRow(FormPrimaryKey parent_key, InsecureType insecure_type);
+
   // Removes information about the credentials compromised for |username| on
   // |signon_realm|. |reason| is the reason why the credentials are removed from
   // the table. Returns true if the SQL completed successfully.
diff --git a/components/password_manager/core/browser/insecure_credentials_table_unittest.cc b/components/password_manager/core/browser/insecure_credentials_table_unittest.cc
index 11d92d1..e9d3728 100644
--- a/components/password_manager/core/browser/insecure_credentials_table_unittest.cc
+++ b/components/password_manager/core/browser/insecure_credentials_table_unittest.cc
@@ -16,6 +16,7 @@
 #include "build/build_config.h"
 #include "components/os_crypt/os_crypt_mocker.h"
 #include "components/password_manager/core/browser/login_database.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "sql/database.h"
@@ -202,6 +203,46 @@
   EXPECT_THAT(db()->GetRows(test_data().signon_realm), IsEmpty());
 }
 
+TEST_F(InsecureCredentialsTableTest, RemoveRowMultipleTypes) {
+  EXPECT_THAT(login_db()->AddLogin(test_form()), SizeIs(1));
+  InsecureCredential leaked = test_data();
+  leaked.insecure_type = InsecureType::kLeaked;
+  InsecureCredential phished = test_data();
+  phished.insecure_type = InsecureType::kPhished;
+  EXPECT_TRUE(db()->AddRow(leaked));
+  EXPECT_TRUE(db()->AddRow(phished));
+
+  EXPECT_THAT(db()->GetRows(test_data().signon_realm),
+              UnorderedElementsAre(leaked, phished));
+  EXPECT_THAT(GetParentIds(db()->GetAllRows()), ElementsAre(1, 1));
+
+  EXPECT_TRUE(db()->RemoveRow(FormPrimaryKey(1), InsecureType::kPhished));
+  EXPECT_THAT(db()->GetRows(test_data().signon_realm), ElementsAre(leaked));
+}
+
+TEST_F(InsecureCredentialsTableTest, UpdateRow) {
+  EXPECT_THAT(login_db()->AddLogin(test_form()), SizeIs(1));
+
+  InsecureCredential insecure_credential = test_data();
+  insecure_credential.is_muted = IsMuted(false);
+  insecure_credential.parent_key = FormPrimaryKey(1);
+  EXPECT_TRUE(db()->AddRow(insecure_credential));
+
+  EXPECT_THAT(db()->GetRows(test_data().signon_realm),
+              UnorderedElementsAre(insecure_credential));
+  EXPECT_THAT(GetParentIds(db()->GetAllRows()), ElementsAre(1));
+
+  InsecurityMetadata new_metadata(insecure_credential.create_time,
+                                  IsMuted(true));
+  InsecureCredential new_insecure_credential = insecure_credential;
+  new_insecure_credential.is_muted = IsMuted(true);
+  EXPECT_TRUE(db()->InsertOrReplace(insecure_credential.parent_key,
+                                    insecure_credential.insecure_type,
+                                    new_metadata));
+  EXPECT_THAT(db()->GetRows(test_data().signon_realm),
+              ElementsAre(new_insecure_credential));
+}
+
 TEST_F(InsecureCredentialsTableTest, ReportMetricsBeforeBulkCheck) {
   EXPECT_THAT(login_db()->AddLogin(test_form()), SizeIs(1));
   EXPECT_TRUE(db()->AddRow(test_data()));
diff --git a/components/password_manager/core/browser/leak_detection/authenticated_leak_check.cc b/components/password_manager/core/browser/leak_detection/authenticated_leak_check.cc
index c8bacb1..8e8f02d 100644
--- a/components/password_manager/core/browser/leak_detection/authenticated_leak_check.cc
+++ b/components/password_manager/core/browser/leak_detection/authenticated_leak_check.cc
@@ -197,14 +197,8 @@
 void AuthenticatedLeakCheck::OnAccessTokenRequestCompleted(
     GoogleServiceAuthError error,
     signin::AccessTokenInfo access_token_info) {
-  base::UmaHistogramEnumeration(
-      "PasswordManager.LeakDetection.AccessTokenFetchStatus", error.state(),
-      GoogleServiceAuthError::NUM_STATES);
   if (error.state() != GoogleServiceAuthError::NONE) {
     // Network error codes are negative. See: src/net/base/net_error_list.h.
-    base::UmaHistogramSparse(
-        "PasswordManager.LeakDetection.AccessTokenNetErrorCode",
-        -error.network_error());
     DLOG(ERROR) << "Token request error: " << error.error_message();
     delegate_->OnError(LeakDetectionError::kTokenRequestFailure);
     return;
@@ -253,10 +247,8 @@
 
   AnalyzeResponse(
       std::move(response), encryption_key_,
-      TimeCallback(
-          base::BindOnce(&AuthenticatedLeakCheck::OnAnalyzeSingleLeakResponse,
-                         weak_ptr_factory_.GetWeakPtr()),
-          "PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime"));
+      base::BindOnce(&AuthenticatedLeakCheck::OnAnalyzeSingleLeakResponse,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 void AuthenticatedLeakCheck::OnAnalyzeSingleLeakResponse(
diff --git a/components/password_manager/core/browser/leak_detection/authenticated_leak_check_unittest.cc b/components/password_manager/core/browser/leak_detection/authenticated_leak_check_unittest.cc
index 9de8351..a5da801 100644
--- a/components/password_manager/core/browser/leak_detection/authenticated_leak_check_unittest.cc
+++ b/components/password_manager/core/browser/leak_detection/authenticated_leak_check_unittest.cc
@@ -169,9 +169,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ObtainAccessTokenTime", kMockElapsedTime,
       1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AccessTokenFetchStatus",
-      GoogleServiceAuthError::NONE, 1);
 
   auto network_request = std::make_unique<MockLeakDetectionRequest>();
   EXPECT_CALL(*network_request,
@@ -225,9 +222,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ObtainAccessTokenTime", kMockElapsedTime,
       1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AccessTokenFetchStatus",
-      GoogleServiceAuthError::NONE, 1);
 }
 
 TEST_F(AuthenticatedLeakCheckTest, GetAccessTokenFailure) {
@@ -244,12 +238,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ObtainAccessTokenTime", kMockElapsedTime,
       1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AccessTokenFetchStatus",
-      GoogleServiceAuthError::CONNECTION_FAILED, 1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AccessTokenNetErrorCode", -net::ERR_FAILED,
-      1);
 }
 
 // Perform the whole cycle of a leak check. The server returns data that
@@ -283,9 +271,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime",
       kMockElapsedTime, 1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime",
-      kMockElapsedTime, 1);
 }
 // Perform the whole cycle of a leak check. The server returns data signalling
 // that the password wasn't leaked.
@@ -316,9 +301,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime",
       kMockElapsedTime, 1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime",
-      kMockElapsedTime, 1);
 }
 
 // Perform the whole cycle of a leak check. The server returns data signalling
@@ -356,9 +338,6 @@
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime",
       kMockElapsedTime, 1);
-  histogram_tester().ExpectUniqueSample(
-      "PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime",
-      kMockElapsedTime, 1);
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index ab464c0..8888810 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -15,6 +15,7 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
@@ -31,11 +32,13 @@
 #include "build/build_config.h"
 #include "components/os_crypt/os_crypt.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
+#include "components/password_manager/core/browser/insecure_credentials_table.h"
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
+#include "components/password_manager/core/browser/password_store_change.h"
 #include "components/password_manager/core/browser/psl_matching_helper.h"
 #include "components/password_manager/core/browser/sql_table_builder.h"
 #include "components/sync/protocol/entity_metadata.pb.h"
@@ -192,14 +195,18 @@
   SQLTableBuilder* sync_model_metadata;
 };
 
+base::span<const uint8_t> PickleToSpan(const base::Pickle& pickle) {
+  return base::make_span(reinterpret_cast<const uint8_t*>(pickle.data()),
+                         pickle.size());
+}
+
 void BindAddStatement(const PasswordForm& form, sql::Statement* s) {
   s->BindString(COLUMN_ORIGIN_URL, form.url.spec());
   s->BindString(COLUMN_ACTION_URL, form.action.spec());
   s->BindString16(COLUMN_USERNAME_ELEMENT, form.username_element);
   s->BindString16(COLUMN_USERNAME_VALUE, form.username_value);
   s->BindString16(COLUMN_PASSWORD_ELEMENT, form.password_element);
-  s->BindBlob(COLUMN_PASSWORD_VALUE, form.encrypted_password.data(),
-              static_cast<int>(form.encrypted_password.length()));
+  s->BindBlob(COLUMN_PASSWORD_VALUE, form.encrypted_password);
   s->BindString16(COLUMN_SUBMIT_ELEMENT, form.submit_element);
   s->BindString(COLUMN_SIGNON_REALM, form.signon_realm);
   s->BindInt64(COLUMN_DATE_CREATED, form.date_created.ToInternalValue());
@@ -209,8 +216,7 @@
   s->BindInt(COLUMN_TIMES_USED, form.times_used);
   base::Pickle form_data_pickle;
   autofill::SerializeFormData(form.form_data, &form_data_pickle);
-  s->BindBlob(COLUMN_FORM_DATA, form_data_pickle.data(),
-              form_data_pickle.size());
+  s->BindBlob(COLUMN_FORM_DATA, PickleToSpan(form_data_pickle));
   s->BindInt64(COLUMN_DATE_SYNCED, form.date_synced.ToInternalValue());
   s->BindString16(COLUMN_DISPLAY_NAME, form.display_name);
   s->BindString(COLUMN_ICON_URL, form.icon_url.spec());
@@ -224,14 +230,13 @@
              static_cast<int>(form.generation_upload_status));
   base::Pickle usernames_pickle =
       SerializeValueElementPairs(form.all_possible_usernames);
-  s->BindBlob(COLUMN_POSSIBLE_USERNAME_PAIRS, usernames_pickle.data(),
-              usernames_pickle.size());
+  s->BindBlob(COLUMN_POSSIBLE_USERNAME_PAIRS, PickleToSpan(usernames_pickle));
   s->BindInt64(COLUMN_DATE_LAST_USED,
                form.date_last_used.ToDeltaSinceWindowsEpoch().InMicroseconds());
   base::Pickle moving_blocked_for_pickle =
       SerializeGaiaIdHashVector(form.moving_blocked_for_list);
-  s->BindBlob(COLUMN_MOVING_BLOCKED_FOR, moving_blocked_for_pickle.data(),
-              moving_blocked_for_pickle.size());
+  s->BindBlob(COLUMN_MOVING_BLOCKED_FOR,
+              PickleToSpan(moving_blocked_for_pickle));
 }
 
 // Output parameter is the first one because of binding order.
@@ -1164,9 +1169,13 @@
   if (success) {
     // If success, the row never existed so password was not changed.
     FillFormInStore(&form_with_encrypted_password);
+    FormPrimaryKey primary_key = FormPrimaryKey(db_.GetLastInsertRowId());
+    if (form_with_encrypted_password.password_issues.has_value()) {
+      UpdateInsecureCredentials(
+          primary_key, form_with_encrypted_password.password_issues.value());
+    }
     list.emplace_back(PasswordStoreChange::ADD,
-                      std::move(form_with_encrypted_password),
-                      FormPrimaryKey(db_.GetLastInsertRowId()),
+                      std::move(form_with_encrypted_password), primary_key,
                       /*password_changed=*/false);
     return list;
   }
@@ -1187,9 +1196,17 @@
     list.emplace_back(PasswordStoreChange::REMOVE, removed_form,
                       FormPrimaryKey(old_primary_key_password.primary_key));
     FillFormInStore(&form_with_encrypted_password);
-    list.emplace_back(
-        PasswordStoreChange::ADD, std::move(form_with_encrypted_password),
-        FormPrimaryKey(db_.GetLastInsertRowId()), password_changed);
+
+    FormPrimaryKey primary_key = FormPrimaryKey(db_.GetLastInsertRowId());
+    InsecureCredentialsChanged insecure_changed(false);
+    if (form_with_encrypted_password.password_issues.has_value()) {
+      insecure_changed = UpdateInsecureCredentials(
+          primary_key, form_with_encrypted_password.password_issues.value());
+    }
+    list.emplace_back(PasswordStoreChange::ADD,
+                      std::move(form_with_encrypted_password),
+                      FormPrimaryKey(db_.GetLastInsertRowId()),
+                      password_changed, insecure_changed);
   } else if (error) {
     if (sqlite_error_code == 19 /*SQLITE_CONSTRAINT*/) {
       *error = AddLoginError::kConstraintViolation;
@@ -1228,8 +1245,7 @@
       db_.GetCachedStatement(SQL_FROM_HERE, update_statement_.c_str()));
   int next_param = 0;
   s.BindString(next_param++, form.action.spec());
-  s.BindBlob(next_param++, encrypted_password.data(),
-             static_cast<int>(encrypted_password.length()));
+  s.BindBlob(next_param++, encrypted_password);
   s.BindString16(next_param++, form.submit_element);
   s.BindInt64(next_param++, form.date_created.ToInternalValue());
   s.BindInt(next_param++, form.blocked_by_user);
@@ -1238,7 +1254,7 @@
   s.BindInt(next_param++, form.times_used);
   base::Pickle form_data_pickle;
   autofill::SerializeFormData(form.form_data, &form_data_pickle);
-  s.BindBlob(next_param++, form_data_pickle.data(), form_data_pickle.size());
+  s.BindBlob(next_param++, PickleToSpan(form_data_pickle));
   s.BindInt64(next_param++, form.date_synced.ToInternalValue());
   s.BindString16(next_param++, form.display_name);
   s.BindString(next_param++, form.icon_url.spec());
@@ -1250,13 +1266,12 @@
   s.BindInt(next_param++, static_cast<int>(form.generation_upload_status));
   base::Pickle username_pickle =
       SerializeValueElementPairs(form.all_possible_usernames);
-  s.BindBlob(next_param++, username_pickle.data(), username_pickle.size());
+  s.BindBlob(next_param++, PickleToSpan(username_pickle));
   s.BindInt64(next_param++,
               form.date_last_used.ToDeltaSinceWindowsEpoch().InMicroseconds());
   base::Pickle moving_blocked_for_pickle =
       SerializeGaiaIdHashVector(form.moving_blocked_for_list);
-  s.BindBlob(next_param++, moving_blocked_for_pickle.data(),
-             moving_blocked_for_pickle.size());
+  s.BindBlob(next_param++, PickleToSpan(moving_blocked_for_pickle));
   // NOTE: Add new fields here unless the field is a part of the unique key.
   // If so, add new field below.
 
@@ -1276,28 +1291,41 @@
     return PasswordStoreChangeList();
   }
 
-  PasswordStoreChangeList list;
-  if (db_.GetLastChangeCount()) {
-    bool password_changed =
-        form.password_value != old_primary_key_password.decrypted_password;
-
-    InsecureCredentialsChanged insecure_changed(
-        password_changed ? insecure_credentials_table().RemoveRows(
-                               form.signon_realm, form.username_value,
-                               RemoveInsecureCredentialsReason::kUpdate)
-                         : false);
-
-    PasswordForm form_with_encrypted_password = form;
-    form_with_encrypted_password.encrypted_password = encrypted_password;
-    FillFormInStore(&form_with_encrypted_password);
-    list.emplace_back(PasswordStoreChange::UPDATE,
-                      std::move(form_with_encrypted_password),
-                      FormPrimaryKey(old_primary_key_password.primary_key),
-                      password_changed, insecure_changed);
-  } else if (error) {
-    *error = UpdateLoginError::kNoUpdatedRecords;
+  // If no rows changed due to this command, it means that there was no row to
+  // update, so there is no point trying to update insecure credentials data.
+  if (db_.GetLastChangeCount() == 0) {
+    if (error) {
+      *error = UpdateLoginError::kNoUpdatedRecords;
+    }
+    return PasswordStoreChangeList();
   }
 
+  bool password_changed =
+      form.password_value != old_primary_key_password.decrypted_password;
+
+  InsecureCredentialsChanged insecure_changed(false);
+  // TODO(crbug.com/1223022): It should be the responsibility of the caller to
+  // set `password_issues` to empty instead of leaving it nullopt in this case.
+  // Remove this once all `UpdateLogin` calls have been checked.
+  if (password_changed && !form.password_issues.has_value()) {
+    insecure_changed = UpdateInsecureCredentials(
+        FormPrimaryKey(old_primary_key_password.primary_key),
+        base::flat_map<InsecureType, InsecurityMetadata>());
+  } else if (form.password_issues.has_value()) {
+    insecure_changed = UpdateInsecureCredentials(
+        FormPrimaryKey(old_primary_key_password.primary_key),
+        form.password_issues.value());
+  }
+
+  PasswordStoreChangeList list;
+  PasswordForm form_with_encrypted_password = form;
+  form_with_encrypted_password.encrypted_password = encrypted_password;
+  FillFormInStore(&form_with_encrypted_password);
+  list.emplace_back(PasswordStoreChange::UPDATE,
+                    std::move(form_with_encrypted_password),
+                    FormPrimaryKey(old_primary_key_password.primary_key),
+                    password_changed, insecure_changed);
+
   return list;
 }
 
@@ -1516,11 +1544,12 @@
 
   std::vector<InsecureCredential> insecure_credentials =
       insecure_credentials_table_.GetRows(FormPrimaryKey(*primary_key));
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
   for (const auto& insecure_credential : insecure_credentials) {
-    form->password_issues[insecure_credential.insecure_type] =
-        InsecurityMetadata(insecure_credential.create_time,
-                           insecure_credential.is_muted);
+    issues[insecure_credential.insecure_type] = InsecurityMetadata(
+        insecure_credential.create_time, insecure_credential.is_muted);
   }
+  form->password_issues = std::move(issues);
 
   return ENCRYPTION_RESULT_SUCCESS;
 }
@@ -2162,4 +2191,27 @@
                                       : PasswordForm::Store::kProfileStore;
 }
 
+InsecureCredentialsChanged LoginDatabase::UpdateInsecureCredentials(
+    FormPrimaryKey primary_key,
+    const base::flat_map<InsecureType, InsecurityMetadata>& password_issues) {
+  bool changed = false;
+  for (const auto& password_issue : password_issues) {
+    changed = insecure_credentials_table_.InsertOrReplace(
+                  primary_key, password_issue.first, password_issue.second) ||
+              changed;
+  }
+
+  // If an insecure type has been removed from the form it has to be removed
+  // from the database. This can currently happen for phished entries.
+  for (auto insecure_type : {InsecureType::kLeaked, InsecureType::kPhished,
+                             InsecureType::kWeak, InsecureType::kReused}) {
+    if (password_issues.find(insecure_type) == password_issues.end()) {
+      changed =
+          insecure_credentials_table_.RemoveRow(primary_key, insecure_type) ||
+          changed;
+    }
+  }
+  return InsecureCredentialsChanged(changed);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index 8b42e6435..8a9d430b 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -337,6 +337,13 @@
   // kAccountStore depending on the value of `is_account_store_`.
   void FillFormInStore(PasswordForm* form) const;
 
+  // Updates data in the `insecure_credentials_table_` with the password issues
+  // data from `password_issues`. Returns whether any insecure credential entry
+  // was changed.
+  InsecureCredentialsChanged UpdateInsecureCredentials(
+      FormPrimaryKey primary_key,
+      const base::flat_map<InsecureType, InsecurityMetadata>& password_issues);
+
   const base::FilePath db_path_;
   const IsAccountStore is_account_store_;
 
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 43836016..c7578839 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/containers/flat_map.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -36,12 +37,15 @@
 #include "sql/test/test_helpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 using autofill::GaiaIdHash;
 using base::ASCIIToUTF16;
 using base::UTF16ToASCII;
+using ::testing::ElementsAre;
 using ::testing::Eq;
+using ::testing::IsEmpty;
 using ::testing::Ne;
 using ::testing::Pointee;
 using ::testing::SizeIs;
@@ -56,12 +60,21 @@
 }
 
 PasswordStoreChangeList UpdateChangeForForm(const PasswordForm& form,
-                                            const bool password_changed) {
+                                            bool password_changed) {
   return PasswordStoreChangeList(
       1, PasswordStoreChange(PasswordStoreChange::UPDATE, form,
                              FormPrimaryKey(1), password_changed));
 }
 
+PasswordStoreChangeList UpdateChangeForForm(const PasswordForm& form,
+                                            bool password_changed,
+                                            bool insecure_changed) {
+  return PasswordStoreChangeList(
+      1, PasswordStoreChange(PasswordStoreChange::UPDATE, form,
+                             FormPrimaryKey(1), password_changed,
+                             InsecureCredentialsChanged(insecure_changed)));
+}
+
 PasswordStoreChangeList RemoveChangeForForm(const PasswordForm& form) {
   return PasswordStoreChangeList(
       1, PasswordStoreChange(PasswordStoreChange::REMOVE, form));
@@ -90,6 +103,10 @@
   form.in_store = PasswordForm::Store::kProfileStore;
   form.moving_blocked_for_list.push_back(GaiaIdHash::FromGaiaId("user1"));
   form.moving_blocked_for_list.push_back(GaiaIdHash::FromGaiaId("user2"));
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  //  via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
   return form;
 }
 
@@ -546,6 +563,13 @@
   form.in_store = PasswordForm::Store::kProfileStore;
   form2.in_store = PasswordForm::Store::kProfileStore;
 
+  // |password_issues| is also expected to be set to empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  form2.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+
   // Match against desktop.
   PasswordFormDigest form_request = {PasswordForm::Scheme::kHtml,
                                      "https://foo.com/",
@@ -587,6 +611,14 @@
   form.in_store = PasswordForm::Store::kProfileStore;
   form_with_port.in_store = PasswordForm::Store::kProfileStore;
 
+  // |password_issues| should also be set to empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  form_with_port.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
+
   // Match localhost with and without port.
   PasswordFormDigest form_request(PasswordForm::Scheme::kHtml,
                                   "http://localhost/",
@@ -701,6 +733,13 @@
   form.in_store = PasswordForm::Store::kProfileStore;
   form2.in_store = PasswordForm::Store::kProfileStore;
 
+  // |password_issues| should also be set to empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  form2.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+
   // Match against the first one.
   PasswordFormDigest form_request = {PasswordForm::Scheme::kHtml,
                                      form.signon_realm, form.url};
@@ -731,6 +770,12 @@
   // When we retrieve the form from the store, it should have |in_store| set.
   form.in_store = PasswordForm::Store::kProfileStore;
 
+  // |password_issues| should also be set to empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+
   // Match against.
   PasswordFormDigest form_request = {PasswordForm::Scheme::kHtml,
                                      "https://example.com/",
@@ -1108,6 +1153,11 @@
   form.federation_origin =
       url::Origin::Create(GURL("https://accounts.google.com/"));
   form.skip_zero_click = true;
+
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
   EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form));
 
   // Get all non-blocklisted logins (should be none).
@@ -1230,6 +1280,12 @@
   PasswordForm expected_form(completed_form);
   // When we retrieve the form from the store, it should have |in_store| set.
   expected_form.in_store = PasswordForm::Store::kProfileStore;
+  // And |password_issues| should be empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  expected_form.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
   EXPECT_EQ(expected_form, *result[0]);
   result.clear();
 }
@@ -1278,6 +1334,15 @@
   complete_form.in_store = PasswordForm::Store::kProfileStore;
   incomplete_form.in_store = PasswordForm::Store::kProfileStore;
 
+  // And |password_issues| should be set to empty.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  complete_form.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
+  incomplete_form.password_issues =
+      base::flat_map<InsecureType, InsecurityMetadata>();
+
   // Both still exist now.
   EXPECT_TRUE(db().GetAutofillableLogins(&result));
   ASSERT_EQ(2U, result.size());
@@ -1361,6 +1426,12 @@
   // When we retrieve the form from the store, it should have |in_store| set.
   form.in_store = PasswordForm::Store::kProfileStore;
 
+  // And |password_issues| should be empty
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+
   std::vector<std::unique_ptr<PasswordForm>> result;
   EXPECT_TRUE(db().GetLogins(PasswordFormDigest(form), &result));
   ASSERT_EQ(1U, result.size());
@@ -1398,6 +1469,11 @@
 
   // When we retrieve the form from the store, it should have |in_store| set.
   form.in_store = PasswordForm::Store::kProfileStore;
+  // And |password_issues| should be empty
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
 
   std::vector<std::unique_ptr<PasswordForm>> result;
   ASSERT_TRUE(db().GetLogins(PasswordFormDigest(form), &result));
@@ -2407,6 +2483,14 @@
   // Delete undecryptable logins and make sure we can get valid logins.
   EXPECT_EQ(DatabaseCleanupResult::kSuccess, db.DeleteUndecryptableLogins());
   EXPECT_TRUE(db.GetAutofillableLogins(&result));
+
+  // Autofillable logins will come back with insecure data so add that to the
+  // expected forms.
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form1.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  form3.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
   EXPECT_THAT(result, UnorderedElementsAre(Pointee(form1), Pointee(form3)));
 
   RunUntilIdle();
@@ -2597,10 +2681,13 @@
                                  IsMuted(false)};
   InsecureCredential credential2 = credential1;
   credential2.insecure_type = InsecureType::kPhished;
-  form.password_issues[InsecureType::kLeaked] =
+
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
+  issues[InsecureType::kLeaked] =
       InsecurityMetadata(credential1.create_time, credential1.is_muted);
-  form.password_issues[InsecureType::kPhished] =
+  issues[InsecureType::kPhished] =
       InsecurityMetadata(credential2.create_time, credential2.is_muted);
+  form.password_issues = std::move(issues);
 
   db().insecure_credentials_table().AddRow(credential1);
   db().insecure_credentials_table().AddRow(credential2);
@@ -2673,35 +2760,107 @@
                            testing::Pair(FormPrimaryKey(3), Pointee(form3))));
 }
 
-TEST_F(LoginDatabaseTest, UpdatingPasswordRemovesInsecureCredentials) {
+TEST_F(LoginDatabaseTest, UpdateLoginWithAddedInsecureCredential) {
   PasswordForm form = GenerateExamplePasswordForm();
-
   ignore_result(db().AddLogin(form));
-  InsecureCredential credential1{form.signon_realm, form.username_value,
-                                 base::Time(), InsecureType::kLeaked,
-                                 IsMuted(false)};
-  InsecureCredential credential2 = credential1;
-  credential2.insecure_type = InsecureType::kPhished;
+  InsecureCredential insecure_credential{form.signon_realm, form.username_value,
+                                         base::Time(), InsecureType::kLeaked,
+                                         IsMuted(false)};
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
+  issues[InsecureType::kLeaked] = InsecurityMetadata(
+      insecure_credential.create_time, insecure_credential.is_muted);
+  form.password_issues = std::move(issues);
 
-  db().insecure_credentials_table().AddRow(credential1);
-  db().insecure_credentials_table().AddRow(credential2);
-
-  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
-              testing::UnorderedElementsAre(credential1, credential2));
-
-  // Verify that changing other fields doesn't involve insecure credentials
-  // removal.
-  form.times_used = 92;
-  EXPECT_EQ(UpdateChangeForForm(form, /*password_changed=*/false),
+  EXPECT_EQ(UpdateChangeForForm(form, /*password_changed=*/false,
+                                /*insecure_changed=*/true),
             db().UpdateLogin(form, nullptr));
   EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
-              testing::UnorderedElementsAre(credential1, credential2));
+              ElementsAre(insecure_credential));
+}
 
+TEST_F(LoginDatabaseTest, UpdateLoginWithNoInsecureCredentialInformation) {
+  PasswordForm form = GenerateExamplePasswordForm();
+  ignore_result(db().AddLogin(form));
+  InsecureCredential insecure_credential{form.signon_realm, form.username_value,
+                                         base::Time(), InsecureType::kLeaked,
+                                         IsMuted(false)};
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
+  issues[InsecureType::kLeaked] = InsecurityMetadata(
+      insecure_credential.create_time, insecure_credential.is_muted);
+  form.password_issues = std::move(issues);
+
+  ASSERT_EQ(UpdateChangeForForm(form, /*password_changed=*/false,
+                                /*insecure_changed=*/true),
+            db().UpdateLogin(form, nullptr));
+  ASSERT_THAT(db().insecure_credentials_table().GetAllRows(),
+              ElementsAre(insecure_credential));
+
+  PasswordForm no_info_form = form;
+  form.password_issues = absl::nullopt;
+  EXPECT_EQ(UpdateChangeForForm(no_info_form, /*password_changed=*/false,
+                                /*insecure_changed=*/false),
+            db().UpdateLogin(no_info_form, nullptr));
+  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
+              ElementsAre(insecure_credential));
+}
+
+TEST_F(LoginDatabaseTest, UpdateLoginWithUpdatedInsecureCredential) {
+  PasswordForm form = GenerateExamplePasswordForm();
+  ignore_result(db().AddLogin(form));
+  InsecureCredential insecure_credential{form.signon_realm, form.username_value,
+                                         base::Time(), InsecureType::kLeaked,
+                                         IsMuted(false)};
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
+  issues[InsecureType::kLeaked] =
+      InsecurityMetadata(base::Time(), IsMuted(false));
+  form.password_issues = std::move(issues);
+
+  ASSERT_EQ(UpdateChangeForForm(form, /*password_changed=*/false,
+                                /*insecure_changed=*/true),
+            db().UpdateLogin(form, nullptr));
+  ASSERT_THAT(db().insecure_credentials_table().GetAllRows(),
+              ElementsAre(insecure_credential));
+
+  (*form.password_issues)[InsecureType::kLeaked].is_muted = IsMuted(true);
+  EXPECT_EQ(UpdateChangeForForm(form, /*password_changed=*/false,
+                                /*insecure_changed=*/true),
+            db().UpdateLogin(form, nullptr));
+  insecure_credential.is_muted = IsMuted(true);
+  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
+              ElementsAre(insecure_credential));
+}
+
+TEST_F(LoginDatabaseTest, UpdateLoginWithRemovedInsecureCredentialEntry) {
+  PasswordForm form = GenerateExamplePasswordForm();
+  ignore_result(db().AddLogin(form));
+  InsecureCredential leaked{form.signon_realm, form.username_value,
+                            base::Time(), InsecureType::kLeaked,
+                            IsMuted(false)};
+  InsecureCredential phished{form.signon_realm, form.username_value,
+                             base::Time(), InsecureType::kPhished,
+                             IsMuted(false)};
+  leaked.parent_key = phished.parent_key = FormPrimaryKey(1);
+  base::flat_map<InsecureType, InsecurityMetadata> issues;
+  issues[InsecureType::kLeaked] =
+      InsecurityMetadata(base::Time(), IsMuted(false));
+  issues[InsecureType::kPhished] =
+      InsecurityMetadata(base::Time(), IsMuted(false));
+  form.password_issues = std::move(issues);
+
+  ASSERT_EQ(UpdateChangeForForm(form, /*password_changed=*/false,
+                                /*insecure_changed=*/true),
+            db().UpdateLogin(form, nullptr));
+  ASSERT_THAT(db().insecure_credentials_table().GetAllRows(),
+              UnorderedElementsAre(leaked, phished));
+
+  // Complete password_issues removal can usually only happen when the password
+  // is changed.
   form.password_value = u"new_password";
-  EXPECT_EQ(UpdateChangeForForm(form, /*password_changed=*/true),
+  form.password_issues->clear();
+  EXPECT_EQ(UpdateChangeForForm(form, /*password_changed=*/true,
+                                /*insecure_changed=*/true),
             db().UpdateLogin(form, nullptr));
-  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
-              testing::IsEmpty());
+  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(), IsEmpty());
 }
 
 TEST_F(LoginDatabaseTest,
@@ -2720,15 +2879,37 @@
 
   EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
               testing::UnorderedElementsAre(credential1, credential2));
-
-  form.times_used++;
+  form.password_value = u"new_password";
 
   PasswordStoreChangeList list;
   list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
   list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
   EXPECT_EQ(list, db().AddLogin(form));
+  EXPECT_THAT(db().insecure_credentials_table().GetAllRows(), IsEmpty());
+}
+
+TEST_F(LoginDatabaseTest, AddLoginWithInsecureCredentialsPersistsThem) {
+  PasswordForm form = GenerateExamplePasswordForm();
+  InsecureCredential leaked{form.signon_realm, form.username_value,
+                            base::Time(), InsecureType::kLeaked,
+                            IsMuted(false)};
+  InsecureCredential phished = leaked;
+  phished.insecure_type = InsecureType::kPhished;
+
+  form.password_value = u"new_password";
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  form.password_issues->insert_or_assign(
+      InsecureType::kLeaked,
+      InsecurityMetadata(leaked.create_time, leaked.is_muted));
+  form.password_issues->insert_or_assign(
+      InsecureType::kPhished,
+      InsecurityMetadata(phished.create_time, phished.is_muted));
+
+  PasswordStoreChangeList list;
+  list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
+  EXPECT_EQ(list, db().AddLogin(form));
   EXPECT_THAT(db().insecure_credentials_table().GetAllRows(),
-              testing::IsEmpty());
+              testing::UnorderedElementsAre(leaked, phished));
 }
 
 class LoginDatabaseForAccountStoreTest : public testing::Test {
diff --git a/components/password_manager/core/browser/password_form.cc b/components/password_manager/core/browser/password_form.cc
index db6294f3..19c086a 100644
--- a/components/password_manager/core/browser/password_form.cc
+++ b/components/password_manager/core/browser/password_form.cc
@@ -169,9 +169,13 @@
     hashes.push_back(gaia_id_hash.ToBase64());
   }
 
+  target->SetString("moving_blocked_for_list", base::JoinString(hashes, ", "));
+
+  if (!form.password_issues.has_value())
+    return;
   std::vector<base::Value> password_issues;
-  password_issues.reserve(form.password_issues.size());
-  for (const auto& issue : form.password_issues) {
+  password_issues.reserve(form.password_issues->size());
+  for (const auto& issue : form.password_issues.value()) {
     base::Value issue_value(base::Value::Type::DICTIONARY);
     issue_value.SetStringPath("insecurity_type", ToString(issue.first));
     issue_value.SetPath("create_time",
@@ -180,7 +184,7 @@
                             static_cast<bool>(issue.second.is_muted));
     password_issues.push_back(std::move(issue_value));
   }
-  target->SetString("moving_blocked_for_list", base::JoinString(hashes, ", "));
+
   target->SetPath("password_issues ", base::Value(password_issues));
 }
 
@@ -246,6 +250,12 @@
   return !password_value.empty() || !new_password_value.empty();
 }
 
+bool PasswordForm::IsInsecureCredential(InsecureType type) {
+  if (!password_issues.has_value())
+    return false;
+  return password_issues->find(type) != password_issues->end();
+}
+
 bool ArePasswordFormUniqueKeysEqual(const PasswordForm& left,
                                     const PasswordForm& right) {
   return (left.signon_realm == right.signon_realm && left.url == right.url &&
diff --git a/components/password_manager/core/browser/password_form.h b/components/password_manager/core/browser/password_form.h
index 0b676b6e..8d8dc882 100644
--- a/components/password_manager/core/browser/password_form.h
+++ b/components/password_manager/core/browser/password_form.h
@@ -60,6 +60,8 @@
   IsMuted is_muted{false};
 };
 
+bool operator==(const InsecurityMetadata& lhs, const InsecurityMetadata& rhs);
+
 // The PasswordForm struct encapsulates information about a login form,
 // which can be an HTML form or a dialog with username/password text fields.
 //
@@ -366,7 +368,10 @@
 
   // A mapping from the credential insecurity type (e.g. leaked, phished),
   // to its metadata (e.g. time it was discovered, whether alerts are muted).
-  base::flat_map<InsecureType, InsecurityMetadata> password_issues;
+  // Forms retrieved for the store always have a `password_issues` value.
+  // NOTE: If it is known that there are no issues, this should be an empty map.
+  absl::optional<base::flat_map<InsecureType, InsecurityMetadata>>
+      password_issues;
 
   // Return true if we consider this form to be a change password form and not
   // a signup form. It's based on local heuristics and may be inaccurate.
@@ -397,6 +402,10 @@
   // Returns true when |password_value| or |new_password_value| are non-empty.
   bool HasNonEmptyPasswordValue() const;
 
+  // Utility method to check whether the form represents an insecure credential
+  // of insecure type `type`.
+  bool IsInsecureCredential(InsecureType type);
+
   PasswordForm();
   PasswordForm(const PasswordForm& other);
   PasswordForm(PasswordForm&& other);
diff --git a/components/password_manager/core/browser/password_hash_data.cc b/components/password_manager/core/browser/password_hash_data.cc
index 2026703c..229d757 100644
--- a/components/password_manager/core/browser/password_hash_data.cc
+++ b/components/password_manager/core/browser/password_hash_data.cc
@@ -33,6 +33,9 @@
 
 PasswordHashData::PasswordHashData(const PasswordHashData& other) = default;
 
+PasswordHashData& PasswordHashData::operator=(const PasswordHashData& other) =
+    default;
+
 PasswordHashData::PasswordHashData(const std::string& username,
                                    const std::u16string& password,
                                    bool force_update,
diff --git a/components/password_manager/core/browser/password_hash_data.h b/components/password_manager/core/browser/password_hash_data.h
index 51a9012..f51a04a 100644
--- a/components/password_manager/core/browser/password_hash_data.h
+++ b/components/password_manager/core/browser/password_hash_data.h
@@ -16,6 +16,7 @@
 struct PasswordHashData {
   PasswordHashData();
   PasswordHashData(const PasswordHashData& other);
+  PasswordHashData& operator=(const PasswordHashData& other);
   PasswordHashData(const std::string& username,
                    const std::u16string& password,
                    bool force_update,
diff --git a/components/password_manager/core/browser/password_manager_test_utils.cc b/components/password_manager/core/browser/password_manager_test_utils.cc
index de18ce60..1bbe84e 100644
--- a/components/password_manager/core/browser/password_manager_test_utils.cc
+++ b/components/password_manager/core/browser/password_manager_test_utils.cc
@@ -14,6 +14,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/password_manager/core/browser/hash_password_manager.h"
+#include "components/password_manager/core/browser/password_form.h"
 
 namespace password_manager {
 
@@ -58,6 +59,7 @@
         url::Origin::Create(GURL("https://accounts.google.com/login"));
   }
   form->in_store = PasswordForm::Store::kProfileStore;
+  form->password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
   return form;
 }
 
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc
index f4e23f4..f507ccb 100644
--- a/components/password_manager/core/browser/password_store_unittest.cc
+++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -26,6 +26,7 @@
 #include "components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h"
 #include "components/password_manager/core/browser/form_parsing/form_parser.h"
 #include "components/password_manager/core/browser/insecure_credentials_consumer.h"
+#include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_reuse_detector.h"
 #include "components/password_manager/core/browser/password_reuse_manager.h"
diff --git a/components/password_manager/core/browser/ui/post_save_compromised_helper.cc b/components/password_manager/core/browser/ui/post_save_compromised_helper.cc
index 5a020d4c..26a14ca4 100644
--- a/components/password_manager/core/browser/ui/post_save_compromised_helper.cc
+++ b/components/password_manager/core/browser/ui/post_save_compromised_helper.cc
@@ -4,8 +4,8 @@
 
 #include "components/password_manager/core/browser/ui/post_save_compromised_helper.h"
 
+#include "base/barrier_closure.h"
 #include "base/containers/contains.h"
-#include "base/containers/cxx20_erase.h"
 #include "base/feature_list.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/common/password_manager_features.h"
@@ -51,34 +51,58 @@
   }
 
   callback_ = std::move(callback);
-  insecure_credentials_reader_ =
-      std::make_unique<InsecureCredentialsReader>(profile_store, account_store);
-  // Unretained(this) is safe here since `this` outlives
-  // `insecure_credentials_reader_`.
-  insecure_credentials_reader_->GetAllInsecureCredentials(
-      base::BindOnce(&PostSaveCompromisedHelper::OnGetAllInsecureCredentials,
-                     base::Unretained(this)));
+
+  int awaiting_callbacks = 1;
+  if (account_store)
+    awaiting_callbacks++;
+
+  forms_received_ = base::BarrierClosure(
+      awaiting_callbacks,
+      base::BindOnce(
+          &PostSaveCompromisedHelper::AnalyzeLeakedCredentialsInternal,
+          base::Unretained(this)));
+
+  profile_store->GetAutofillableLogins(this);
+  if (account_store)
+    account_store->GetAutofillableLogins(this);
 }
 
-void PostSaveCompromisedHelper::OnGetAllInsecureCredentials(
-    std::vector<InsecureCredential> insecure_credentials) {
-  const bool compromised_password_changed =
-      current_leak_ && !base::Contains(insecure_credentials, *current_leak_);
-  if (base::FeatureList::IsEnabled(features::kMutingCompromisedCredentials)) {
-    // We want to show bubble even if updated insecure credentials was muted,
-    // this is why muted credentials are erased after computing
-    // 'compromised_password_changed';
-    base::EraseIf(insecure_credentials,
-                  [](const auto& credential) { return credential.is_muted; });
+void PostSaveCompromisedHelper::OnGetPasswordStoreResults(
+    std::vector<std::unique_ptr<password_manager::PasswordForm>> results) {
+  base::ranges::move(results, std::back_inserter(passwords_));
+  forms_received_.Run();
+}
+
+void PostSaveCompromisedHelper::AnalyzeLeakedCredentialsInternal() {
+  bool compromised_password_changed = false;
+
+  for (const auto& form : passwords_) {
+    DCHECK(form->password_issues.has_value());
+    if (current_leak_ && form->username_value == current_leak_->username &&
+        form->signon_realm == current_leak_->signon_realm) {
+      if (form->password_issues->empty())
+        compromised_password_changed = true;
+    }
+    if (!form->password_issues->empty()) {
+      if (base::FeatureList::IsEnabled(
+              features::kMutingCompromisedCredentials)) {
+        if (std::any_of(
+                form->password_issues->begin(), form->password_issues->end(),
+                [](const auto& issue) { return !issue.second.is_muted; })) {
+          compromised_count_++;
+        }
+      } else {
+        compromised_count_++;
+      }
+    }
   }
   if (compromised_password_changed) {
-    bubble_type_ = insecure_credentials.empty()
+    bubble_type_ = compromised_count_ == 0
                        ? BubbleType::kPasswordUpdatedSafeState
                        : BubbleType::kPasswordUpdatedWithMoreToFix;
   } else {
     bubble_type_ = BubbleType::kNoBubble;
   }
-  compromised_count_ = insecure_credentials.size();
   std::move(callback_).Run(bubble_type_, compromised_count_);
 }
 
diff --git a/components/password_manager/core/browser/ui/post_save_compromised_helper.h b/components/password_manager/core/browser/ui/post_save_compromised_helper.h
index 161e47b..ae083c6c 100644
--- a/components/password_manager/core/browser/ui/post_save_compromised_helper.h
+++ b/components/password_manager/core/browser/ui/post_save_compromised_helper.h
@@ -10,7 +10,7 @@
 #include "base/callback.h"
 #include "base/containers/span.h"
 #include "components/password_manager/core/browser/insecure_credentials_table.h"
-#include "components/password_manager/core/browser/ui/insecure_credentials_reader.h"
+#include "components/password_manager/core/browser/password_store_consumer.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefService;
@@ -20,7 +20,8 @@
 class PasswordStore;
 
 // Helps to choose a compromised credential bubble after a password was saved.
-class PostSaveCompromisedHelper {
+class PostSaveCompromisedHelper
+    : public password_manager::PasswordStoreConsumer {
  public:
   enum class BubbleType {
     // No follow-up bubble should be shown.
@@ -40,7 +41,7 @@
   // |current_username| is the username that was just saved or updated.
   PostSaveCompromisedHelper(base::span<const InsecureCredential> compromised,
                             const std::u16string& current_username);
-  ~PostSaveCompromisedHelper();
+  ~PostSaveCompromisedHelper() override;
 
   PostSaveCompromisedHelper(const PostSaveCompromisedHelper&) = delete;
   PostSaveCompromisedHelper& operator=(const PostSaveCompromisedHelper&) =
@@ -57,8 +58,12 @@
   size_t compromised_count() const { return compromised_count_; }
 
  private:
-  void OnGetAllInsecureCredentials(
-      std::vector<InsecureCredential> insecure_credentials);
+  // PasswordStoreConsumer:
+  void OnGetPasswordStoreResults(
+      std::vector<std::unique_ptr<password_manager::PasswordForm>> results)
+      override;
+
+  void AnalyzeLeakedCredentialsInternal();
 
   // Contains the entry for the currently leaked credentials if it was leaked.
   absl::optional<InsecureCredential> current_leak_;
@@ -69,7 +74,10 @@
   // Count of compromised credentials after the callback was executed.
   size_t compromised_count_ = 0;
 
-  std::unique_ptr<InsecureCredentialsReader> insecure_credentials_reader_;
+  // Closure which is released after both PasswordStores reply with results.
+  base::RepeatingClosure forms_received_;
+
+  std::vector<std::unique_ptr<PasswordForm>> passwords_;
 };
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/ui/post_save_compromised_helper_unittest.cc b/components/password_manager/core/browser/ui/post_save_compromised_helper_unittest.cc
index 9d4776c..dbcd700 100644
--- a/components/password_manager/core/browser/ui/post_save_compromised_helper_unittest.cc
+++ b/components/password_manager/core/browser/ui/post_save_compromised_helper_unittest.cc
@@ -41,6 +41,22 @@
   return compromised;
 }
 
+// Creates a form.
+PasswordForm CreateForm(
+    base::StringPiece signon_realm,
+    base::StringPiece16 username,
+    PasswordForm::Store store = PasswordForm::Store::kProfileStore) {
+  PasswordForm form;
+  form.signon_realm = std::string(signon_realm);
+  form.username_value = std::u16string(username);
+  form.in_store = store;
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  form.password_issues = base::flat_map<InsecureType, InsecurityMetadata>();
+  return form;
+}
+
 }  // namespace
 
 class PostSaveCompromisedHelperTest : public testing::Test {
@@ -55,6 +71,17 @@
     mock_profile_store_->ShutdownOnUIThread();
   }
 
+  void ExpectGetLoginsCall(std::vector<PasswordForm> password_forms) {
+    EXPECT_CALL(*profile_store(), GetAutofillableLogins)
+        .WillOnce(testing::WithArg<0>([password_forms](
+                                          PasswordStoreConsumer* consumer) {
+          std::vector<std::unique_ptr<PasswordForm>> results;
+          for (auto& form : password_forms)
+            results.push_back(std::make_unique<PasswordForm>(std::move(form)));
+          consumer->OnGetPasswordStoreResults(std::move(results));
+        }));
+  }
+
   void WaitForPasswordStore() { task_environment_.RunUntilIdle(); }
 
   MockPasswordStore* profile_store() { return mock_profile_store_.get(); }
@@ -83,7 +110,7 @@
   PostSaveCompromisedHelper helper({}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kNoBubble, 0));
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl);
+  ExpectGetLoginsCall({});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -98,10 +125,9 @@
   PostSaveCompromisedHelper helper({}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kNoBubble, _));
-  std::vector<InsecureCredential> saved = {
-      CreateInsecureCredential(kUsername2)};
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+
+  PasswordForm form = CreateForm(kSignonRealm, kUsername2);
+  ExpectGetLoginsCall({form});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -112,14 +138,16 @@
   prefs()->SetDouble(
       kLastTimePasswordCheckCompleted,
       (base::Time::Now() - base::TimeDelta::FromMinutes(1)).ToDoubleT());
-  std::vector<InsecureCredential> saved = {
-      CreateInsecureCredential(kUsername),
-      CreateInsecureCredential(kUsername2)};
-  PostSaveCompromisedHelper helper({saved}, kUsername);
+  PasswordForm form1 = CreateForm(kSignonRealm, kUsername);
+  form1.password_issues->insert({InsecureType::kLeaked, InsecurityMetadata()});
+  PasswordForm form2 = CreateForm(kSignonRealm, kUsername2);
+  form2.password_issues->insert({InsecureType::kLeaked, InsecurityMetadata()});
+
+  PostSaveCompromisedHelper helper({{CreateInsecureCredential(kUsername)}},
+                                   kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
-  EXPECT_CALL(callback, Run(BubbleType::kNoBubble, _));
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+  ExpectGetLoginsCall({form1, form2});
+  EXPECT_CALL(callback, Run(BubbleType::kNoBubble, 2));
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -133,12 +161,15 @@
   std::vector<InsecureCredential> saved = {
       CreateInsecureCredential(kUsername),
       CreateInsecureCredential(kUsername2)};
+
+  PasswordForm form1 = CreateForm(kSignonRealm, kUsername);
+  PasswordForm form2 = CreateForm(kSignonRealm, kUsername2);
+  form2.password_issues->insert({InsecureType::kLeaked, InsecurityMetadata()});
+
   PostSaveCompromisedHelper helper({saved}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kPasswordUpdatedWithMoreToFix, 1));
-  saved = {CreateInsecureCredential(kUsername2)};
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+  ExpectGetLoginsCall({form1, form2});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -147,11 +178,11 @@
 }
 
 TEST_F(PostSaveCompromisedHelperTest, FixedLast_BulkCheckNeverDone) {
-  std::vector<InsecureCredential> saved = {CreateInsecureCredential(kUsername)};
-  PostSaveCompromisedHelper helper({saved}, kUsername);
+  PostSaveCompromisedHelper helper({{CreateInsecureCredential(kUsername)}},
+                                   kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kNoBubble, 0));
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl).Times(0);
+  EXPECT_CALL(*profile_store(), GetAutofillableLogins).Times(0);
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -167,7 +198,7 @@
   PostSaveCompromisedHelper helper({saved}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kNoBubble, 0));
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl).Times(0);
+  EXPECT_CALL(*profile_store(), GetAutofillableLogins).Times(0);
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -183,9 +214,7 @@
   PostSaveCompromisedHelper helper({saved}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kPasswordUpdatedSafeState, 0));
-  saved = {};
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+  ExpectGetLoginsCall({CreateForm(kSignonRealm, kUsername)});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -206,9 +235,7 @@
   PostSaveCompromisedHelper helper({saved}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kPasswordUpdatedSafeState, 0));
-  saved = {};
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+  ExpectGetLoginsCall({CreateForm(kSignonRealm, kUsername)});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -228,13 +255,14 @@
   PostSaveCompromisedHelper helper({saved}, kUsername);
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kPasswordUpdatedWithMoreToFix, 1));
-  saved = {
-      CreateInsecureCredential(kUsername2),
-      CreateInsecureCredential(kUsername3, PasswordForm::Store::kProfileStore,
-                               IsMuted(true)),
-  };
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(saved));
+  PasswordForm form1 = CreateForm(kSignonRealm, kUsername);
+  PasswordForm form2 = CreateForm(kSignonRealm, kUsername2);
+  form2.password_issues->insert({InsecureType::kLeaked, InsecurityMetadata()});
+  PasswordForm form3 = CreateForm(kSignonRealm, kUsername3);
+  form3.password_issues->insert(
+      {InsecureType::kLeaked, InsecurityMetadata(base::Time(), IsMuted(true))});
+
+  ExpectGetLoginsCall({form1, form2, form3});
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
                                   callback.Get());
   WaitForPasswordStore();
@@ -280,12 +308,24 @@
       account_store_compromised_credential};
 
   PostSaveCompromisedHelper helper({compromised_credentials}, kUsername);
-  EXPECT_CALL(*profile_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(std::vector<InsecureCredential>{
-          profile_store_compromised_credential}));
-  EXPECT_CALL(*account_store(), GetAllInsecureCredentialsImpl)
-      .WillOnce(Return(std::vector<InsecureCredential>{
-          account_store_compromised_credential}));
+  EXPECT_CALL(*profile_store(), GetAutofillableLogins)
+      .WillOnce(testing::WithArg<0>([](PasswordStoreConsumer* consumer) {
+        std::vector<std::unique_ptr<PasswordForm>> results;
+        results.push_back(std::make_unique<PasswordForm>(
+            CreateForm(kSignonRealm, kUsername)));
+        results.back()->password_issues->insert(
+            {InsecureType::kLeaked, InsecurityMetadata()});
+        consumer->OnGetPasswordStoreResults(std::move(results));
+      }));
+  EXPECT_CALL(*account_store(), GetAutofillableLogins)
+      .WillOnce(testing::WithArg<0>([](PasswordStoreConsumer* consumer) {
+        std::vector<std::unique_ptr<PasswordForm>> results;
+        results.push_back(std::make_unique<PasswordForm>(CreateForm(
+            kSignonRealm, kUsername, PasswordForm::Store::kAccountStore)));
+        results.back()->password_issues->insert(
+            {InsecureType::kLeaked, InsecurityMetadata()});
+        consumer->OnGetPasswordStoreResults(std::move(results));
+      }));
   base::MockCallback<PostSaveCompromisedHelper::BubbleCallback> callback;
   EXPECT_CALL(callback, Run(BubbleType::kNoBubble, _));
   helper.AnalyzeLeakedCredentials(profile_store(), account_store(), prefs(),
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc
index 2cf67a7f..c282692 100644
--- a/components/password_manager/core/common/password_manager_features.cc
+++ b/components/password_manager/core/common/password_manager_features.cc
@@ -16,11 +16,6 @@
 const base::Feature kBiometricTouchToFill = {"BiometricTouchToFill",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enables creating Affiliation Service and prefetching change password info for
-// requested sites.
-const base::Feature kChangePasswordAffiliationInfo = {
-    "ChangePasswordAffiliationInfo", base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enables submission detection for forms dynamically cleared but not removed
 // from the page.
 const base::Feature kDetectFormSubmissionOnFormClear = {
diff --git a/components/password_manager/core/common/password_manager_features.h b/components/password_manager/core/common/password_manager_features.h
index 0774350c..c9a57983 100644
--- a/components/password_manager/core/common/password_manager_features.h
+++ b/components/password_manager/core/common/password_manager_features.h
@@ -18,7 +18,6 @@
 // alongside the definition of their values in the .cc file.
 
 extern const base::Feature kBiometricTouchToFill;
-extern const base::Feature kChangePasswordAffiliationInfo;
 extern const base::Feature kEditPasswordsInSettings;
 extern const base::Feature kDetectFormSubmissionOnFormClear;
 extern const base::Feature kEnableManualPasswordGeneration;
diff --git a/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml b/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml
index 97208a7..4de376c5 100644
--- a/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml
+++ b/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml
@@ -3,14 +3,10 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:textDirection="locale"
-    android:orientation="vertical"
-    android:paddingHorizontal="@dimen/secure_payment_confirmation_authn_ui_horizontal_padding"
-    android:paddingBottom="@dimen/secure_payment_confirmation_authn_ui_vertical_padding">
+    android:layout_width="match_parent">
 
     <!-- Drag handlebar -->
     <ImageView
@@ -19,125 +15,161 @@
         android:layout_gravity="center_horizontal"
         android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_drag_handle_spacing"
         android:importantForAccessibility="no"
+        android:layout_centerHorizontal="true"
         android:src="@drawable/drag_handlebar" />
 
-    <!-- Shopping cart image -->
-    <ImageView
-        android:id="@+id/secure_payment_confirmation_image"
-        android:importantForAccessibility="no"
+    <ScrollView
+        android:id="@+id/scroll_view"
         android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:scaleType="centerInside"/>
+        android:layout_width="match_parent">
 
-    <!-- "Verify your purchase" label. -->
-    <TextView
-        android:layout_height="wrap_content"
-        android:layout_width="fill_parent"
-        android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"
-        android:gravity="center_horizontal"
-        android:textAppearance="@style/TextAppearance.Headline.Primary"
-        android:text="@string/secure_payment_confirmation_verify_purchase"/>
-
-    <LinearLayout
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:paddingBottom="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"
-        android:orientation="vertical"
-        android:showDividers="middle|end"
-        android:divider="?android:listDivider">
-
-        <!-- "Store" row -->
-        <LinearLayout
+        <RelativeLayout
             android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
+            android:textDirection="locale"
+            android:paddingHorizontal="@dimen/secure_payment_confirmation_authn_ui_horizontal_padding"
             android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding">
 
+            <!-- Shopping cart image -->
+            <ImageView
+                android:id="@+id/secure_payment_confirmation_image"
+                android:importantForAccessibility="no"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:scaleType="centerInside"/>
+
+            <!-- "Verify your purchase" label -->
             <TextView
+                android:id="@+id/secure_payment_confirmation_title"
+                android:layout_below="@id/secure_payment_confirmation_image"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_marginBottom="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"
+                android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"
+                android:layout_centerHorizontal="true"
+                android:textAppearance="@style/TextAppearance.Headline.Primary"
+                android:text="@string/secure_payment_confirmation_verify_purchase"/>
+
+            <!-- "Store" label -->
+            <TextView
+                android:id="@+id/store_label"
+                android:layout_alignParentStart="true"
+                android:layout_below="@id/secure_payment_confirmation_title"
                 android:layout_height="wrap_content"
                 android:layout_width="@dimen/secure_payment_confirmation_authn_ui_label_size"
                 android:textAppearance="@style/TextAppearance.TextMediumThick.Primary"
                 android:text="@string/secure_payment_confirmation_store_label"/>
 
+            <!-- "Store" field -->
             <TextView
                 android:id="@+id/store"
+                android:layout_toEndOf="@id/store_label"
+                android:layout_below="@id/secure_payment_confirmation_title"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:textAppearance="@style/TextAppearance.TextMedium.Primary"/>
 
-        </LinearLayout>
+            <!-- "Store" row divider -->
+            <View
+                style="@style/HorizontalDivider"
+                android:id="@+id/store_divider"
+                android:layout_below="@id/store_label"
+                android:layout_marginVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"/>
 
-        <!-- "Payment" row -->
-        <LinearLayout
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:gravity="center_vertical"
-            android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding">
-
-            <TextView
-                android:layout_height="wrap_content"
-                android:layout_width="@dimen/secure_payment_confirmation_authn_ui_label_size"
-                android:textAppearance="@style/TextAppearance.TextMediumThick.Primary"
-                android:text="@string/payment_request_payment_method_section_name"/>
-
-            <ImageView
-                android:id="@+id/payment_icon"
-                android:importantForAccessibility="no"
-                android:layout_height="@dimen/secure_payment_confirmation_authn_ui_icon_size"
-                android:layout_width="@dimen/secure_payment_confirmation_authn_ui_icon_size"
-                android:scaleType="centerCrop"/>
-
-            <TextView
-                android:id="@+id/payment"
+            <!-- "Payment" row -->
+            <LinearLayout
+                android:id="@+id/payment_row"
+                android:layout_alignParentStart="true"
+                android:layout_below="@id/store_divider"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
-                android:paddingHorizontal="@dimen/secure_payment_confirmation_authn_ui_payment_icon_label_spacing"
-                android:textAppearance="@style/TextAppearance.TextMedium.Primary"/>
+                android:gravity="center_vertical">
 
-        </LinearLayout>
+                <TextView
+                    android:layout_height="wrap_content"
+                    android:layout_width="@dimen/secure_payment_confirmation_authn_ui_label_size"
+                    android:textAppearance="@style/TextAppearance.TextMediumThick.Primary"
+                    android:text="@string/payment_request_payment_method_section_name"/>
 
-        <!-- "Total" row -->
-        <LinearLayout
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:paddingVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding">
+                <ImageView
+                    android:id="@+id/payment_icon"
+                    android:importantForAccessibility="no"
+                    android:layout_height="@dimen/secure_payment_confirmation_authn_ui_icon_size"
+                    android:layout_width="@dimen/secure_payment_confirmation_authn_ui_icon_size"
+                    android:scaleType="centerCrop"/>
 
+                <TextView
+                    android:id="@+id/payment"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:paddingHorizontal="@dimen/secure_payment_confirmation_authn_ui_payment_icon_label_spacing"
+                    android:textAppearance="@style/TextAppearance.TextMedium.Primary"/>
+
+            </LinearLayout>
+
+            <!-- "Payment" row divider -->
+            <View
+                style="@style/HorizontalDivider"
+                android:id="@+id/payment_divider"
+                android:layout_below="@id/payment_row"
+                android:layout_marginVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"/>
+
+            <!-- "Total" label -->
             <TextView
+                android:id="@+id/total_label"
+                android:layout_alignParentStart="true"
+                android:layout_below="@id/payment_divider"
                 android:layout_height="wrap_content"
                 android:layout_width="@dimen/secure_payment_confirmation_authn_ui_label_size"
                 android:textAppearance="@style/TextAppearance.TextMediumThick.Primary"
                 android:text="@string/secure_payment_confirmation_total_label"/>
 
+            <!-- "Total" field -->
             <TextView
                 android:id="@+id/total"
+                android:layout_toEndOf="@id/total_label"
+                android:layout_below="@id/payment_divider"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:textAppearance="@style/TextAppearance.TextMedium.Primary"/>
 
+            <!-- "Currency" field -->
             <TextView
                 android:id="@+id/currency"
+                android:layout_toEndOf="@id/total"
+                android:layout_below="@id/payment_divider"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:paddingHorizontal="@dimen/secure_payment_confirmation_authn_ui_amount_currency_spacing"
                 android:textAppearance="@style/TextAppearance.TextMedium.Primary"/>
 
-        </LinearLayout>
+            <!-- "Total" row divider -->
+            <View
+                style="@style/HorizontalDivider"
+                android:id="@+id/total_divider"
+                android:layout_below="@id/total_label"
+                android:layout_marginVertical="@dimen/secure_payment_confirmation_authn_ui_vertical_padding"/>
 
-    </LinearLayout>
+            <!-- "Continue" button -->
+            <org.chromium.ui.widget.ButtonCompat
+                android:id="@+id/continue_button"
+                android:layout_below="@id/total_divider"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:text="@string/payments_continue_button"
+                style="@style/FilledButton.Flat"/>
 
-    <!-- "Continue" button -->
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/continue_button"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:text="@string/payments_continue_button"
-        style="@style/FilledButton.Flat"/>
+            <!-- "Cancel" button -->
+            <org.chromium.ui.widget.ButtonCompat
+                android:id="@+id/cancel_button"
+                android:layout_below="@id/continue_button"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:text="@string/cancel"
+                style="@style/TextButton"/>
 
-    <!-- "Cancel" button -->
-    <org.chromium.ui.widget.ButtonCompat
-        android:id="@+id/cancel_button"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:text="@string/cancel"
-        style="@style/TextButton"/>
+        </RelativeLayout>
 
-</LinearLayout>
+    </ScrollView>
+
+</RelativeLayout>
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnController.java b/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnController.java
index 4005d8e..61f39c2 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnController.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnController.java
@@ -59,6 +59,10 @@
 
         @Override
         public int getVerticalScrollOffset() {
+            if (mView != null) {
+                return mView.getScrollY();
+            }
+
             return 0;
         }
 
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnView.java b/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnView.java
index 8d33bf8..7880ae7 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnView.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/spcauthn/SecurePaymentConfirmationAuthnView.java
@@ -3,12 +3,14 @@
 // found in the LICENSE file.
 
 package org.chromium.components.payments.spcauthn;
+
 import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.ScrollView;
 import android.widget.TextView;
 
 import org.chromium.components.payments.R;
@@ -19,7 +21,8 @@
  * payment details and provides the option to continue with the payment or to cancel.
  */
 /* package */ class SecurePaymentConfirmationAuthnView {
-    private final LinearLayout mContentView;
+    private final RelativeLayout mContentView;
+    private final ScrollView mScrollView;
 
     /* package */ final ImageView mHeaderImage;
     /* package */ final TextView mStoreOrigin;
@@ -31,9 +34,10 @@
     /* package */ final Button mCancelButton;
 
     /* package */ SecurePaymentConfirmationAuthnView(Context context) {
-        mContentView = (LinearLayout) LayoutInflater.from(context).inflate(
+        mContentView = (RelativeLayout) LayoutInflater.from(context).inflate(
                 R.layout.secure_payment_confirmation_authn_ui, null);
 
+        mScrollView = (ScrollView) mContentView.findViewById(R.id.scroll_view);
         mHeaderImage =
                 (ImageView) mContentView.findViewById(R.id.secure_payment_confirmation_image);
         mStoreOrigin = (TextView) mContentView.findViewById(R.id.store);
@@ -50,4 +54,8 @@
     /* package */ View getContentView() {
         return mContentView;
     }
+
+    /* package */ int getScrollY() {
+        return mScrollView.getScrollY();
+    }
 }
diff --git a/components/payments/content/payment_method_manifest_table.cc b/components/payments/content/payment_method_manifest_table.cc
index 03e9ce6..0957f644 100644
--- a/components/payments/content/payment_method_manifest_table.cc
+++ b/components/payments/content/payment_method_manifest_table.cc
@@ -154,8 +154,7 @@
                                 "WHERE credential_id=? "
                                 "AND relying_party_id<>?"));
     int index = 0;
-    if (!s0.BindBlob(index++, instrument.credential_id.data(),
-                     instrument.credential_id.size()))
+    if (!s0.BindBlob(index++, instrument.credential_id))
       return false;
 
     if (!s0.BindString(index++, instrument.relying_party_id))
@@ -169,8 +168,7 @@
     sql::Statement s1(db_->GetUniqueStatement(
         "DELETE FROM secure_payment_confirmation_instrument "
         "WHERE credential_id=?"));
-    if (!s1.BindBlob(0, instrument.credential_id.data(),
-                     instrument.credential_id.size()))
+    if (!s1.BindBlob(0, instrument.credential_id))
       return false;
 
     if (!s1.Run())
@@ -183,8 +181,7 @@
         "(credential_id, relying_party_id, label, icon) "
         "VALUES (?, ?, ?, ?)"));
     int index = 0;
-    if (!s2.BindBlob(index++, instrument.credential_id.data(),
-                     instrument.credential_id.size()))
+    if (!s2.BindBlob(index++, instrument.credential_id))
       return false;
 
     if (!s2.BindString(index++, instrument.relying_party_id))
@@ -193,7 +190,7 @@
     if (!s2.BindString16(index++, instrument.label))
       return false;
 
-    if (!s2.BindBlob(index++, instrument.icon.data(), instrument.icon.size()))
+    if (!s2.BindBlob(index++, instrument.icon))
       return false;
 
     if (!s2.Run())
@@ -221,7 +218,7 @@
     if (credential_id.empty())
       continue;
 
-    if (!s.BindBlob(0, credential_id.data(), credential_id.size()))
+    if (!s.BindBlob(0, credential_id))
       continue;
 
     if (!s.Step())
diff --git a/components/payments/content/web_app_manifest_section_table.cc b/components/payments/content/web_app_manifest_section_table.cc
index 678fbb3..b7a9b54 100644
--- a/components/payments/content/web_app_manifest_section_table.cc
+++ b/components/payments/content/web_app_manifest_section_table.cc
@@ -140,8 +140,7 @@
     s2.BindInt64(index++, section.min_version);
     std::unique_ptr<std::vector<uint8_t>> serialized_fingerprints =
         SerializeFingerPrints(section.fingerprints);
-    s2.BindBlob(index, serialized_fingerprints->data(),
-                serialized_fingerprints->size());
+    s2.BindBlob(index, *serialized_fingerprints);
     if (!s2.Run())
       return false;
     s2.Reset(true);
diff --git a/components/permissions/features.cc b/components/permissions/features.cc
index 74d2abf..05ff442 100644
--- a/components/permissions/features.cc
+++ b/components/permissions/features.cc
@@ -32,6 +32,12 @@
 const base::Feature kPermissionChip{"PermissionChip",
                                     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables an experimental less prominent permission prompt that uses a chip in
+// the location bar. Requires chrome://flags/#quiet-notification-prompts to be
+// enabled.
+const base::Feature kPermissionQuietChip{"PermissionQuietChip",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kPermissionChipAutoDismiss{
     "PermissionChipAutoDismiss", base::FEATURE_ENABLED_BY_DEFAULT};
 const base::FeatureParam<int> kPermissionChipAutoDismissDelay{
diff --git a/components/permissions/features.h b/components/permissions/features.h
index 3deda9a..81feb02b 100644
--- a/components/permissions/features.h
+++ b/components/permissions/features.h
@@ -28,6 +28,9 @@
 extern const base::Feature kPermissionChip;
 
 COMPONENT_EXPORT(PERMISSIONS_COMMON)
+extern const base::Feature kPermissionQuietChip;
+
+COMPONENT_EXPORT(PERMISSIONS_COMMON)
 extern const base::Feature kPermissionChipAutoDismiss;
 
 COMPONENT_EXPORT(PERMISSIONS_COMMON)
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc
index fdd8ca13..3361f64 100644
--- a/components/permissions/permission_request_manager.cc
+++ b/components/permissions/permission_request_manager.cc
@@ -69,6 +69,35 @@
 
 namespace {
 
+// When there are multiple permissions requests in `queued_requests_`, we try to
+// reorder them based on the acceptance rates. Notifications and Geolocations
+// have one of the lowest acceptance, hence they have the lowest priority and
+// will be shown the last.
+bool IsLowPriorityRequest(PermissionRequest* request) {
+  return request->GetRequestType() == RequestType::kNotifications ||
+         request->GetRequestType() == RequestType::kGeolocation;
+}
+
+// In case of multiple permission requests that use chip UI, a newly added
+// request will preempt the currently showing request, which is put back to the
+// queue, and will be shown later. To reduce user annoyance, if a quiet chip
+// permission prompt was displayed longer than `kQuietChipIgnoreTimeout`, we
+// consider it as shown long enough and it will not be shown again after it is
+// preempted.
+// TODO(crbug.com/1221083): If a user switched tabs, do not include that time as
+// "shown".
+bool ShouldShowQuietRequestAgainIfPreempted(
+    absl::optional<base::Time> request_display_start_time) {
+  if (request_display_start_time->is_null()) {
+    return true;
+  }
+
+  static constexpr base::TimeDelta kQuietChipIgnoreTimeout =
+      base::TimeDelta::FromSecondsD(8.5);
+  return base::Time::Now() - request_display_start_time.value() <
+         kQuietChipIgnoreTimeout;
+}
+
 bool IsMediaRequest(RequestType type) {
 #if !defined(OS_ANDROID)
   if (type == RequestType::kCameraPanTiltZoom)
@@ -216,24 +245,16 @@
         base::UserMetricsAction("PermissionBubbleIFrameRequestQueued"));
   }
 
-  if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
-    // Because the requests are shown in a different order for Chip, pending
-    // requests are returned back to queued_requests_ to process them after the
-    // new requests.
-    ResetViewStateForCurrentRequest();
-    for (auto* request : requests_)
-      queued_requests_.push_back(request);
-    requests_.clear();
+  CurrentRequestFate current_request_fate =
+      GetCurrentRequestFateInFaceOfNewRequest(request);
+
+  if (current_request_fate == CurrentRequestFate::Preempt) {
+    PreemptAndRequeueCurrentRequest();
   }
 
-  queued_requests_.push_back(request);
-  request_sources_map_.emplace(
-      request, PermissionRequestSource({source_frame->GetProcess()->GetID(),
-                                        source_frame->GetRoutingID()}));
+  QueueRequest(source_frame, request);
 
-  // If we're displaying a quiet permission request, kill it in favor of this
-  // permission request.
-  if (ShouldCurrentRequestUseQuietUI()) {
+  if (current_request_fate == CurrentRequestFate::Finalize) {
     // FinalizeCurrentRequests will call ScheduleDequeueRequest on its own.
     FinalizeCurrentRequests(PermissionAction::IGNORED);
   } else {
@@ -241,6 +262,58 @@
   }
 }
 
+PermissionRequestManager::CurrentRequestFate
+PermissionRequestManager::GetCurrentRequestFateInFaceOfNewRequest(
+    PermissionRequest* new_request) {
+  if (base::FeatureList::IsEnabled(features::kPermissionQuietChip)) {
+    if (ShouldCurrentRequestUseQuietUI() &&
+        !ShouldShowQuietRequestAgainIfPreempted(
+            current_request_first_display_time_)) {
+      return CurrentRequestFate::Finalize;
+    }
+
+    if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
+      // Preempt current request if it is a quiet UI request or it is not
+      // Notifications or Geolocation.
+      if (ShouldCurrentRequestUseQuietUI() ||
+          !IsLowPriorityRequest(new_request)) {
+        return CurrentRequestFate::Preempt;
+      }
+    } else {
+      if (ShouldCurrentRequestUseQuietUI()) {
+        return CurrentRequestFate::Preempt;
+      }
+    }
+  } else {
+    if (base::FeatureList::IsEnabled(features::kPermissionChip)) {
+      return CurrentRequestFate::Preempt;
+    } else if (ShouldCurrentRequestUseQuietUI()) {
+      // If we're displaying a quiet permission request, ignore it in favor of a
+      // new permission request.
+      return CurrentRequestFate::Finalize;
+    }
+  }
+
+  return CurrentRequestFate::KeepCurrent;
+}
+
+void PermissionRequestManager::QueueRequest(
+    content::RenderFrameHost* source_frame,
+    PermissionRequest* request) {
+  PushQueuedRequest(request);
+  request_sources_map_.emplace(
+      request, PermissionRequestSource({source_frame->GetProcess()->GetID(),
+                                        source_frame->GetRoutingID()}));
+}
+
+void PermissionRequestManager::PreemptAndRequeueCurrentRequest() {
+  ResetViewStateForCurrentRequest();
+  for (auto* current_request : requests_) {
+    PushQueuedRequest(current_request);
+  }
+  requests_.clear();
+}
+
 void PermissionRequestManager::UpdateAnchor() {
   if (view_) {
     // When the prompt's anchor is being updated, the prompt view can be
@@ -263,7 +336,8 @@
   // browser-initiated navigation.
   //
   // TODO(crbug.com/952347): This check has to be done at DidStartNavigation
-  // time, the HasUserGesture state is lost by the time the navigation commits.
+  // time, the HasUserGesture state is lost by the time the navigation
+  // commits.
   if (!navigation_handle->IsRendererInitiated() ||
       navigation_handle->HasUserGesture()) {
     is_notification_prompt_cooldown_active_ = false;
@@ -313,8 +387,8 @@
   CleanUpRequests();
 
   // The WebContents is going away; be aggressively paranoid and delete
-  // ourselves lest other parts of the system attempt to add permission bubbles
-  // or use us otherwise during the destruction.
+  // ourselves lest other parts of the system attempt to add permission
+  // bubbles or use us otherwise during the destruction.
   web_contents()->RemoveUserData(UserDataKey());
   // That was the equivalent of "delete this". This object is now destroyed;
   // returning from this function is the only safe thing to do.
@@ -388,7 +462,8 @@
   std::vector<PermissionRequest*>::iterator requests_iter;
   for (requests_iter = requests_.begin(); requests_iter != requests_.end();
        requests_iter++) {
-    PermissionGrantedIncludingDuplicates(*requests_iter, /*is_one_time=*/false);
+    PermissionGrantedIncludingDuplicates(*requests_iter,
+                                         /*is_one_time=*/false);
   }
   FinalizeCurrentRequests(PermissionAction::GRANTED);
 }
@@ -400,7 +475,8 @@
   std::vector<PermissionRequest*>::iterator requests_iter;
   for (requests_iter = requests_.begin(); requests_iter != requests_.end();
        requests_iter++) {
-    PermissionGrantedIncludingDuplicates(*requests_iter, /*is_one_time=*/true);
+    PermissionGrantedIncludingDuplicates(*requests_iter,
+                                         /*is_one_time=*/true);
   }
   FinalizeCurrentRequests(PermissionAction::GRANTED_ONCE);
 }
@@ -411,9 +487,10 @@
   DCHECK(view_);
 
   // Suppress any further prompts in this WebContents, from any origin, until
-  // there is a user-initiated navigation. This stops users from getting trapped
-  // in request loops where the website automatically navigates cross-origin
-  // (e.g. to another subdomain) to be able to prompt again after a rejection.
+  // there is a user-initiated navigation. This stops users from getting
+  // trapped in request loops where the website automatically navigates
+  // cross-origin (e.g. to another subdomain) to be able to prompt again after
+  // a rejection.
   if (base::FeatureList::IsEnabled(
           features::kBlockRepeatedNotificationPermissionPrompts) &&
       std::any_of(requests_.begin(), requests_.end(), [](const auto* request) {
@@ -468,9 +545,9 @@
 
 void PermissionRequestManager::DequeueRequestIfNeeded() {
   // TODO(olesiamarukhno): Media requests block other media requests from
-  // pre-empting them. For example, when a camera request is pending and mic is
-  // requested, the camera request remains pending and mic request appears only
-  // after the camera request is resolved. This is caused by code in
+  // pre-empting them. For example, when a camera request is pending and mic
+  // is requested, the camera request remains pending and mic request appears
+  // only after the camera request is resolved. This is caused by code in
   // PermissionBubbleMediaAccessHandler and UserMediaClient. We probably don't
   // need two permission queues, so resolve the duplication.
 
@@ -548,8 +625,9 @@
 }
 
 void PermissionRequestManager::ShowBubble() {
-  // There is a race condition where the request might have been removed already
-  // so double-checking that there is a request in progress (crbug.com/1041222).
+  // There is a race condition where the request might have been removed
+  // already so double-checking that there is a request in progress
+  // (crbug.com/1041222).
   if (!IsRequestInProgress())
     return;
 
@@ -562,8 +640,12 @@
     return;
 
   view_ = view_factory_.Run(web_contents(), this);
-  if (!view_)
+  if (!view_) {
+    current_request_prompt_disposition_ =
+        PermissionPromptDisposition::NONE_VISIBLE;
+    FinalizeCurrentRequests(PermissionAction::IGNORED);
     return;
+  }
 
   current_request_prompt_disposition_ = view_->GetPromptDisposition();
 
@@ -645,9 +727,9 @@
     quiet_ui_reason = ReasonForUsingQuietUi();
 
   for (PermissionRequest* request : requests_) {
-    // TODO(timloh): We only support dismiss and ignore embargo for permissions
-    // which use PermissionRequestImpl as the other subclasses don't support
-    // GetContentSettingsType.
+    // TODO(timloh): We only support dismiss and ignore embargo for
+    // permissions which use PermissionRequestImpl as the other subclasses
+    // don't support GetContentSettingsType.
     if (request->GetContentSettingsType() == ContentSettingsType::DEFAULT)
       continue;
 
@@ -776,7 +858,8 @@
 
 bool PermissionRequestManager::ShouldCurrentRequestUseQuietUI() const {
   // ContentSettingImageModel might call into this method if the user switches
-  // between tabs while the |notification_permission_ui_selectors_| are pending.
+  // between tabs while the |notification_permission_ui_selectors_| are
+  // pending.
   return ReasonForUsingQuietUi() != absl::nullopt;
 }
 
@@ -793,6 +876,23 @@
   return !requests_.empty();
 }
 
+bool PermissionRequestManager::ShouldDropCurrentRequestIfCannotShowQuietly() {
+  absl::optional<QuietUiReason> quiet_ui_reason = ReasonForUsingQuietUi();
+  if (quiet_ui_reason.has_value()) {
+    switch (quiet_ui_reason.value()) {
+      case QuietUiReason::kEnabledInPrefs:
+      case QuietUiReason::kPredictedVeryUnlikelyGrant:
+      case QuietUiReason::kTriggeredByCrowdDeny:
+        return false;
+      case QuietUiReason::kTriggeredDueToAbusiveRequests:
+      case QuietUiReason::kTriggeredDueToAbusiveContent:
+        return true;
+    }
+  }
+
+  return false;
+}
+
 void PermissionRequestManager::NotifyBubbleAdded() {
   for (Observer& observer : observer_list_)
     observer.OnBubbleAdded();
@@ -918,6 +1018,15 @@
   return next;
 }
 
+void PermissionRequestManager::PushQueuedRequest(PermissionRequest* request) {
+  if (base::FeatureList::IsEnabled(features::kPermissionQuietChip) &&
+      !base::FeatureList::IsEnabled(features::kPermissionChip)) {
+    queued_requests_.push_front(request);
+  } else {
+    queued_requests_.push_back(request);
+  }
+}
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(PermissionRequestManager)
 
 }  // namespace permissions
diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h
index 4442cb80..5923513 100644
--- a/components/permissions/permission_request_manager.h
+++ b/components/permissions/permission_request_manager.h
@@ -123,6 +123,10 @@
 
   bool IsRequestInProgress() const;
 
+  // If the LocationBar is not visible, there is no place to display a quiet
+  // permission prompt. Abusive prompts will be ignored.
+  bool ShouldDropCurrentRequestIfCannotShowQuietly();
+
   // Do NOT use this methods in production code. Use this methods in browser
   // tests that need to accept or deny permissions when requested in
   // JavaScript. Your test needs to set this appropriately, and then the bubble
@@ -184,6 +188,10 @@
 
   PermissionPrompt* view_for_testing() { return view_.get(); }
 
+  void set_current_request_first_display_time_for_testing(base::Time time) {
+    current_request_first_display_time_ = time;
+  }
+
   absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
   prediction_grant_likelihood_for_testing() {
     return prediction_grant_likelihood_;
@@ -200,6 +208,23 @@
 
   explicit PermissionRequestManager(content::WebContents* web_contents);
 
+  enum class CurrentRequestFate { KeepCurrent, Preempt, Finalize };
+
+  // Returns `CurrentRequestFate` based on what type of UI has been shown for
+  // `requests_`.
+  CurrentRequestFate GetCurrentRequestFateInFaceOfNewRequest(
+      PermissionRequest* request);
+
+  // Adds `request` into `queued_requests_`, and request's `source_frame` into
+  // `request_sources_map_`.
+  void QueueRequest(content::RenderFrameHost* source_frame,
+                    PermissionRequest* request);
+
+  // Because the requests are shown in a different order for Normal and Quiet
+  // Chip, pending requests are returned back to queued_requests_ to process
+  // them after the new requests.
+  void PreemptAndRequeueCurrentRequest();
+
   // Posts a task which will allow the bubble to become visible.
   void ScheduleShowBubble();
 
@@ -293,12 +318,20 @@
     bool IsSourceFrameInactiveAndDisallowActivation() const;
   };
 
-  base::circular_deque<PermissionRequest*> queued_requests_;
-
   PermissionRequest* PeekNextQueuedRequest();
 
   PermissionRequest* PopNextQueuedRequest();
 
+  // Encapsulate enqueuing `request` into `queued_requests_`. Based on the chip
+  // / quiet chip experiments, the `request` is added into the back or front of
+  // the queue.
+  void PushQueuedRequest(PermissionRequest* request);
+
+  // TODO(crbug.com/1221150): Create a separate entity to handle Enqueue /
+  // Dequeue with all edge cases. Expose to `PermissionRequestManager` only a
+  // clear API like `Peek()` and `Pop()`, etc.
+  base::circular_deque<PermissionRequest*> queued_requests_;
+
   // Maps from the first request of a kind to subsequent requests that were
   // duped against it.
   std::unordered_multimap<PermissionRequest*, PermissionRequest*>
diff --git a/components/permissions/permission_request_manager_unittest.cc b/components/permissions/permission_request_manager_unittest.cc
index 71e9e46..3dc9793 100644
--- a/components/permissions/permission_request_manager_unittest.cc
+++ b/components/permissions/permission_request_manager_unittest.cc
@@ -55,10 +55,10 @@
                      PermissionRequestGestureType::NO_GESTURE),
 #endif
         iframe_request_same_domain_(u"iframe",
-                                    RequestType::kNotifications,
+                                    RequestType::kMidiSysex,
                                     GURL("http://www.google.com/some/url")),
         iframe_request_other_domain_(u"iframe",
-                                     RequestType::kGeolocation,
+                                     RequestType::kStorageAccess,
                                      GURL("http://www.youtube.com")),
         iframe_request_camera_other_domain_(u"iframe",
                                             RequestType::kCameraStream,
@@ -125,6 +125,36 @@
     manager_->NavigationEntryCommitted(details);
   }
 
+  std::unique_ptr<MockPermissionRequest> CreateAndAddRequest(
+      RequestType type,
+      bool should_be_seen,
+      int expected_request_count) {
+    std::unique_ptr<MockPermissionRequest> request =
+        std::make_unique<MockPermissionRequest>(
+            u"request", type, PermissionRequestGestureType::GESTURE);
+    manager_->AddRequest(web_contents()->GetMainFrame(), request.get());
+    WaitForBubbleToBeShown();
+    if (should_be_seen) {
+      EXPECT_TRUE(prompt_factory_->RequestTypeSeen(type));
+    } else {
+      EXPECT_FALSE(prompt_factory_->RequestTypeSeen(type));
+    }
+    EXPECT_EQ(prompt_factory_->TotalRequestCount(), expected_request_count);
+
+    return request;
+  }
+
+  void WaitAndAcceptPromptForRequest(MockPermissionRequest* request) {
+    WaitForBubbleToBeShown();
+
+    EXPECT_FALSE(request->finished());
+    EXPECT_TRUE(prompt_factory_->is_visible());
+    ASSERT_EQ(prompt_factory_->request_count(), 1);
+
+    Accept();
+    EXPECT_TRUE(request->granted());
+  }
+
  protected:
   GURL url_;
   MockPermissionRequest request1_;
@@ -994,8 +1024,458 @@
   Accept();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Quiet UI chip. Low priority for Notifications & Geolocation.
+////////////////////////////////////////////////////////////////////////////////
+
+TEST_P(PermissionRequestManagerTest, NotificationsSingleBubbleAndChipRequest) {
+  MockPermissionRequest request(u"request", RequestType::kNotifications,
+                                PermissionRequestGestureType::GESTURE);
+
+  manager_->AddRequest(web_contents()->GetMainFrame(), &request);
+  WaitForBubbleToBeShown();
+
+  EXPECT_TRUE(prompt_factory_->is_visible());
+  ASSERT_EQ(prompt_factory_->request_count(), 1);
+
+  Accept();
+  EXPECT_TRUE(request.granted());
+  EXPECT_EQ(prompt_factory_->show_count(), 1);
+}
+
+// Quiet UI feature is disabled. Chip is disabled. No low priority requests, the
+// first request is always shown.
+//
+// Permissions requested in order:
+// 1. Notification (non abusive)
+// 2. Geolocation
+// 3. Camera
+//
+// Prompt display order:
+// 1. Notification request shown
+// 2. Geolocation request shown
+// 3. Camera request shown
+TEST_P(PermissionRequestManagerTest,
+       NotificationsGeolocationCameraBubbleRequest) {
+  // permissions::features::kPermissionChip is enabled based on `GetParam()`.
+  // That test is only for the default bubble.
+  if (GetParam())
+    return;
+
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          1);
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
+                          1);
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/false, 1);
+
+  for (auto* kRequest : {request_notifications.get(), request_geolocation.get(),
+                         request_camera.get()}) {
+    WaitAndAcceptPromptForRequest(kRequest);
+  }
+
+  EXPECT_EQ(prompt_factory_->show_count(), 3);
+}
+
+// Quiet UI feature is disabled, no low priority requests, the last request is
+// always shown.
+//
+// Permissions requested in order:
+// 1. Notification (non abusive)
+// 2. Geolocation
+// 3. Camera
+//
+// Prompt display order:
+// 1. Notifications request shown but is preempted
+// 2. Geolocation request shown but is preempted
+// 3. Camera request shown
+// 4. Geolocation request shown again
+// 5. Notifications request shown again
+TEST_P(PermissionRequestManagerTest,
+       NotificationsGeolocationCameraChipRequest) {
+  // permissions::features::kPermissionChip is enabled based on `GetParam()`.
+  // That test is only for the chip UI.
+  if (!GetParam())
+    return;
+
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          1);
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
+                          2);
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 3);
+
+  for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
+                         request_notifications.get()}) {
+    WaitAndAcceptPromptForRequest(kRequest);
+  }
+
+  EXPECT_EQ(prompt_factory_->show_count(), 5);
+}
+
+// Quiet UI feature is disabled, no low priority requests, the last request is
+// always shown.
+//
+// Permissions requested in order:
+// 1. Camera
+// 2. Notification (non abusive)
+// 3. Geolocation
+//
+// Prompt display order:
+// 1. Camera request shown but is preempted
+// 2. Notifications request shown but is preempted
+// 3. Geolocation request shown
+// 4. Notifications request shown again
+// 5. Camera request shown again
+TEST_P(PermissionRequestManagerTest,
+       CameraNotificationsGeolocationChipRequest) {
+  // permissions::features::kPermissionChip is enabled based on `GetParam()`.
+  // That test is only for the chip.
+  if (!GetParam())
+    return;
+
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 1);
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          2);
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
+                          3);
+
+  for (auto* kRequest : {request_geolocation.get(), request_notifications.get(),
+                         request_camera.get()}) {
+    WaitAndAcceptPromptForRequest(kRequest);
+  }
+
+  EXPECT_EQ(prompt_factory_->show_count(), 5);
+}
+
+class PermissionRequestManagerTestQuietChip
+    : public PermissionRequestManagerTest {
+ public:
+  PermissionRequestManagerTestQuietChip() {
+    feature_list_.InitWithFeatureState(
+        permissions::features::kPermissionQuietChip, true);
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Verifies that the quiet UI chip is not ignored if another request came in
+// less than 8.5 seconds after.
+// Permissions requested in order:
+// 1. Notification (abusive)
+// 2. After less than 8.5 seconds Geolocation
+//
+// Prompt display order:
+// 1. Notifications request shown but is preempted because of quiet UI.
+// 2. Geolocation request shown
+// 3. Notifications request shown again
+TEST_P(PermissionRequestManagerTestQuietChip,
+       AbusiveNotificationsGeolocationQuietUIChipRequest) {
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_,
+      PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
+      false /* async */);
+
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          1);
+
+  // Less then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(5000));
+
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
+                          2);
+
+  WaitAndAcceptPromptForRequest(request_geolocation.get());
+  WaitAndAcceptPromptForRequest(request_notifications.get());
+
+  EXPECT_EQ(prompt_factory_->show_count(), 3);
+}
+
+// Verifies that the quiet UI chip is ignored if another request came in more
+// than 8.5 seconds after.
+//
+// Permissions requested in order:
+// 1. Notification (abusive)
+// 2. After more than 8.5 seconds Geolocation
+//
+// Prompt display order:
+// 1. Notifications request shown but is preempted because of quiet UI.
+// 2. Geolocation request shown
+TEST_P(PermissionRequestManagerTestQuietChip,
+       AbusiveNotificationsShownLongEnough) {
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_,
+      PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
+      false /* async */);
+
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          1);
+
+  // More then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(9000));
+
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
+                          2);
+
+  // The second permission was requested after 8.5 second window, the quiet UI
+  // Notifiations request for an abusive origin is automatically ignored.
+  EXPECT_FALSE(request_notifications->granted());
+  EXPECT_TRUE(request_notifications->finished());
+
+  WaitAndAcceptPromptForRequest(request_geolocation.get());
+
+  EXPECT_EQ(prompt_factory_->show_count(), 2);
+}
+
+// Verifies that the quiet UI chip is not ignored if another request came in
+// more than 8.5 seconds after. Verify different requests priority. Camera
+// request is shown despite being requested last.
+//
+// Permissions requested in order:
+// 1. Notification (abusive)
+// 2. After less than 8.5 seconds Geolocation
+// 3. Camera
+//
+// Prompt display order:
+// 1. Notifications request shown but is preempted because of quiet UI.
+// 2. Geolocation request shown but is preempted because of low priority.
+// 3. Camera request shown
+// 4. Geolocation request shown again
+// 5. Notifications quiet UI request shown again
+TEST_P(PermissionRequestManagerTestQuietChip,
+       AbusiveNotificationsShownLongEnoughCamera) {
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_,
+      PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
+      false /* async */);
+
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
+                          1);
+  // Less then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(5000));
+
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
+                          2);
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 3);
+
+  // The second permission was requested in 8.5 second window, the quiet UI
+  // Notifiations request for an abusive origin is not automatically ignored.
+  EXPECT_FALSE(request_notifications->granted());
+  EXPECT_FALSE(request_notifications->finished());
+
+  for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
+                         request_notifications.get()}) {
+    WaitAndAcceptPromptForRequest(kRequest);
+  }
+
+  EXPECT_EQ(prompt_factory_->show_count(), 5);
+}
+
+// Verifies that the quiet UI chip is not ignored if another request came in
+// more than 8.5 seconds after. Verify different requests priority. Camera
+// request is not preemted.
+//
+// Permissions requested in order:
+// 1. Camera
+// 2. Notification (abusive)
+// 3. After less than 8.5 seconds Geolocation
+//
+// Prompt display order:
+// 1. Camera request shown
+// 2. Geolocation request shown
+// 3. Camera request shown
+TEST_P(PermissionRequestManagerTestQuietChip,
+       CameraAbusiveNotificationsGeolocation) {
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_,
+      PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
+      false /* async */);
+
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 1);
+
+  // Quiet UI is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
+                          1);
+  // Less then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(5000));
+
+  // Geolocation is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
+                          1);
+
+  // The second permission after quiet UI was requested in 8.5 second window,
+  // the quiet UI Notifiations request for an abusive origin is not
+  // automatically ignored.
+  EXPECT_FALSE(request_notifications->granted());
+  EXPECT_FALSE(request_notifications->finished());
+
+  for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
+                         request_notifications.get()}) {
+    WaitAndAcceptPromptForRequest(kRequest);
+  }
+
+  EXPECT_EQ(prompt_factory_->show_count(), 3);
+}
+
+// Verifies that the quiet UI chip is not ignored if another request came in
+// more than 8.5 seconds after. Verify different requests priority. Camera
+// request is not preemted.
+//
+// Permissions requested in order:
+// 1. Camera
+// 2. Notification (abusive)
+// 3. After less than 8.5 seconds Geolocation
+// 4. MIDI
+//
+// Prompt display order:
+// 1. Camera request shown
+// 2. MIDI request shown (or MIDI and then Camera, the order depends on
+// `GetParam()`)
+// 3. Geolocation request shown
+// 4. Notifications request shown
+// If Chip is enabled MIDI will replace Camera, hence 5 prompts will be
+// shown. Otherwise 4.
+TEST_P(PermissionRequestManagerTestQuietChip,
+       CameraAbusiveNotificationsGeolocationMIDI) {
+  MockNotificationPermissionUiSelector::CreateForManager(
+      manager_,
+      PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
+      false /* async */);
+
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 1);
+
+  // Quiet UI is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
+                          1);
+  // Less then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(5000));
+
+  // Geolocation is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
+                          1);
+
+  std::unique_ptr<MockPermissionRequest> request_midi;
+
+  // If Chip is enabled, MIDI should be shown, otherwise MIDI should not be
+  // shown.
+  if (GetParam()) {
+    request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
+                                       /*should_be_seen=*/true, 2);
+  } else {
+    request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
+                                       /*should_be_seen=*/false, 1);
+  }
+
+  // The second permission after quiet UI was requested in 8.5 second window,
+  // the quiet UI Notifiations request for an abusive origin is not
+  // automatically ignored.
+  EXPECT_FALSE(request_notifications->granted());
+  EXPECT_FALSE(request_notifications->finished());
+
+  WaitAndAcceptPromptForRequest(GetParam() ? request_midi.get()
+                                           : request_camera.get());
+  WaitAndAcceptPromptForRequest(GetParam() ? request_camera.get()
+                                           : request_midi.get());
+  WaitAndAcceptPromptForRequest(request_geolocation.get());
+  WaitAndAcceptPromptForRequest(request_notifications.get());
+
+  EXPECT_EQ(prompt_factory_->show_count(), GetParam() ? 5 : 4);
+}
+
+// Verifies that non abusive chip behaves similar to others when Quiet UI Chip
+// is enabled.
+//
+// Permissions requested in order:
+// 1. Camera
+// 2. Notification (non abusive)
+// 3. After less than 8.5 seconds Geolocation
+// 4. MIDI
+//
+// Prompt display order:
+// 1. Camera request shown
+// 2. MIDI request shown (or MIDI and then Camera, the order depends on
+// `GetParam()`)
+// 3. Geolocation request shown
+// 4. Notifications request shown
+// If Chip is enabled MIDI will replace Camera, hence 5 prompts will be
+// shown. Otherwise 4.
+TEST_P(PermissionRequestManagerTestQuietChip,
+       CameraNonAbusiveNotificationsGeolocationMIDI) {
+  std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
+      RequestType::kCameraStream, /*should_be_seen=*/true, 1);
+
+  // Quiet UI is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_notifications =
+      CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
+                          1);
+  // Less then 8.5 seconds.
+  manager_->set_current_request_first_display_time_for_testing(
+      base::Time::Now() - base::TimeDelta::FromMilliseconds(5000));
+
+  // Geolocation is not shown because Camera has higher priority.
+  std::unique_ptr<MockPermissionRequest> request_geolocation =
+      CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
+                          1);
+
+  std::unique_ptr<MockPermissionRequest> request_midi;
+
+  // If Chip is enabled, MIDI should be shown, otherwise MIDI should not be
+  // shown.
+  if (GetParam()) {
+    request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
+                                       /*should_be_seen=*/true, 2);
+  } else {
+    request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
+                                       /*should_be_seen=*/false, 1);
+  }
+
+  // The second permission after quiet UI was requested in 8.5 second window,
+  // the quiet UI Notifiations request for an abusive origin is not
+  // automatically ignored.
+  EXPECT_FALSE(request_notifications->granted());
+  EXPECT_FALSE(request_notifications->finished());
+
+  WaitAndAcceptPromptForRequest(GetParam() ? request_midi.get()
+                                           : request_camera.get());
+  WaitAndAcceptPromptForRequest(GetParam() ? request_camera.get()
+                                           : request_midi.get());
+  WaitAndAcceptPromptForRequest(request_geolocation.get());
+  WaitAndAcceptPromptForRequest(request_notifications.get());
+
+  EXPECT_EQ(prompt_factory_->show_count(), GetParam() ? 5 : 4);
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          PermissionRequestManagerTest,
                          ::testing::Values(false, true));
+INSTANTIATE_TEST_SUITE_P(All,
+                         PermissionRequestManagerTestQuietChip,
+                         ::testing::Values(false, true));
 
 }  // namespace permissions
diff --git a/components/permissions/permission_uma_util.cc b/components/permissions/permission_uma_util.cc
index c696aa75..0eef0530 100644
--- a/components/permissions/permission_uma_util.cc
+++ b/components/permissions/permission_uma_util.cc
@@ -269,6 +269,8 @@
       return "CustomModalDialog";
     case PermissionPromptDisposition::LOCATION_BAR_LEFT_CHIP:
       return "LocationBarLeftChip";
+    case PermissionPromptDisposition::LOCATION_BAR_LEFT_QUIET_CHIP:
+      return "LocationBarLeftQuietChip";
     case PermissionPromptDisposition::LOCATION_BAR_RIGHT_ANIMATED_ICON:
       return "LocationBarRightAnimatedIcon";
     case PermissionPromptDisposition::LOCATION_BAR_RIGHT_STATIC_ICON:
diff --git a/components/permissions/permission_uma_util.h b/components/permissions/permission_uma_util.h
index e04ed92..8a31d90 100644
--- a/components/permissions/permission_uma_util.h
+++ b/components/permissions/permission_uma_util.h
@@ -154,6 +154,10 @@
 
   // Other custom modal dialogs.
   CUSTOM_MODAL_DIALOG = 8,
+
+  // Only used on desktop, a less prominent version of chip on the left-hand
+  // side of the location bar that shows a bubble when clicked.
+  LOCATION_BAR_LEFT_QUIET_CHIP = 9,
 };
 
 // The reason why the permission prompt disposition was used. Enum used in UKMs,
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
index 067042c..eabe1fa 100644
--- a/components/permissions/permission_util.cc
+++ b/components/permissions/permission_util.cc
@@ -4,6 +4,7 @@
 
 #include "components/permissions/permission_util.h"
 
+#include "base/feature_list.h"
 #include "base/notreached.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -91,64 +92,92 @@
 
 bool PermissionUtil::GetPermissionType(ContentSettingsType type,
                                        PermissionType* out) {
-  if (type == ContentSettingsType::GEOLOCATION) {
-    *out = PermissionType::GEOLOCATION;
-  } else if (type == ContentSettingsType::NOTIFICATIONS) {
-    *out = PermissionType::NOTIFICATIONS;
-  } else if (type == ContentSettingsType::MIDI) {
-    *out = PermissionType::MIDI;
-  } else if (type == ContentSettingsType::MIDI_SYSEX) {
-    *out = PermissionType::MIDI_SYSEX;
-  } else if (type == ContentSettingsType::DURABLE_STORAGE) {
-    *out = PermissionType::DURABLE_STORAGE;
-  } else if (type == ContentSettingsType::MEDIASTREAM_CAMERA) {
-    *out = PermissionType::VIDEO_CAPTURE;
-  } else if (type == ContentSettingsType::MEDIASTREAM_MIC) {
-    *out = PermissionType::AUDIO_CAPTURE;
-  } else if (type == ContentSettingsType::BACKGROUND_SYNC) {
-    *out = PermissionType::BACKGROUND_SYNC;
+  switch (type) {
+    case ContentSettingsType::GEOLOCATION:
+      *out = PermissionType::GEOLOCATION;
+      break;
+    case ContentSettingsType::NOTIFICATIONS:
+      *out = PermissionType::NOTIFICATIONS;
+      break;
+    case ContentSettingsType::MIDI:
+      *out = PermissionType::MIDI;
+      break;
+    case ContentSettingsType::MIDI_SYSEX:
+      *out = PermissionType::MIDI_SYSEX;
+      break;
+    case ContentSettingsType::DURABLE_STORAGE:
+      *out = PermissionType::DURABLE_STORAGE;
+      break;
+    case ContentSettingsType::MEDIASTREAM_CAMERA:
+      *out = PermissionType::VIDEO_CAPTURE;
+      break;
+    case ContentSettingsType::MEDIASTREAM_MIC:
+      *out = PermissionType::AUDIO_CAPTURE;
+      break;
+    case ContentSettingsType::BACKGROUND_SYNC:
+      *out = PermissionType::BACKGROUND_SYNC;
+      break;
 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) || defined(OW_WIN)
-  } else if (type == ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER) {
-    *out = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
+    case ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER:
+      *out = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
+      break;
 #endif
-  } else if (type == ContentSettingsType::SENSORS) {
-    *out = PermissionType::SENSORS;
-  } else if (type == ContentSettingsType::ACCESSIBILITY_EVENTS) {
-    *out = PermissionType::ACCESSIBILITY_EVENTS;
-  } else if (type == ContentSettingsType::CLIPBOARD_READ_WRITE) {
-    *out = PermissionType::CLIPBOARD_READ_WRITE;
-  } else if (type == ContentSettingsType::PAYMENT_HANDLER) {
-    *out = PermissionType::PAYMENT_HANDLER;
-  } else if (type == ContentSettingsType::BACKGROUND_FETCH) {
-    *out = PermissionType::BACKGROUND_FETCH;
-  } else if (type == ContentSettingsType::PERIODIC_BACKGROUND_SYNC) {
-    *out = PermissionType::PERIODIC_BACKGROUND_SYNC;
-  } else if (type == ContentSettingsType::WAKE_LOCK_SCREEN) {
-    *out = PermissionType::WAKE_LOCK_SCREEN;
-  } else if (type == ContentSettingsType::WAKE_LOCK_SYSTEM) {
-    *out = PermissionType::WAKE_LOCK_SYSTEM;
-  } else if (type == ContentSettingsType::NFC) {
-    *out = PermissionType::NFC;
-  } else if (type == ContentSettingsType::VR) {
-    *out = PermissionType::VR;
-  } else if (type == ContentSettingsType::AR) {
-    *out = PermissionType::AR;
-  } else if (type == ContentSettingsType::STORAGE_ACCESS) {
-    *out = PermissionType::STORAGE_ACCESS_GRANT;
-  } else if (type == ContentSettingsType::CAMERA_PAN_TILT_ZOOM) {
-    *out = PermissionType::CAMERA_PAN_TILT_ZOOM;
-  } else if (type == ContentSettingsType::WINDOW_PLACEMENT) {
-    *out = PermissionType::WINDOW_PLACEMENT;
-  } else if (type == ContentSettingsType::FONT_ACCESS) {
-    *out = PermissionType::FONT_ACCESS;
-  } else if (type == ContentSettingsType::IDLE_DETECTION) {
-    *out = PermissionType::IDLE_DETECTION;
-  } else if (type == ContentSettingsType::DISPLAY_CAPTURE) {
-    *out = PermissionType::DISPLAY_CAPTURE;
-  } else if (type == ContentSettingsType::FILE_HANDLING) {
-    *out = PermissionType::FILE_HANDLING;
-  } else {
-    return false;
+    case ContentSettingsType::SENSORS:
+      *out = PermissionType::SENSORS;
+      break;
+    case ContentSettingsType::ACCESSIBILITY_EVENTS:
+      *out = PermissionType::ACCESSIBILITY_EVENTS;
+      break;
+    case ContentSettingsType::CLIPBOARD_READ_WRITE:
+      *out = PermissionType::CLIPBOARD_READ_WRITE;
+      break;
+    case ContentSettingsType::PAYMENT_HANDLER:
+      *out = PermissionType::PAYMENT_HANDLER;
+      break;
+    case ContentSettingsType::BACKGROUND_FETCH:
+      *out = PermissionType::BACKGROUND_FETCH;
+      break;
+    case ContentSettingsType::PERIODIC_BACKGROUND_SYNC:
+      *out = PermissionType::PERIODIC_BACKGROUND_SYNC;
+      break;
+    case ContentSettingsType::WAKE_LOCK_SCREEN:
+      *out = PermissionType::WAKE_LOCK_SCREEN;
+      break;
+    case ContentSettingsType::WAKE_LOCK_SYSTEM:
+      *out = PermissionType::WAKE_LOCK_SYSTEM;
+      break;
+    case ContentSettingsType::NFC:
+      *out = PermissionType::NFC;
+      break;
+    case ContentSettingsType::VR:
+      *out = PermissionType::VR;
+      break;
+    case ContentSettingsType::AR:
+      *out = PermissionType::AR;
+      break;
+    case ContentSettingsType::STORAGE_ACCESS:
+      *out = PermissionType::STORAGE_ACCESS_GRANT;
+      break;
+    case ContentSettingsType::CAMERA_PAN_TILT_ZOOM:
+      *out = PermissionType::CAMERA_PAN_TILT_ZOOM;
+      break;
+    case ContentSettingsType::WINDOW_PLACEMENT:
+      *out = PermissionType::WINDOW_PLACEMENT;
+      break;
+    case ContentSettingsType::FONT_ACCESS:
+      *out = PermissionType::FONT_ACCESS;
+      break;
+    case ContentSettingsType::IDLE_DETECTION:
+      *out = PermissionType::IDLE_DETECTION;
+      break;
+    case ContentSettingsType::DISPLAY_CAPTURE:
+      *out = PermissionType::DISPLAY_CAPTURE;
+      break;
+    case ContentSettingsType::FILE_HANDLING:
+      *out = PermissionType::FILE_HANDLING;
+      break;
+    default:
+      return false;
   }
   return true;
 }
@@ -190,6 +219,30 @@
   }
 }
 
+bool PermissionUtil::IsGuardContentSetting(ContentSettingsType type) {
+  switch (type) {
+    case ContentSettingsType::USB_GUARD:
+    case ContentSettingsType::SERIAL_GUARD:
+    case ContentSettingsType::BLUETOOTH_GUARD:
+    case ContentSettingsType::BLUETOOTH_SCANNING:
+    case ContentSettingsType::FILE_SYSTEM_WRITE_GUARD:
+    case ContentSettingsType::HID_GUARD:
+      return true;
+    default:
+      return false;
+  }
+}
+
+bool PermissionUtil::CanPermissionBeAllowedOnce(ContentSettingsType type) {
+  switch (type) {
+    case ContentSettingsType::GEOLOCATION:
+      return base::FeatureList::IsEnabled(
+          permissions::features::kOneTimeGeolocationPermission);
+    default:
+      return false;
+  }
+}
+
 // Returns the last committed URL for `web_contents`. If the frame's URL is
 // about:blank, returns GetLastCommittedOrigin.
 // Due to dependency issues, this method is duplicated in
@@ -207,4 +260,5 @@
 
   return web_contents->GetLastCommittedURL().GetOrigin();
 }
+
 }  // namespace permissions
diff --git a/components/permissions/permission_util.h b/components/permissions/permission_util.h
index 74ab00d3..e107fd8 100644
--- a/components/permissions/permission_util.h
+++ b/components/permissions/permission_util.h
@@ -58,6 +58,14 @@
   // PermissionManager.
   static bool IsPermission(ContentSettingsType type);
 
+  // Checks whether the given ContentSettingsType is a guard content setting,
+  // meaning it does not support allow setting and toggles between "ask" and
+  // "block" instead. This is primarily used for chooser-based permissions.
+  static bool IsGuardContentSetting(ContentSettingsType type);
+
+  // Checks whether the given ContentSettingsType supports one time grants.
+  static bool CanPermissionBeAllowedOnce(ContentSettingsType type);
+
   // Returns the authoritative `embedding origin`, as a GURL, to be used for
   // permission decisions in `web_contents`.
   // TODO(crbug.com/698985): This method should only be used temporarily, and
diff --git a/components/policy/core/browser/policy_conversions.cc b/components/policy/core/browser/policy_conversions.cc
index 9f1866d..8c0b412 100644
--- a/components/policy/core/browser/policy_conversions.cc
+++ b/components/policy/core/browser/policy_conversions.cc
@@ -22,7 +22,7 @@
     {"commandLine", IDS_POLICY_SOURCE_COMMAND_LINE},
     {"cloud", IDS_POLICY_SOURCE_CLOUD},
     {"sourceActiveDirectory", IDS_POLICY_SOURCE_ACTIVE_DIRECTORY},
-    {"sourceDeviceLocalAccountOverride",
+    {"sourceDeviceLocalAccountOverrideDeprecated",
      IDS_POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE},
     {"platform", IDS_POLICY_SOURCE_PLATFORM},
     {"priorityCloud", IDS_POLICY_SOURCE_CLOUD},
diff --git a/components/policy/core/browser/policy_pref_mapping_test.cc b/components/policy/core/browser/policy_pref_mapping_test.cc
index e25a171..82e0d045 100644
--- a/components/policy/core/browser/policy_pref_mapping_test.cc
+++ b/components/policy/core/browser/policy_pref_mapping_test.cc
@@ -435,7 +435,7 @@
     else if (*source == "active_directory")
       settings.source = POLICY_SOURCE_ACTIVE_DIRECTORY;
     else if (*source == "local_account_override")
-      settings.source = POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE;
+      settings.source = POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED;
     else if (*source == "platform")
       settings.source = POLICY_SOURCE_PLATFORM;
     else if (*source == "priority_cloud")
diff --git a/components/policy/core/browser/url_blocklist_manager.cc b/components/policy/core/browser/url_blocklist_manager.cc
index a4a9c33..b246e5e 100644
--- a/components/policy/core/browser/url_blocklist_manager.cc
+++ b/components/policy/core/browser/url_blocklist_manager.cc
@@ -242,10 +242,12 @@
       background_task_runner_.get(), FROM_HERE,
       base::BindOnce(
           &BuildBlocklist,
-          base::Owned(
-              pref_service_->GetList(policy_prefs::kUrlBlocklist)->DeepCopy()),
-          base::Owned(
-              pref_service_->GetList(policy_prefs::kUrlAllowlist)->DeepCopy())),
+          base::Owned(pref_service_->GetList(policy_prefs::kUrlBlocklist)
+                          ->CreateDeepCopy()
+                          .release()),
+          base::Owned(pref_service_->GetList(policy_prefs::kUrlAllowlist)
+                          ->CreateDeepCopy()
+                          .release())),
       base::BindOnce(&URLBlocklistManager::SetBlocklist,
                      ui_weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/components/policy/core/common/cloud/cloud_policy_validator.cc b/components/policy/core/common/cloud/cloud_policy_validator.cc
index f79b996..ffff7c7 100644
--- a/components/policy/core/common/cloud/cloud_policy_validator.cc
+++ b/components/policy/core/common/cloud/cloud_policy_validator.cc
@@ -18,11 +18,18 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "crypto/signature_verifier.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "base/command_line.h"
+#include "base/system/sys_info.h"
+#include "components/policy/core/common/policy_switches.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace em = enterprise_management;
 
 namespace policy {
@@ -268,7 +275,20 @@
       verification_key_(GetPolicyVerificationKey()),
       allow_key_rotation_(false),
       background_task_runner_(background_task_runner) {
-  DCHECK(!verification_key_.empty());
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Empty `verification_key_` is only allowed on Chrome OS test image when
+  // policy key verification is disabled via command line flag.
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kDisablePolicyKeyVerification)) {
+    base::SysInfo::CrashIfChromeOSNonTestImage();
+    // GetPolicyVerificationKey() returns a non-empty string.
+    verification_key_ = absl::nullopt;
+  } else {
+    DCHECK(verification_key_);
+  }
+#else
+  DCHECK(verification_key_);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 // static
@@ -373,6 +393,13 @@
 // Verifies the |new_public_key_verification_signature_deprecated| for the
 // |new_public_key| in the policy blob.
 bool CloudPolicyValidatorBase::CheckNewPublicKeyVerificationSignature() {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Skip verification if the key is empty (disabled via command line).
+  if (!verification_key_) {
+    return true;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
   if (!policy_->has_new_public_key_verification_signature_deprecated()) {
     // Policy does not contain a verification signature, so log an error.
     LOG(ERROR) << "Policy is missing public_key_verification_signature";
@@ -380,7 +407,7 @@
   }
 
   if (!CheckVerificationKeySignature(
-          policy_->new_public_key(), verification_key_,
+          policy_->new_public_key(), verification_key_.value(),
           policy_->new_public_key_verification_signature_deprecated())) {
     LOG(ERROR) << "Signature verification failed";
     return false;
@@ -476,7 +503,14 @@
 }
 
 CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckCachedKey() {
-  if (!CheckVerificationKeySignature(cached_key_, verification_key_,
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Skip verification if the key is empty (disabled via command line).
+  if (!verification_key_) {
+    return VALIDATION_OK;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+  if (!CheckVerificationKeySignature(cached_key_, verification_key_.value(),
                                      cached_key_signature_)) {
     LOG(ERROR) << "Cached key signature verification failed";
     return VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE;
diff --git a/components/policy/core/common/cloud/cloud_policy_validator.h b/components/policy/core/common/cloud/cloud_policy_validator.h
index d4e804c9..e4e18de 100644
--- a/components/policy/core/common/cloud/cloud_policy_validator.h
+++ b/components/policy/core/common/cloud/cloud_policy_validator.h
@@ -23,6 +23,7 @@
 #include "components/policy/core/common/cloud/policy_value_validator.h"
 #include "components/policy/policy_export.h"
 #include "components/policy/proto/cloud_policy.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
 #include "components/policy/proto/chrome_extension_policy.pb.h"
@@ -372,7 +373,7 @@
   std::string key_;
   std::string cached_key_;
   std::string cached_key_signature_;
-  std::string verification_key_;
+  absl::optional<std::string> verification_key_;
   std::string owning_domain_;
   bool allow_key_rotation_;
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
diff --git a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
index 9f72c0a..dc0c2926 100644
--- a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
@@ -27,6 +27,14 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "base/command_line.h"
+#include "base/system/sys_info.h"
+#include "base/test/scoped_chromeos_version_info.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest-death-test.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 namespace em = enterprise_management;
 
 using testing::Invoke;
@@ -177,6 +185,45 @@
   DISALLOW_COPY_AND_ASSIGN(CloudPolicyValidatorTest);
 };
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(CloudPolicyValidatorTest,
+       SuccessfulValidationWithDisableKeyVerificationOnTestImage) {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  command_line->AppendSwitch(switches::kDisablePolicyKeyVerification);
+  const char kLsbRelease[] =
+      "CHROMEOS_RELEASE_NAME=Chrome OS\n"
+      "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"
+      "CHROMEOS_RELEASE_TRACK=testimage-channel\n";
+  base::test::ScopedChromeOSVersionInfo version(kLsbRelease, base::Time());
+  EXPECT_TRUE(base::SysInfo::IsRunningOnChromeOS());
+
+  // Should not crash when creating a CloudPolicyValidator. Runs validation
+  // successfully.
+  Validate(Invoke(this, &CloudPolicyValidatorTest::CheckSuccessfulValidation));
+}
+
+TEST_F(CloudPolicyValidatorTest,
+       CrashIfDisableKeyVerificationWithoutTestImage) {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  command_line->AppendSwitch(switches::kDisablePolicyKeyVerification);
+  const char kLsbRelease[] =
+      "CHROMEOS_RELEASE_NAME=Chrome OS\n"
+      "CHROMEOS_RELEASE_VERSION=1.2.3.4\n"
+      "CHROMEOS_RELEASE_TRACK=stable-channel\n";
+  base::test::ScopedChromeOSVersionInfo version(kLsbRelease, base::Time());
+  EXPECT_TRUE(base::SysInfo::IsRunningOnChromeOS());
+
+  // Should crash when creating a CloudPolicyValidator.
+  EXPECT_DEATH_IF_SUPPORTED(
+      {
+        policy_.Build();
+        std::unique_ptr<UserCloudPolicyValidator> validator =
+            CreateValidator(policy_.GetCopy());
+      },
+      "");
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 TEST_F(CloudPolicyValidatorTest, SuccessfulValidation) {
   Validate(Invoke(this, &CloudPolicyValidatorTest::CheckSuccessfulValidation));
 }
diff --git a/components/policy/core/common/generate_policy_source_unittest.cc b/components/policy/core/common/generate_policy_source_unittest.cc
index 757a1e2..dbf89760 100644
--- a/components/policy/core/common/generate_policy_source_unittest.cc
+++ b/components/policy/core/common/generate_policy_source_unittest.cc
@@ -210,10 +210,16 @@
   EXPECT_TRUE(details->is_device_policy);
   EXPECT_EQ(90, details->id);
   EXPECT_EQ(0u, details->max_external_data_size);
-#endif
 
-  // TODO(bartfab): add a test that verifies a max_external_data_size larger
-  // than 0, once a type 'external' policy is added.
+  // Policies of type 'external' have a greater-than-zero value for
+  // |max_external_data_size|.
+  details = GetChromePolicyDetails(key::kWallpaperImage);
+  ASSERT_TRUE(details);
+  EXPECT_FALSE(details->is_deprecated);
+  EXPECT_FALSE(details->is_device_policy);
+  EXPECT_EQ(262, details->id);
+  EXPECT_GT(details->max_external_data_size, 0u);
+#endif
 }
 
 #if defined(OS_CHROMEOS)
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc
index 6539d12..6547308 100644
--- a/components/policy/core/common/policy_loader_win_unittest.cc
+++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -84,10 +84,7 @@
     }
 
     case base::Value::Type::DOUBLE: {
-      double double_value;
-      if (!value.GetAsDouble(&double_value))
-        return false;
-      std::wstring str_value = base::NumberToWString(double_value);
+      std::wstring str_value = base::NumberToWString(value.GetDouble());
       return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
     }
 
diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc
index 3475003..2d72dbb 100644
--- a/components/policy/core/common/policy_map_unittest.cc
+++ b/components/policy/core/common/policy_map_unittest.cc
@@ -383,8 +383,8 @@
         POLICY_SOURCE_ENTERPRISE_DEFAULT, absl::nullopt,
         CreateExternalDataFetcher("b"));
   b.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE, base::Value(true),
-        nullptr);
+        POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED,
+        base::Value(true), nullptr);
   b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_PLATFORM, base::Value(std::string()), nullptr);
   b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
@@ -430,8 +430,8 @@
       ->AddConflictingPolicy(b.Get(kTestPolicyName3)->DeepCopy());
   // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER for POLICY_LEVEL_RECOMMENDED.
   c.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE, base::Value(true),
-        nullptr);
+        POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED,
+        base::Value(true), nullptr);
   c.GetMutable(kTestPolicyName4)
       ->AddMessage(PolicyMap::MessageType::kWarning,
                    IDS_POLICY_CONFLICT_DIFF_VALUE);
@@ -609,7 +609,7 @@
 
   case7.AddConflictingPolicy(
       PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                       POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
+                       POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED,
                        base::Value(list_dict_c), nullptr));
 
   PolicyMap::Entry expected_case7(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
@@ -697,9 +697,10 @@
   case1.AddConflictingPolicy(
       PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
                        POLICY_SOURCE_PLATFORM, dict_b.Clone(), nullptr));
-  case1.AddConflictingPolicy(PolicyMap::Entry(
-      POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-      POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE, dict_c.Clone(), nullptr));
+  case1.AddConflictingPolicy(
+      PolicyMap::Entry(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+                       POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED,
+                       dict_c.Clone(), nullptr));
   case1.AddConflictingPolicy(PolicyMap::Entry(
       POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
       POLICY_SOURCE_ACTIVE_DIRECTORY, dict_d.Clone(), nullptr));
diff --git a/components/policy/core/common/policy_switches.cc b/components/policy/core/common/policy_switches.cc
index 515327d..3052c2d5 100644
--- a/components/policy/core/common/policy_switches.cc
+++ b/components/policy/core/common/policy_switches.cc
@@ -9,7 +9,7 @@
 
 // Specifies the URL at which to communicate with the device management backend
 // to fetch configuration policies and perform other device tasks.
-const char kDeviceManagementUrl[]           = "device-management-url";
+const char kDeviceManagementUrl[] = "device-management-url";
 
 // Specifies the URL at which to upload real-time reports.
 const char kRealtimeReportingUrl[] = "realtime-reporting-url";
@@ -19,10 +19,18 @@
 
 // Always treat user as affiliated.
 // TODO(antrim): Remove once test servers correctly produce affiliation ids.
-const char kUserAlwaysAffiliated[]  = "user-always-affiliated";
+const char kUserAlwaysAffiliated[] = "user-always-affiliated";
 
 // Set policy value by command line.
 const char kChromePolicy[] = "policy";
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+// Disables the verification of policy signing keys. It just works on Chrome OS
+// test images and crashes otherwise.
+// TODO(crbug.com/1225054): This flag might introduce security risks. Find a
+// better solution to enable policy tast test for Family Link account.
+const char kDisablePolicyKeyVerification[] = "disable-policy-key-verification";
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace switches
 }  // namespace policy
diff --git a/components/policy/core/common/policy_switches.h b/components/policy/core/common/policy_switches.h
index 72f5ce5..534fc24 100644
--- a/components/policy/core/common/policy_switches.h
+++ b/components/policy/core/common/policy_switches.h
@@ -8,6 +8,7 @@
 #include "components/policy/policy_export.h"
 
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 
 namespace policy {
 namespace switches {
@@ -17,6 +18,9 @@
 POLICY_EXPORT extern const char kEncryptedReportingUrl[];
 POLICY_EXPORT extern const char kUserAlwaysAffiliated[];
 POLICY_EXPORT extern const char kChromePolicy[];
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+POLICY_EXPORT extern const char kDisablePolicyKeyVerification[];
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 }  // namespace switches
 }  // namespace policy
diff --git a/components/policy/core/common/policy_test_utils.h b/components/policy/core/common/policy_test_utils.h
index 33772a9..f81fb16 100644
--- a/components/policy/core/common/policy_test_utils.h
+++ b/components/policy/core/common/policy_test_utils.h
@@ -16,6 +16,10 @@
 #include "components/policy/core/common/policy_service.h"
 #include "components/policy/core/common/policy_types.h"
 
+#if defined(OS_APPLE)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
 namespace policy {
 
 class PolicyBundle;
diff --git a/components/policy/core/common/policy_types.h b/components/policy/core/common/policy_types.h
index ba0df44f..7e6ce591 100644
--- a/components/policy/core/common/policy_types.h
+++ b/components/policy/core/common/policy_types.h
@@ -47,7 +47,8 @@
 
   // Any non-platform policy was overridden because we are running in a
   // public session or kiosk mode.
-  POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE,
+  // TODO(crbug/1225922): Remove deprecated policy source.
+  POLICY_SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED,
 
   // The policy was set by a platform source.
   POLICY_SOURCE_PLATFORM,
diff --git a/components/policy/core/common/schema_map.cc b/components/policy/core/common/schema_map.cc
index 0b410969..991027eb 100644
--- a/components/policy/core/common/schema_map.cc
+++ b/components/policy/core/common/schema_map.cc
@@ -4,6 +4,8 @@
 
 #include "components/policy/core/common/schema_map.h"
 
+#include <utility>
+
 #include "base/values.h"
 #include "components/policy/core/common/policy_bundle.h"
 #include "components/policy/core/common/policy_map.h"
@@ -12,9 +14,7 @@
 
 SchemaMap::SchemaMap() {}
 
-SchemaMap::SchemaMap(DomainMap& map) {
-  map_.swap(map);
-}
+SchemaMap::SchemaMap(DomainMap map) : map_(std::move(map)) {}
 
 SchemaMap::~SchemaMap() {}
 
diff --git a/components/policy/core/common/schema_map.h b/components/policy/core/common/schema_map.h
index 09954aa..12455a8 100644
--- a/components/policy/core/common/schema_map.h
+++ b/components/policy/core/common/schema_map.h
@@ -28,9 +28,7 @@
 class POLICY_EXPORT SchemaMap : public base::RefCountedThreadSafe<SchemaMap> {
  public:
   SchemaMap();
-  // Takes ownership of |map| (its contents will be swapped).
-  // TODO(emaxx): Change to use move semantics.
-  explicit SchemaMap(DomainMap& map);
+  explicit SchemaMap(DomainMap map);
 
   const DomainMap& GetDomains() const;
 
diff --git a/components/policy/core/common/schema_map_unittest.cc b/components/policy/core/common/schema_map_unittest.cc
index 746e216e..4ec31298 100644
--- a/components/policy/core/common/schema_map_unittest.cc
+++ b/components/policy/core/common/schema_map_unittest.cc
@@ -65,7 +65,7 @@
     DomainMap domain_map;
     domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
 
-    return new SchemaMap(domain_map);
+    return new SchemaMap(std::move(domain_map));
   }
 };
 
@@ -88,12 +88,13 @@
   component_map[""] = schema;
   DomainMap domain_map;
   domain_map[POLICY_DOMAIN_CHROME] = component_map;
-  map = new SchemaMap(domain_map);
+  map = new SchemaMap(std::move(domain_map));
   EXPECT_FALSE(map->HasComponents());
 
   // An extension schema does.
+  domain_map.clear();
   domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
-  map = new SchemaMap(domain_map);
+  map = new SchemaMap(std::move(domain_map));
   EXPECT_TRUE(map->HasComponents());
 }
 
@@ -132,7 +133,7 @@
 
   DomainMap domain_map;
   domain_map[POLICY_DOMAIN_EXTENSIONS]["abc"] = schema;
-  scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
+  scoped_refptr<SchemaMap> schema_map = new SchemaMap(std::move(domain_map));
 
   PolicyBundle bundle;
   schema_map->FilterBundle(&bundle, /*drop_invalid_component_policies=*/true);
@@ -232,7 +233,7 @@
   DomainMap domain_map;
   domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema;
   domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema();
-  scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
+  scoped_refptr<SchemaMap> schema_map = new SchemaMap(std::move(domain_map));
 
   // |bundle| contains policies loaded by a policy provider.
   PolicyBundle bundle;
@@ -290,7 +291,7 @@
   DomainMap domain_map;
   domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema;
   domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema();
-  scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
+  scoped_refptr<SchemaMap> schema_map = new SchemaMap(std::move(domain_map));
 
   // |bundle| contains policies loaded by a policy provider.
   PolicyBundle bundle;
@@ -349,9 +350,10 @@
 TEST_F(SchemaMapTest, GetChanges) {
   DomainMap map;
   map[POLICY_DOMAIN_CHROME][""] = Schema();
-  scoped_refptr<SchemaMap> older = new SchemaMap(map);
+  scoped_refptr<SchemaMap> older = new SchemaMap(std::move(map));
+  map.clear();
   map[POLICY_DOMAIN_CHROME][""] = Schema();
-  scoped_refptr<SchemaMap> newer = new SchemaMap(map);
+  scoped_refptr<SchemaMap> newer = new SchemaMap(std::move(map));
 
   PolicyNamespaceList removed;
   PolicyNamespaceList added;
@@ -359,17 +361,19 @@
   EXPECT_TRUE(removed.empty());
   EXPECT_TRUE(added.empty());
 
+  map.clear();
   map[POLICY_DOMAIN_CHROME][""] = Schema();
   map[POLICY_DOMAIN_EXTENSIONS]["xyz"] = Schema();
-  newer = new SchemaMap(map);
+  newer = new SchemaMap(std::move(map));
   newer->GetChanges(older, &removed, &added);
   EXPECT_TRUE(removed.empty());
   ASSERT_EQ(1u, added.size());
   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), added[0]);
 
   older = newer;
+  map.clear();
   map[POLICY_DOMAIN_EXTENSIONS]["abc"] = Schema();
-  newer = new SchemaMap(map);
+  newer = new SchemaMap(std::move(map));
   newer->GetChanges(older, &removed, &added);
   ASSERT_EQ(2u, removed.size());
   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), removed[0]);
diff --git a/components/policy/core/common/schema_registry.cc b/components/policy/core/common/schema_registry.cc
index ccd85bc..e357fbe 100644
--- a/components/policy/core/common/schema_registry.cc
+++ b/components/policy/core/common/schema_registry.cc
@@ -47,7 +47,7 @@
   DomainMap map(schema_map_->GetDomains());
   for (auto it = components.begin(); it != components.end(); ++it)
     map[domain][it->first] = it->second;
-  schema_map_ = new SchemaMap(map);
+  schema_map_ = new SchemaMap(std::move(map));
   Notify(true);
 }
 
@@ -55,7 +55,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DomainMap map(schema_map_->GetDomains());
   if (map[ns.domain].erase(ns.component_id) != 0) {
-    schema_map_ = new SchemaMap(map);
+    schema_map_ = new SchemaMap(std::move(map));
     Notify(false);
   } else {
     // Extension might be uninstalled before install so the associated policies
@@ -151,7 +151,7 @@
   DomainMap map(own_schema_map_->GetDomains());
   for (auto it = components.begin(); it != components.end(); ++it)
     map[domain][it->first] = it->second;
-  own_schema_map_ = new SchemaMap(map);
+  own_schema_map_ = new SchemaMap(std::move(map));
   Combine(true);
 }
 
@@ -159,7 +159,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DomainMap map(own_schema_map_->GetDomains());
   if (map[ns.domain].erase(ns.component_id) != 0) {
-    own_schema_map_ = new SchemaMap(map);
+    own_schema_map_ = new SchemaMap(std::move(map));
     Combine(false);
   } else {
     NOTREACHED();
@@ -210,7 +210,7 @@
       }
     }
   }
-  schema_map_ = new SchemaMap(map);
+  schema_map_ = new SchemaMap(std::move(map));
   Notify(has_new_schemas);
 }
 
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index 12025c3..0c7f91a 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -1813,7 +1813,7 @@
 
     // A policy is overridden by ChromeOS if it's running in a public session or
     // kiosk mode.
-    SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE = 4;
+    SOURCE_DEVICE_LOCAL_ACCOUNT_OVERRIDE_DEPRECATED = 4;
 
     // A policy is set by OS built-in tool on desktop.
     SOURCE_PLATFORM = 5;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index ac6daecb..93630fd 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -5366,6 +5366,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5386,6 +5387,7 @@
       'schema': { 'type': 'boolean' },
       'supported_on': ['chrome.*:85-', 'chrome_os:85-'],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5413,6 +5415,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5436,6 +5439,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5459,6 +5463,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5482,6 +5487,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5501,6 +5507,7 @@
       'supported_on': ['chrome.*:10-63', 'chrome_os:11-63', 'android:30-63'],
       'deprecated': True,
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5528,6 +5535,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5554,6 +5562,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5580,6 +5589,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5599,6 +5609,7 @@
       'supported_on': ['chrome.*:25-63', 'chrome_os:25-63', 'android:30-63'],
       'deprecated': True,
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5624,6 +5635,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5647,6 +5659,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5670,6 +5683,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5693,6 +5707,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5712,6 +5727,7 @@
       'supported_on': ['chrome.*:29-63', 'chrome_os:29-63', 'android:30-63'],
       'deprecated': True,
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -5737,6 +5753,7 @@
         'ios:88-',
       ],
       'features': {
+        'can_be_recommended': True,
         'dynamic_refresh': True,
         'per_profile': True,
       },
@@ -14034,7 +14051,7 @@
     },
     {
       'name': 'AttestationEnabledForDevice',
-      'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'],
+      'owners': ['emaxx@chromium.org', 'file://chrome/browser/ash/attestation/OWNERS'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
       'supported_on': ['chrome_os:28-'],
@@ -14053,7 +14070,7 @@
     },
     {
       'name': 'AttestationEnabledForUser',
-      'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'],
+      'owners': ['emaxx@chromium.org', 'file://chrome/browser/ash/attestation/OWNERS'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
       'supported_on': ['chrome_os:28-'],
@@ -14071,7 +14088,7 @@
     },
     {
       'name': 'AttestationExtensionAllowlist',
-      'owners': ['file://components/policy/resources/OWNERS', 'poromov@chromium.org'],
+      'owners': ['emaxx@chromium.org', 'file://chrome/browser/extensions/api/enterprise_platform_keys/OWNERS'],
       'type': 'list',
       'schema': {
         'type': 'array',
@@ -14092,7 +14109,7 @@
     },
     {
       'name': 'AttestationExtensionWhitelist',
-      'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'],
+      'owners': ['emaxx@chromium.org', 'file://chrome/browser/extensions/api/enterprise_platform_keys/OWNERS'],
       'type': 'list',
       'schema': {
         'type': 'array',
@@ -14116,7 +14133,7 @@
     },
     {
       'name': 'AttestationForContentProtectionEnabled',
-      'owners': ['file://components/policy/resources/OWNERS', 'rsorokin@chromium.org'],
+      'owners': ['emaxx@chromium.org', 'file://chrome/browser/ash/attestation/OWNERS'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
       'supported_on': ['chrome_os:31-'],
diff --git a/components/policy/resources/policy_templates_de.xtb b/components/policy/resources/policy_templates_de.xtb
index f33b81a..451ee5b 100644
--- a/components/policy/resources/policy_templates_de.xtb
+++ b/components/policy/resources/policy_templates_de.xtb
@@ -360,6 +360,13 @@
       Wenn die Richtlinie nicht konfiguriert ist, versucht <ph name="PRODUCT_NAME" /> zu ermitteln, ob sich ein Server im Intranet befindet. Es reagiert nur dann auf IWA-Anfragen. Wenn der Server sich dagegen im Internet befindet, werden dessen IWA-Anfragen von <ph name="PRODUCT_NAME" /> ignoriert.
 
       Trennen Sie mehrere Servernamen durch Kommas. Platzhalter wie <ph name="WILDCARD_VALUE" /> sind zulässig.</translation>
+<translation id="1495817006535797003">Wenn die Richtlinie konfiguriert ist, wird für jeden der benannten Ursprünge in einer durch Kommas getrennten Liste ein eigener Prozess ausgeführt. Dabei werden auch durch Subdomains benannte Ursprünge isoliert. Wenn Sie z. B. „https://beispiel.de/“ angeben, wird auch „https://xyz.beispiel.de/“ als Teil der Website „https://beispiel.de/“ isoliert.  Beachten Sie, dass Android bestimmte sensible Websites ab <ph name="PRODUCT_NAME" /> Version 77 standardmäßig isoliert. Diese Richtlinie weitet diesen Modus aus, sodass bestimmte zusätzliche Ursprünge isoliert werden.
+
+      Wenn diese Einstellung deaktiviert ist, wird jegliche Form der Website-Isolierung deaktiviert, einschließlich der Isolierung sensibler Websites und Tests von IsolateOriginsAndroid, SitePerProcessAndroid und anderer Website-Isolierungsmodi. Nutzer können aber weiterhin Befehlszeilen-Flags verwenden, um IsolateOrigins manuell zu aktivieren.
+
+      Ist diese Richtlinie nicht konfiguriert, können Nutzer diese Einstellung ändern.
+
+      Hinweis: Wenn unter Android zu viele Websites isoliert werden, kann dies Leistungsprobleme verursachen, vor allem auf leistungsschwächeren Geräten. Diese Richtlinie ist nur für Chrome unter Android auf Geräten mit mehr als 1 GB RAM gültig. Möchten Sie die Richtlinie auf anderen Plattformen als Android nutzen, verwenden Sie dafür <ph name="ISOLATE_ORIGINS_POLICY_NAME" />.</translation>
 <translation id="1502843533062797703">Blockieren von Codeeinschleusungen durch Drittanbieter-Software aktivieren</translation>
 <translation id="1503969899251962413">Mit dieser Richtlinie wird der <ph name="PLUGIN_VM_NAME" />-Lizenzschlüssel für dieses Gerät angegeben.
 
@@ -695,6 +702,7 @@
 <translation id="1930127294345368978">Maximal zulässige Anzahl Blätter für einen einzelnen Druckauftrag</translation>
 <translation id="193259052151668190">Whitelist mit trennbaren USB-Geräten</translation>
 <translation id="1933378685401357864">Hintergrundbild</translation>
+<translation id="1942626390957213764">Desktop-Freigabe-Hub deaktivieren</translation>
 <translation id="1945994447126139909">Diese Unternehmensrichtlinie kann nur übergangsweise verwendet werden und wird in Version 88 von <ph name="PRODUCT_NAME" /> entfernt.
 
       Die standardmäßige Verweisrichtlinie in Chrome wird verschärft. Hierzu wird der Standardwert von no-referrer-when-downgrade zum sichereren Wert strict-origin-when-cross-origin geändert. Die Umstellung erfolgt graduell und soll mit Chrome-Version 85 (stabil) abgeschlossen sein.
@@ -2436,6 +2444,9 @@
 <translation id="4086150283035515220">Wenn die Richtlinie aktiviert ist, werden Nutzer vor jedem Download nach dem gewünschten Speicherort gefragt. Ist die Richtlinie deaktiviert, beginnt der Download sofort und Nutzer werden nicht nach dem gewünschten Speicherort gefragt.
 
       Ist diese Richtlinie nicht konfiguriert, können Nutzer diese Einstellung ändern.</translation>
+<translation id="4087476676669545471">Wenn die Richtlinie auf „True“ gesetzt oder nicht konfiguriert ist, können Nutzer die aktuelle Webseite anhand der über den Desktop-Freigabe-Hub verfügbaren Aktionen teilen oder speichern. Auf den Freigabe-Hub wird über ein Omnibox-Symbol oder das Dreipunkt-Menü zugegriffen.
+
+       Wenn die Richtlinie auf „False“ gesetzt ist, wird das Freigabesymbol aus der Omnibox und der Eintrag aus dem Dreipunkt-Menü entfernt.</translation>
 <translation id="4088589230932595924">Inkognitomodus erzwungen</translation>
 <translation id="4089849819635523136">Wenn "<ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" />" aktiviert ist, gibt "<ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" />" den Suchbegriff oder die Verknüpfung an, die in der Adressleiste zum Starten der Suche für diesen Anbieter verwendet wird.
 
@@ -3109,11 +3120,6 @@
 <translation id="5078623750797048009">PDF-Anmerkungen aktivieren</translation>
 <translation id="5082572440690475059">Lesezugriff über die File System API auf diesen Websites erlauben</translation>
 <translation id="5085647276663819155">Druckvorschau deaktivieren</translation>
-<translation id="5087424855041813182">Wenn diese Richtlinie konfiguriert ist, können Sie eine Liste mit URL-Mustern erstellen, die angeben, welche Websites Benachrichtigungen anzeigen dürfen.
-
-      Wenn die Richtlinie nicht konfiguriert ist, gilt <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> für alle Websites, sofern konfiguriert. Falls nicht, wird die persönliche Einstellung des Nutzers verwendet.
-
-      Genaue Informationen zu gültigen <ph name="URL_LABEL" />-Mustern finden Sie unter https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> ist kein akzeptierter Wert für diese Richtlinie.</translation>
 <translation id="5090791951240382356">Zusammenführen von Wörterbuchrichtlinien aus unterschiedlichen Quellen erlauben</translation>
 <translation id="5091315650312105069"><ph name="BASIC_AUTH" /> die Authentifizierung für HTTP erlauben</translation>
 <translation id="5103112931744164177">Mit dieser Richtlinie wird festgelegt, welcher Software-Stack zur Kommunikation mit dem DNS-Server verwendet wird: der DNS-Client des Betriebssystems oder der integrierte DNS-Client von <ph name="PRODUCT_NAME" />. Sie beeinflusst nicht, welche DNS-Server verwendet werden. Wenn beispielsweise das Betriebssystem für die Verwendung eines Unternehmens-DNS-Servers konfiguriert ist, verwendet der integrierte DNS-Client genau diesen Server. Mit der Richtlinie wird auch nicht gesteuert, ob DoH (DNS over HTTPS) verwendet wird. <ph name="PRODUCT_NAME" /> nutzt immer den integrierten Resolver für DoH-Anfragen. Weitere Informationen zum Steuern von DoH finden Sie in der Richtlinie „<ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />“.
@@ -3390,6 +3396,7 @@
 
           Wenn die Richtlinie deaktiviert wird, ist die Funktion standardmäßig deaktiviert.
           </translation>
+<translation id="5435888298115339571">Desktop-Freigabe in der Omnibox und im Dreipunkt-Menü aktivieren</translation>
 <translation id="5442026853063570579">Mit dieser Richtlinie wird außerdem der Zugriff auf Android-Entwickleroptionen festgelegt. Wenn Sie diese Richtlinie auf "DeveloperToolsDisallowed" (Wert 2) setzen, können Nutzer nicht auf die Entwickleroptionen zugreifen. Wenn Sie diese Richtlinie auf einen anderen Wert setzen oder sie nicht festlegen, können Nutzer auf die Entwickleroptionen zugreifen, indem sie in der Android-App "Einstellungen" siebenmal auf die Build-Nummer tippen.</translation>
 <translation id="5445596354079213552">Diese Richtlinie wird nur angewendet, wenn das Gerät das Ablaufdatum für die automatische Aktualisierung erreicht hat und die durch die Richtlinie <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> festgelegte Mindestanforderung im Hinblick auf die <ph name="PRODUCT_OS_NAME" />-Version nicht mehr erfüllt.
 
@@ -4254,6 +4261,17 @@
       Wenn die Richtlinie nicht konfiguriert oder eine leere Liste festgelegt ist, gibt es keine lokalen Gerätekonten.</translation>
 <translation id="6584541828182430328">Anzeige von Vollbild-Warnung deaktivieren</translation>
 <translation id="6598235178374410284">Nutzer-Avatarbild</translation>
+<translation id="6601311299236772162">Diese Richtlinie legt fest, wie <ph name="PRODUCT_NAME" /> Richtlinien zu Websitelisten/Greylists für die Funktion zur Unterstützung älterer Browser interpretiert. Die folgenden Richtlinien sind betroffen: <ph name="URL_LIST_POLICY_NAME" />, <ph name="URL_GREYLIST_POLICY_NAME" />, <ph name="USE_IE_SITELIST_POLICY_NAME" />, <ph name="EXTERNAL_SITELIST_POLICY_NAME" /> und <ph name="EXTERNAL_GREYLIST_POLICY_NAME" />.
+
+      Wenn die Richtlinie auf „Default“ (0) gesetzt oder nicht konfiguriert ist, ist der URL-Abgleich weniger streng. Bei Regeln, die „/“ nicht enthalten, wird nach einem Teilstring im Hostnamen der URL gesucht.
+
+      Wenn die Richtlinie auf „Strict“ (1) gesetzt ist, ist der URL-Abgleich strenger. Bei Regeln, die „/“ nicht enthalten, wird nur der letzte Abschnitt des Hostnamens berücksichtigt. Sie müssen außerdem innerhalb des Bereichs für Domainnamen liegen. Dies bietet eine bessere Kompatibilität mit <ph name="MS_IE_PRODUCT_NAME" /> und <ph name="MS_EDGE_PRODUCT_NAME" />.
+
+      Beispiel anhand der Regel „beispiel.de“:
+
+      „http://beispiel.de/“ und „http://subdomain.beispiel.de/“ stimmen unabhängig vom Parsing-Modus überein.
+
+      „http://keinbeispiel.de/“, „http://beispiel.de.ungültig.com/“ und „http://beispiel.deabc/“ stimmen nur im Modus „Default“ überein.</translation>
 <translation id="6603004149426829878">Beim Auflösen der Zeitzone immer verfügbare Standortsignale an den Server senden</translation>
 <translation id="6604049565198492174">Wenn die Richtlinie aktiviert ist, ermöglicht sie, Netzwerkkonfigurationen auf <ph name="PRODUCT_NAME" />-Geräten für einzelne Nutzer zu übernehmen. Die Netzwerkkonfiguration ist ein String im JSON-Format, der der Definition des ONC-Formats (Open Network Configuration) entspricht.</translation>
 <translation id="660567106648774919">Diese Richtlinie ist veraltet. Bitte verwenden Sie stattdessen die Richtlinie <ph name="TOS_DIALOG_BEHAVIOR_POLICY_NAME" />.
@@ -4443,26 +4461,6 @@
 
           Hinweis: Sofern konfiguriert, überschreibt "<ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />" diese Richtlinie.</translation>
 <translation id="6833988859168635883">Start, Startseite und Seite "Neuer Tab"</translation>
-<translation id="6834298774555537368">Durch Festlegen der Richtlinie werden die Proxyeinstellungen für Chrome- und ARC-Apps so konfiguriert, dass alle Proxyoptionen, die über die Befehlszeile eingegeben werden, ignoriert werden.
-
-       Wird die Richtlinie nicht konfiguriert, können Nutzer die Proxyeinstellungen auswählen.
-
-       Durch Festlegen der Richtlinie „<ph name="PROXY_SETTINGS_POLICY_NAME" />“ werden die folgenden Felder übernommen:
-         * „<ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />“ legt fest, welcher Proxyserver von Chrome verwendet werden soll, und verhindert, dass Nutzer die Proxyeinstellungen ändern
-         * „<ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />“, die URL zu einer PAC-Proxydatei
-         * „<ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />“, die URL des Proxyservers
-         * „<ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />“, eine Liste mit Hosts, für die der Proxy umgangen wird
-
-       Das Feld „<ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" />“ wurde zugunsten des Felds „<ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />“ eingestellt.
-
-        Für „<ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />“ können folgende Werte festgelegt werden:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" /> – kein Proxy wird verwendet und alle anderen Felder werden ignoriert.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" /> – der Proxy des Systems wird verwendet und alle anderen Felder werden ignoriert.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" /> – alle anderen Felder werden ignoriert.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" /> – die Felder „<ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />“ und „<ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />“ werden verwendet.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" /> – die Felder „<ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" />“ und „<ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />“ werden verwendet.
-
-      Hinweis: Ausführliche Beispiele finden Sie in den Chromium-Projekten unter https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett.</translation>
 <translation id="6835883744948188639">Dem Nutzer eine wiederkehrende Aufforderung anzeigen, dass ein Neustart empfohlen wird</translation>
 <translation id="683688607121170501">Mit dieser Einstellung können Nutzer nach der Anmeldung auf ihrem <ph name="PRODUCT_OS_NAME" />-Gerät im Inhaltsbereich des Browserfensters und in Android-Apps zwischen Google-Konten wechseln.
 
@@ -4765,11 +4763,6 @@
 <translation id="7126928806195745404">JavaScript-Einstellungen</translation>
 <translation id="7127892035367404455">Rollback auf die Zielversion</translation>
 <translation id="7127980134843952133">Downloadverlauf</translation>
-<translation id="7129052644387688634">Wenn diese Richtlinie konfiguriert ist, können Sie eine Liste mit URL-Mustern erstellen, die angeben, welche Websites keine Benachrichtigungen anzeigen dürfen.
-
-      Wenn die Richtlinie nicht konfiguriert ist, gilt <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> für alle Websites, sofern konfiguriert. Falls nicht, wird die persönliche Einstellung des Nutzers verwendet.
-
-      Genaue Informationen zu gültigen <ph name="URL_LABEL" />-Mustern finden Sie unter https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> ist kein akzeptierter Wert für diese Richtlinie.</translation>
 <translation id="712963038874313213">Gibt ein Ansible-Playbook an, das im standardmäßigen Crostini-Container ausgeführt werden muss.
 
       Diese Richtlinie ermöglicht die Bereitstellung eines Ansible-Playbooks, das auf den standardmäßigen Crostini-Container angewendet wird, sofern er auf dem jeweiligen Gerät verfügbar und gemäß den Richtlinien zulässig ist.
@@ -5194,6 +5187,13 @@
 
           Der Wert für die Richtlinie muss in Millisekunden angegeben werden. Werte müssen kleiner oder gleich dem Wert der Verzögerung für die Bildschirmabschaltung (falls angegeben) und der Inaktivitätsverzögerung sein.</translation>
 <translation id="7680437377926096177">Dialogfeld für die Abmeldung beim Schließen des letzten Fensters nicht anzeigen.</translation>
+<translation id="7681958144280390173">Wenn die Richtlinie aktiviert ist, werden alle Websites isoliert. Jede Website wird dann in einem eigenen Prozess ausgeführt. Beachten Sie, dass Android bestimmte sensible Websites ab <ph name="PRODUCT_NAME" />-Version 77 standardmäßig isoliert. Diese Richtlinie weitet diesen standardmäßigen Website-Isolierungsmodus auf alle Websites aus.
+
+      Wenn diese Einstellung deaktiviert ist, wird jegliche Form der Website-Isolierung deaktiviert, einschließlich der Isolierung sensibler Websites und Tests von IsolateOriginsAndroid, SitePerProcessAndroid und anderer Website-Isolierungsmodi. Nutzer können die Richtlinie aber weiterhin manuell aktivieren.
+
+      Wenn die Richtlinie nicht konfiguriert ist, können Nutzer diese Einstellung ändern.
+
+      Hinweis: Die Unterstützung der Isolierung jeder Website unter Android wird weiter verbessert. Derzeit kann sie aber Leistungsprobleme verursachen, vor allem auf leistungsschwächeren Geräten. Diese Richtlinie ist nur für Chrome unter Android auf Geräten mit mehr als 1 GB RAM gültig. Wenn Sie bestimmte Websites isolieren und die Leistungseinbußen dabei so gering wie möglich halten möchten, verwenden Sie <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> für eine Liste der Websites, die isoliert werden sollen.  Möchten Sie die Richtlinie auf anderen Plattformen als Android nutzen, verwenden Sie dafür <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation>
 <translation id="7683777542468165012">Dynamische Richtlinienaktualisierung</translation>
 <translation id="7687943045976362719">Wenn diese Richtlinie konfiguriert ist, wird für alle angegebenen Inhaltstypen <ph name="PRODUCT_FRAME_NAME" /> verwendet.
 
@@ -5896,6 +5896,7 @@
       Ist die Richtlinie nicht konfiguriert, öffnet sich die „Neuer Tab“-Seite beim Start.
 
       Unter <ph name="MS_WIN_NAME" /> steht diese Funktion nur bei Instanzen zur Verfügung, die Teil einer <ph name="MS_AD_NAME" />-Domain sind, auf denen Windows 10 Pro läuft oder die über <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> verwaltet werden. Unter <ph name="MAC_OS_NAME" /> steht diese Funktion nur bei Instanzen zur Verfügung, die über die Mobilgeräteverwaltung verwaltet werden oder per MCX mit einer Domain verbunden sind.</translation>
+<translation id="8671119576957984818">Desktop-Freigabe-Hub aktivieren</translation>
 <translation id="8672321184841719703">Automatische Aktualisierung auf Zielversion</translation>
 <translation id="867410340948518937">U2F (Universal Second Factor)</translation>
 <translation id="8676959842615154675">Wenn diese Richtlinie aktiviert ist, vergleicht der Host für den Remotezugriff den Namen des mit dem Host verknüpften lokalen Nutzers mit dem Namen des Google-Kontos, das als Hosteigentümer registriert ist (z. B. „maxmustermann“, wenn der Hosteigentümer das Google-Konto „maxmustermann@beispiel.de“ ist). Dieser Host wird nicht gestartet, wenn der Name des Hosteigentümers vom Namen des mit dem Host verknüpften lokalen Nutzers abweicht. Wenn Sie erzwingen möchten, dass das Google-Konto des Eigentümers mit einer bestimmten Domain verknüpft ist, verwenden Sie die Richtlinie mit <ph name="REMOTE_ACCESS_HOST_DOMAIN_POLICY_NAME" />.
diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb
index a01ac0c..483dae6 100644
--- a/components/policy/resources/policy_templates_es-419.xtb
+++ b/components/policy/resources/policy_templates_es-419.xtb
@@ -366,6 +366,13 @@
       Si no estableces la política, <ph name="PRODUCT_NAME" /> intentará detectar si un servidor se encuentra en la intranet. Solo en ese caso responderá a las solicitudes de IWA. Si se detecta un servidor como Internet, <ph name="PRODUCT_NAME" /> ignorará las solicitudes de IWA que provengan de ese servidor.
 
       Nota: Los nombres de los servidores se separan con comas. Se permite el uso de caracteres comodín (<ph name="WILDCARD_VALUE" />).</translation>
+<translation id="1495817006535797003">Si estableces la política, se ejecutarán en su propios procesos los orígenes designados en una lista de elementos separados por comas. Además, se aislarán los orígenes designados a partir de subdominios. Por ejemplo, si especificas https://example.com/, también se aislará https://foo.example.com/ como parte del sitio https://example.com/.  Ten en cuenta que Android aísla algunos sitios sensibles de forma predeterminada a partir de la versión 77 de <ph name="PRODUCT_NAME" /> y que esta política extiende ese modo para aislar orígenes adicionales específicos.
+
+      Si inhabilitas la política, se desactivará toda forma de aislamiento de sitios, incluido el aislamiento de sitios sensibles y pruebas de campo de IsolateOriginsAndroid, SitePerProcessAndroid y otros modos de aislamiento de sitios. Los usuarios aún podrán activar IsolateOrigins de forma manual usando esa función experimental de línea de comandos.
+
+      Si no estableces la política, los usuarios podrán cambiar esta configuración.
+
+      Nota: Si aíslas demasiados sitios en Android, es posible que se generen problemas de rendimiento, en especial en dispositivos con poca memoria. Esta política solo se aplica a Chrome cuando se ejecuta en dispositivos con Android que tienen exclusivamente más de 1 GB de RAM. Para aplicar la política en plataformas que no tienen Android, utiliza <ph name="ISOLATE_ORIGINS_POLICY_NAME" />.</translation>
 <translation id="1502843533062797703">Habilitar el bloqueo de inserción de software de terceros</translation>
 <translation id="1503969899251962413">Si estableces la política, se especificará la clave de licencia <ph name="PLUGIN_VM_NAME" /> para este dispositivo.
 
@@ -700,6 +707,7 @@
 <translation id="1930127294345368978">Cantidad máxima de hojas permitidas para un solo trabajo de impresión</translation>
 <translation id="193259052151668190">Lista blanca de dispositivos USB que se pueden separar</translation>
 <translation id="1933378685401357864">Imagen de fondo de pantalla</translation>
+<translation id="1942626390957213764">Inhabilitar el centro para compartir el escritorio</translation>
 <translation id="1945994447126139909">Esta política empresarial es una adaptación por corto plazo y se quitará en la versión 88 de <ph name="PRODUCT_NAME" />.
 
       Para fortalecer la política del referente predeterminado de Chrome, su valor actual de "sin referente cuando cambia a una versión inferior" cambia al valor más seguro "origen estricto cuando el origen es cruzado" mediante un lanzamiento gradual que apunta a la versión 85 estable.
@@ -2456,6 +2464,9 @@
 <translation id="4086150283035515220">Si habilitas la política, se les preguntará a los usuarios dónde guardar los archivos antes de descargarlos. Si la inhabilitas, las descargas se iniciarán inmediatamente; no se les preguntará a los usuarios dónde guardar los archivos.
 
       Si no estableces la política, los usuarios podrán cambiar esta configuración.</translation>
+<translation id="4087476676669545471">Si estableces la política como verdadera o no la estableces, los usuarios podrán compartir o guardar la página web actual mediante acciones proporcionadas por el centro para compartir el escritorio. Se puede acceder al centro para compartir a través del cuadro multifunción o el menú de 3 puntos.
+
+       Si estableces la política como falsa, dejará de estar disponible el ícono para compartir en el cuadro multifunción y en el menú de 3 puntos.</translation>
 <translation id="4088589230932595924">Modo incógnito forzado</translation>
 <translation id="4089849819635523136">Si activas <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" />, establecer <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" /> especificará la palabra clave o el atajo que se utilizará en la barra de direcciones para activar la búsqueda de este proveedor.
 
@@ -3130,11 +3141,6 @@
 <translation id="5078623750797048009">Habilitar las anotaciones en archivos PDF</translation>
 <translation id="5082572440690475059">Permite el acceso de lectura a través de la API de File System en estos sitios</translation>
 <translation id="5085647276663819155">Inhabilitar vista previa de impresión</translation>
-<translation id="5087424855041813182">Si estableces la política, podrás especificar una lista de patrones de URL que indiquen los sitios que pueden mostrar notificaciones.
-
-      Si no estableces la política, se aplicará <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> para todos los sitios, en caso de haberse establecido. De lo contrario se aplicará la configuración personal del usuario.
-
-      Para obtener información detallada sobre los patrones de <ph name="URL_LABEL" /> válidos, consulta https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> no es un valor aceptado para esta política.</translation>
 <translation id="5090791951240382356">Permitir la combinación de políticas de diccionarios con diferentes fuentes</translation>
 <translation id="5091315650312105069">Permitir la autenticación <ph name="BASIC_AUTH" /> para HTTP</translation>
 <translation id="5103112931744164177">Esta política controla la pila de software que se utiliza para establecer la comunicación con el servidor DNS: el cliente DNS del sistema operativo o el cliente DNS integrado de <ph name="PRODUCT_NAME" />. Esta política no cambia los servidores DNS que se utilizan: si, por ejemplo, el sistema operativo está configurado para usar un servidor DNS empresarial, el cliente DNS integrado utilizará ese mismo servidor. Tampoco controla si se utiliza el protocolo DNS por HTTPS; <ph name="PRODUCT_NAME" /> siempre utilizará el agente de resolución integrado para las solicitudes del protocolo DNS por HTTPS. Para obtener información sobre el control de este protocolo, consulta la política <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />.
@@ -3411,6 +3417,7 @@
 
           Si la inhabilitas, se desactivará esta función de forma forzosa.
           </translation>
+<translation id="5435888298115339571">Habilitar el uso compartido del escritorio en el cuadro multifunción y el menú de 3 puntos</translation>
 <translation id="5442026853063570579">Esta política también controla el acceso a las Opciones para desarrolladores de Android. Si estableces esta política como "DeveloperToolsDisallowed" (valor 2), los usuarios no pueden acceder a las Opciones para desarrolladores. Si la estableces con otro valor o la dejas sin establecer, los usuarios pueden acceder a las Opciones para desarrolladores al presionar siete veces el número de versión en la app de Configuración de Android.</translation>
 <translation id="5445596354079213552">Esta política solo es válida si se alcanzó la fecha de vencimiento de las actualizaciones automáticas para el dispositivo y no se cumple el requisito de versión mínima permitida de <ph name="PRODUCT_OS_NAME" /> que se estableció en la política <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" />.
 
@@ -4283,6 +4290,17 @@
       Si no estableces la política o la defines con una lista vacía, no habrá ninguna cuenta local del dispositivo.</translation>
 <translation id="6584541828182430328">Inhabilita la alerta de pantalla completa</translation>
 <translation id="6598235178374410284">Imagen de avatar del usuario</translation>
+<translation id="6601311299236772162">Esta política controla la manera en la que <ph name="PRODUCT_NAME" /> interpreta las políticas de listas de sitios o listas grises para la función Compatibilidad con navegadores heredados. Afecta las siguientes políticas: <ph name="URL_LIST_POLICY_NAME" />, <ph name="URL_GREYLIST_POLICY_NAME" />, <ph name="USE_IE_SITELIST_POLICY_NAME" />, <ph name="EXTERNAL_SITELIST_POLICY_NAME" /> y <ph name="EXTERNAL_GREYLIST_POLICY_NAME" />.
+
+      Si estableces la política como "Default" (0) o no la estableces, las coincidencias de URL serán menos estrictas. Las reglas que no incluyan "/" buscarán un substring en el nombre de host de la URL.
+
+      Si estableces la política como "Strict" (1), las coincidencias de URL serán más estrictas. Las reglas que no incluyan "/" solo buscarán coincidencias al final del nombre de host. Las reglas deben estar en el límite de un nombre de dominio. Es más compatible con <ph name="MS_IE_PRODUCT_NAME" /> y <ph name="MS_EDGE_PRODUCT_NAME" />.
+
+      Por ejemplo, con la regla "example.com":
+
+      "http://example.com/" y "http://subdomain.example.com/" coinciden, independientemente del modo de análisis.
+
+      "http://notexample.com/", "http://example.com.invalid.com/" y "http://example.comabc/" solo coinciden en el modo "Default".</translation>
 <translation id="6603004149426829878">Enviar siempre cualquier señal de ubicación disponible al servidor mientras se determina la zona horaria</translation>
 <translation id="6604049565198492174">Si estableces la política, se podrá aplicar la configuración de red por usuario de cada dispositivo <ph name="PRODUCT_NAME" />. La configuración de red es una string en formato JSON, como la define el formato Open Network Configuration.</translation>
 <translation id="660567106648774919">Esta política dejó de estar disponible. En su lugar, utiliza <ph name="TOS_DIALOG_BEHAVIOR_POLICY_NAME" />.
@@ -4472,26 +4490,6 @@
 
           Nota: Si se especifica <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />, anulará esta política.</translation>
 <translation id="6833988859168635883">Página de inicio, página principal y página Nueva pestaña</translation>
-<translation id="6834298774555537368">Si estableces la política, se especificará la configuración de proxy para Chrome y las apps de ARC, por lo que se ignorarán todas las opciones relacionadas con el proxy que se especifiquen desde la línea de comandos.
-
-       Si no la estableces, los usuarios podrán elegir su configuración de proxy.
-
-       Si estableces la política <ph name="PROXY_SETTINGS_POLICY_NAME" />, se aceptarán los siguientes campos:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> (podrás especificar el servidor proxy que usa Chrome y evitar que los usuarios cambien la configuración del proxy)
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> (dirección URL a un archivo de proxy en formato .pac)
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> (dirección URL al servidor proxy)
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> (lista de hosts que omitirán el proxy)
-
-       El campo <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> dejó de estar disponible. En su lugar, aparece el campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Para <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, puedes elegir alguno de los valores siguientes:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, no se usará nunca un proxy y se ignorará el resto de los campos.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, se usará el proxy del sistema y se ignorará el resto de los campos.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, se ignorará el resto de los campos.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, se usarán los campos <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> y <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, se usarán los campos <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> y <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-
-      Nota: Para obtener más ejemplos detallados, visita The Chromium Projects ( https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett ).</translation>
 <translation id="6835883744948188639">Mostrar un mensaje recurrente al usuario para indicarle que se recomienda llevar a cabo el reinicio</translation>
 <translation id="683688607121170501">Esta configuración permite que los usuarios cambien entre Cuentas de Google en el área de contenido de la ventana del navegador y en apps de Android después de acceder en el dispositivo con <ph name="PRODUCT_OS_NAME" />.
 
@@ -4791,11 +4789,6 @@
 <translation id="7126928806195745404">Configuración de JavaScript</translation>
 <translation id="7127892035367404455">Reversión a la versión objetivo</translation>
 <translation id="7127980134843952133">Historial de descargas</translation>
-<translation id="7129052644387688634">Si estableces la política, podrás especificar una lista de patrones de URL que indiquen los sitios que no pueden mostrar notificaciones.
-
-      Si no estableces la política, se aplicará <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> para todos los sitios, en caso de haberse establecido. De lo contrario se aplicará la configuración personal del usuario.
-
-      Para obtener información detallada sobre los patrones de <ph name="URL_LABEL" /> válidos, consulta https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> no es un valor aceptado para esta política.</translation>
 <translation id="712963038874313213">Proporciona un playbook de Ansible que debe ejecutarse en el contenedor predeterminado de Crostini.
 
       Esta política proporciona un playbook de Ansible para aplicarlo en el contenedor predeterminado de Crostini si este está disponible en el dispositivo determinado y si lo permiten las políticas.
@@ -5222,6 +5215,13 @@
 
           El valor de la política debe especificarse en milisegundos. Los valores deben ser menores o iguales que la demora de pantalla apagada (si está configurada) y la demora por inactividad.</translation>
 <translation id="7680437377926096177">No mostrar el diálogo de salida cuando se cierra la última ventana</translation>
+<translation id="7681958144280390173">Si habilitas la política, se aislarán todos los sitios (cada sitio se ejecutará en su propio proceso). Ten en cuenta que Android aísla algunos sitios sensibles de forma predeterminada a partir de la versión 77 de <ph name="PRODUCT_NAME" /> y que esta política extiende la aplicación de ese modo predeterminado de aislamiento de sitios a todos los sitios.
+
+      Si inhabilitas la política, se desactivará toda forma de aislamiento de sitios, incluido el aislamiento de sitios sensibles y pruebas de campo de IsolateOriginsAndroid, SitePerProcessAndroid y otros modos de aislamiento de sitios. Los usuarios aún podrán activar la política manualmente.
+
+      Si no estableces la política, los usuarios podrán cambiar esta configuración.
+
+      Nota: Mejorará la compatibilidad para aislar todos los sitios en Android, pero, por el momento, es posible que esta acción genere problemas de rendimiento, en especial en dispositivos de gama baja. Esta política solo se aplica a Chrome cuando se ejecuta en dispositivos con Android que tienen exclusivamente más de 1 GB de RAM. Para aislar sitios específicos y limitar el impacto del rendimiento para los usuarios, utiliza <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> con una lista de los sitios que quieras aislar.  Para aplicar la política en plataformas que no tienen Android, utiliza <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation>
 <translation id="7683777542468165012">Actualizar política dinámica</translation>
 <translation id="7687943045976362719">Si se configura esta política, <ph name="PRODUCT_FRAME_NAME" /> determinará los tipos de contenido especificados.
 
@@ -5946,6 +5946,7 @@
       Si no la estableces, se abrirá la página Nueva pestaña al iniciar el navegador.
 
       En <ph name="MS_WIN_NAME" />, esta funcionalidad solo estará disponible en instancias que están vinculadas a un dominio de <ph name="MS_AD_NAME" />, están inscritas en <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> o se ejecutan en Windows 10 Pro. En <ph name="MAC_OS_NAME" />, esta funcionalidad solo está disponible en instancias administradas mediante MDM o vinculadas a un dominio a través de MCX.</translation>
+<translation id="8671119576957984818">Habilitar el centro para compartir el escritorio</translation>
 <translation id="8672321184841719703">Versión de destino para las actualizaciones automáticas</translation>
 <translation id="867410340948518937">U2F (segundo factor universal)</translation>
 <translation id="8676959842615154675">Si habilitas la política, el host de acceso remoto comparará el nombre del usuario local con el que está asociado el host y el nombre de la Cuenta de Google registrado como el propietario del host ("juanperez" si el host le pertenece a "juanperez@ejemplo.com"). No se iniciará el host si el nombre del propietario del host es diferente del nombre del usuario local con el que está asociado el host. Para asociar de forma forzosa la Cuenta de Google del propietario con un dominio específico, utiliza la política con <ph name="REMOTE_ACCESS_HOST_DOMAIN_POLICY_NAME" />.
diff --git a/components/policy/resources/policy_templates_es.xtb b/components/policy/resources/policy_templates_es.xtb
index 82a4e7c..f15aabfad 100644
--- a/components/policy/resources/policy_templates_es.xtb
+++ b/components/policy/resources/policy_templates_es.xtb
@@ -3155,11 +3155,6 @@
 <translation id="5078623750797048009">Habilitar anotaciones en PDF</translation>
 <translation id="5082572440690475059">Permitir el acceso de lectura a través de la API File System en estos sitios web</translation>
 <translation id="5085647276663819155">Inhabilitar vista previa de impresión</translation>
-<translation id="5087424855041813182">Si le asignas un valor a esta política, podrás establecer una lista de patrones de URL donde se especifique qué sitios pueden mostrar notificaciones.
-
-      Si no se le asigna ningún valor a esta política, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> se aplicará a todos los sitios, si se ha definido. Si no se ha definido, se aplicará la configuración personal del usuario.
-
-      Para obtener información detallada sobre los patrones de <ph name="URL_LABEL" /> válidos, consulta https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> no es un valor aceptado para esta política.</translation>
 <translation id="5090791951240382356">Permite combinar políticas de diccionario de fuentes distintas</translation>
 <translation id="5091315650312105069">Permitir la autenticación <ph name="BASIC_AUTH" /> para conexiones HTTP</translation>
 <translation id="5103112931744164177">Esta política controla qué pila de software se utiliza para comunicarse con el servidor DNS: el cliente DNS del sistema operativo o el cliente DNS integrado de <ph name="PRODUCT_NAME" />. Esta política no afecta a qué servidores DNS se utilizan. Por ejemplo, si el sistema operativo está configurado para utilizar un servidor DNS de empresa, el cliente DNS integrado usará ese mismo servidor. Tampoco controla si se usará DNS‑over‑HTTPS; <ph name="PRODUCT_NAME" /> siempre utilizará la resolución integrada para solicitudes DNS‑over‑HTTPS. Consulta la política <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> para obtener información sobre los controles de DNS‑over‑HTTPS.
@@ -4511,26 +4506,6 @@
 
           Nota: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> anula esta política si se especifica la anterior.</translation>
 <translation id="6833988859168635883">Inicio, Página principal y página Nueva pestaña</translation>
-<translation id="6834298774555537368">Si se establece la política, se definirá la configuración de proxy aplicable a Chrome y a las aplicaciones ARC, que ignoran todas las opciones relacionadas con el proxy especificadas en la línea de comandos.
-
-       Si no se establece la política, los usuarios podrán elegir su configuración de proxy.
-
-       Si se establece la política <ph name="PROXY_SETTINGS_POLICY_NAME" />, se aceptarán los siguientes campos:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />: permite especificar el servidor proxy que usará Chrome. Además, impide que los usuarios puedan cambiar la configuración del proxy.
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />: URL a un archivo .pac de proxy.
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />: URL del servidor proxy.
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />: lista de hosts que determinarán que se evite el proxy.
-
-       El campo <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> está obsoleto y ha sido sustituido por el campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Si en el campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> eliges el valor:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />: nunca se usará un proxy y se ignorarán los demás campos.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />: se usará el proxy del sistema y se ignorarán el resto de los campos.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />: se ignorarán los demás campos.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />: se usarán los campos <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> y <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />: se usarán los campos <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> y <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-
-      Nota: Puedes consultar más ejemplos detallados en The Chromium Projects: https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett</translation>
 <translation id="6835883744948188639">Mostrar un mensaje periódico al usuario indicando que se recomienda reiniciar el navegador</translation>
 <translation id="683688607121170501">Esta opción permite que los usuarios cambien de una cuenta de Google a otra en el área de contenido de la ventana de su navegador y en las aplicaciones de Android después de haber iniciado sesión en su dispositivo <ph name="PRODUCT_OS_NAME" />.
 
@@ -4832,11 +4807,6 @@
 <translation id="7126928806195745404">Configuración de JavaScript</translation>
 <translation id="7127892035367404455">Vuelve a instalar la versión de destino</translation>
 <translation id="7127980134843952133">Historial de descargas</translation>
-<translation id="7129052644387688634">Si le asignas un valor a esta política, podrás establecer una lista de patrones de URL donde se especifique qué sitios no pueden mostrar notificaciones.
-
-      Si no se le asigna ningún valor a esta política, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> se aplicará a todos los sitios, si se ha definido. Si no se ha definido, se aplicará la configuración personal del usuario.
-
-      Para obtener información detallada sobre los patrones de <ph name="URL_LABEL" /> válidos, consulta https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> no es un valor aceptado para esta política.</translation>
 <translation id="712963038874313213">Proporciona un playbook de Ansible que debe ejecutarse en el contenedor de Crostini predeterminado.
 
       Esta política permite proporcionar un playbook de Ansible para que se aplique al contenedor de Crostini predeterminado (si está disponible en el dispositivo y las políticas lo permiten).
diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb
index 5c96e45a..65a6521 100644
--- a/components/policy/resources/policy_templates_fr.xtb
+++ b/components/policy/resources/policy_templates_fr.xtb
@@ -366,6 +366,13 @@
       Si cette règle n'est pas configurée, <ph name="PRODUCT_NAME" /> essaie de détecter si un serveur se trouve sur l'intranet et répond aux requêtes IWA seulement si c'est le cas. Si un serveur est détecté sur Internet, <ph name="PRODUCT_NAME" /> ignore alors les requêtes IWA.
 
       Remarque : S'il y a plusieurs serveurs, séparez leur nom par une virgule. Les caractères génériques (<ph name="WILDCARD_VALUE" />) sont autorisés.</translation>
+<translation id="1495817006535797003">Si cette règle est activée, chacune des origines définies et répertoriées dans une liste d'éléments séparés par une virgule exécute son propre processus et isole les origines par sous-domaines. Par exemple, si vous indiquez https://example.com/, https://foo.example.com/ est isolé en tant que partie du site https://example.com/.  Sachez qu'Android isole certains sites sensibles par défaut depuis <ph name="PRODUCT_NAME" /> 77. Cette règle étend ce mode d'isolation aux sites d'autres origines en particulier.
+
+      Si cette règle est désactivée, toute forme d'isolation de sites l'est aussi, y compris l'isolation des sites sensibles et des tests en conditions réelles d'IsolateOriginsAndroid et de SitePerProcessAndroid, et les autres modes d'isolation de sites. Les utilisateurs peuvent quand même activer manuellement IsolateOrigins à l'aide de l'indicateur de ligne de commande.
+
+      Si cette règle n'est pas configurée, les utilisateurs peuvent modifier ce paramètre.
+
+      Remarque : L'isolation de trop nombreux sites sur Android peut entraîner des problèmes de performances, surtout sur les appareils disposant de peu de mémoire. Cette règle ne concerne que les appareils Android dans Chrome, qui ont plus de 1 Go de RAM. Pour l'appliquer sur des plates-formes autres qu'Android, utilisez <ph name="ISOLATE_ORIGINS_POLICY_NAME" />.</translation>
 <translation id="1502843533062797703">Activer le blocage de l'injection de logiciels tiers</translation>
 <translation id="1503969899251962413">Cette règle permet de spécifier la clé de licence <ph name="PLUGIN_VM_NAME" /> pour cet appareil.
 
@@ -706,6 +713,7 @@
 <translation id="1930127294345368978">Nombre maximal de feuilles pouvant être imprimées par tâche d'impression</translation>
 <translation id="193259052151668190">Liste blanche d'appareils USB amovibles</translation>
 <translation id="1933378685401357864">Image de fond d'écran</translation>
+<translation id="1942626390957213764">Désactiver le hub de partage du bureau</translation>
 <translation id="1945994447126139909">Cette règle permet d'assurer la transition à court terme vers <ph name="PRODUCT_NAME" /> 88, après quoi elle sera supprimée.
 
       La règle par défaut de Chrome concernant l'URL de provenance est renforcée. L'objectif est de favoriser une transition progressive de sa valeur actuelle (no-referrer-when-downgrade) à une nouvelle valeur plus sécurisée (strict-origin-when-cross-origin) afin d'obtenir une version Chrome 85 stable.
@@ -2444,6 +2452,9 @@
 <translation id="4086150283035515220">Si cette règle est activée, les utilisateurs doivent toujours spécifier le répertoire de destination d'un fichier avant de le télécharger. Si cette règle est désactivée, le téléchargement commence immédiatement. Les utilisateurs n'ont pas besoin de spécifier une destination.
 
       Si cette règle n'est pas configurée, les utilisateurs peuvent modifier ce paramètre.</translation>
+<translation id="4087476676669545471">Si cette règle est définie sur "True" ou si elle n'est pas configurée, les utilisateurs peuvent partager ou enregistrer la page Web actuelle à l'aide d'actions réalisables dans le hub de partage du bureau. Le hub de partage est accessible via l'icône de l'omnibox ou le menu à trois points.
+
+       Si la règle est définie sur "False", l'icône de partage est supprimée de l'omnibox et l'entrée est supprimée du menu à trois points.</translation>
 <translation id="4088589230932595924">Mode navigation privée forcé</translation>
 <translation id="4089849819635523136">Si la règle <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> est activée, la règle <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" /> vous permet de spécifier le mot clé ou le raccourci utilisé dans la barre d'adresse pour déclencher la recherche avec ce moteur de recherche.
 
@@ -3115,11 +3126,6 @@
 <translation id="5078623750797048009">Activer les annotations des PDF</translation>
 <translation id="5082572440690475059">Autoriser l'accès en lecture via l'API File System pour ces sites</translation>
 <translation id="5085647276663819155">Désactiver l'aperçu avant impression</translation>
-<translation id="5087424855041813182">Permet de dresser la liste des formats d'URL pour lesquels les sites sont autorisés à afficher des notifications.
-
-      Si cette règle n'est pas configurée, la règle <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> s'applique pour tous les sites, à condition qu'elle soit définie. Si ce n'est pas le cas, le paramètre défini par l'utilisateur s'applique.
-
-      Pour en savoir plus sur les formats <ph name="URL_LABEL" /> valides, veuillez consulter la page https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. La valeur <ph name="WILDCARD_VALUE" /> n'est pas acceptée pour cette règle.</translation>
 <translation id="5090791951240382356">Autoriser la fusion de règles de dictionnaire qui proviennent de sources différentes</translation>
 <translation id="5091315650312105069">Autoriser l'authentification <ph name="BASIC_AUTH" /> pour HTTP</translation>
 <translation id="5103112931744164177">Cette règle détermine la pile logicielle utilisée pour communiquer avec le serveur DNS, c'est-à-dire soit le client DNS du système d'exploitation, soit le client DNS intégré de <ph name="PRODUCT_NAME" />. Cette règle n'a aucune incidence sur les serveurs DNS utilisés : si, par exemple, le système d'exploitation est configuré pour utiliser un serveur DNS d'entreprise, ce même serveur sera utilisé par le client DNS intégré. Elle ne contrôle pas non plus l'utilisation du protocole DNS-over-HTTPS. <ph name="PRODUCT_NAME" /> utilisera toujours le résolveur intégré pour les requêtes DNS-over-HTTPS. Pour plus d'informations sur le contrôle du protocole DNS-over-HTTPS, veuillez consulter la règle <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />.
@@ -3397,6 +3403,7 @@
 
           Si cette règle est désactivée, cette fonctionnalité est désactivée de façon forcée.
           </translation>
+<translation id="5435888298115339571">Activer le partage du bureau dans l'omnibox et le menu à trois points</translation>
 <translation id="5442026853063570579">Cette règle permet également de contrôler l'accès aux options pour les développeurs Android. Si vous définissez cette règle sur "DeveloperToolsDisallowed" (valeur 2), les utilisateurs ne pourront pas accéder aux options pour les développeurs. Si vous la définissez sur une autre valeur ou si vous ne la modifiez pas, les utilisateurs pourront accéder aux options pour les développeurs en appuyant sept fois sur le numéro de version dans l'application des paramètres Android.</translation>
 <translation id="5445596354079213552">Cette règle n'est appliquée que si la date d'expiration des mises à jour automatiques associée à l'appareil est atteinte et que celui-ci ne répond pas aux exigences de version minimale pour <ph name="PRODUCT_OS_NAME" />, définies dans la règle <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" />.
 
@@ -4269,6 +4276,17 @@
       Si cette règle n'est pas configurée ou que la liste est vide, aucun compte local de l'appareil n'est affiché.</translation>
 <translation id="6584541828182430328">Désactiver l'affichage de l'alerte plein écran</translation>
 <translation id="6598235178374410284">Avatar de l'utilisateur</translation>
+<translation id="6601311299236772162">Cette règle contrôle la façon dont <ph name="PRODUCT_NAME" /> interprète les règles des listes grises/de sites pour la fonctionnalité Legacy Browser Support. Cela concerne ces règles : <ph name="URL_LIST_POLICY_NAME" />, <ph name="URL_GREYLIST_POLICY_NAME" />, <ph name="USE_IE_SITELIST_POLICY_NAME" />, <ph name="EXTERNAL_SITELIST_POLICY_NAME" /> et <ph name="EXTERNAL_GREYLIST_POLICY_NAME" />.
+
+      Si la valeur est définie sur "Par défaut" (0) ou n'est pas spécifiée, la correspondance d'URL est moins stricte. Les règles qui n'incluent pas "/" recherchent une sous-chaîne dans le nom d'hôte de l'URL.
+
+      Si la valeur est définie sur "Strict" (1), la correspondance d'URL est plus stricte. Les règles qui n'incluent pas "/" n'établissent une correspondance qu'avec la fin du nom d'hôte. Elles doivent être associées à la limite d'un nom de domaine. La compatibilité est meilleure avec <ph name="MS_IE_PRODUCT_NAME" /> et <ph name="MS_EDGE_PRODUCT_NAME" />.
+
+      Par exemple, pour la règle "example.com" :
+
+      "http://example.com/" et "http://subdomain.example.com/" correspondent, quel que soit le mode d'analyse.
+
+      "http://notexample.com/", "http://example.com.invalid.com/" et "http://example.comabc/" correspondent uniquement en mode "Par défaut".</translation>
 <translation id="6603004149426829878">Toujours transmettre les signaux de localisation disponibles au serveur tout en mettant à jour le fuseau horaire</translation>
 <translation id="6604049565198492174">Si cette règle est activée, la configuration réseau est appliquée par utilisateur pour chaque appareil <ph name="PRODUCT_NAME" />. La configuration réseau est une chaîne au format JSON conformément au format de configuration de réseau ouvert.</translation>
 <translation id="660567106648774919">Cette règle est obsolète (veuillez utiliser la règle <ph name="TOS_DIALOG_BEHAVIOR_POLICY_NAME" /> à la place).
@@ -4458,26 +4476,6 @@
 
           Remarque : <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> remplace cette règle si l'ancienne est définie.</translation>
 <translation id="6833988859168635883">Démarrage, page d'accueil et page Nouvel onglet</translation>
-<translation id="6834298774555537368">Cette règle permet de configurer les paramètres de proxy pour Chrome et les applis ARC, qui ignorent toutes les options liées au proxy spécifiées à partir de la ligne de commande.
-
-       Si cette règle n'est pas configurée, les utilisateurs peuvent sélectionner les paramètres de proxy.
-
-       Si la règle <ph name="PROXY_SETTINGS_POLICY_NAME" /> est configurée, les champs suivants sont proposés :
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> : qui vous permet de spécifier le serveur proxy que Chrome utilise et empêche les utilisateurs de modifier les paramètres de proxy
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> : URL d'un fichier .pac de proxy
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> : URL du serveur proxy
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> : liste d'hôtes pour lesquels le proxy sera contourné
-
-       Le champ <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> est obsolète et a été remplacé par le champ <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Dans <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, si vous sélectionnez :
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, aucun proxy n'est utilisé et tous les autres champs sont ignorés ;
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, le proxy du système est utilisé et tous les autres champs sont ignorés ;
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, tous les autres champs sont ignorés ;
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, les champs <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> et <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> sont utilisés ;
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, les champs <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> et <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> sont utilisés.
-
-      Remarque : Pour voir des exemples détaillés, accédez à The Chromium Projects (https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett).</translation>
 <translation id="6835883744948188639">Afficher une invite récurrente indiquant qu'un redémarrage est recommandé</translation>
 <translation id="683688607121170501">Ce paramètre permet aux utilisateurs de basculer d'un compte Google à l'autre dans la zone de contenu de la fenêtre de leur navigateur et dans les applications Android une fois qu'ils sont connectés sur leur appareil <ph name="PRODUCT_OS_NAME" />.
 
@@ -4779,11 +4777,6 @@
 <translation id="7126928806195745404">Paramètres JavaScript</translation>
 <translation id="7127892035367404455">Rétablir la version cible</translation>
 <translation id="7127980134843952133">Historique des téléchargements</translation>
-<translation id="7129052644387688634">Permet de dresser la liste des formats d'URL pour lesquels les sites ne sont pas autorisés à afficher des notifications.
-
-      Si cette règle n'est pas configurée, la règle <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> s'applique pour tous les sites, à condition qu'elle soit définie. Si ce n'est pas le cas, le paramètre défini par l'utilisateur s'applique.
-
-      Pour en savoir plus sur les formats <ph name="URL_LABEL" /> valides, veuillez consulter la page https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  La valeur <ph name="WILDCARD_VALUE" /> n'est pas acceptée pour cette règle.</translation>
 <translation id="712963038874313213">Fournit un playbook Ansible à exécuter dans le conteneur Crostini par défaut.
 
       Cette règle permet de fournir un playbook Ansible à appliquer au conteneur Crostini par défaut s'il est disponible sur l'appareil concerné et que les règles l'autorisent.
@@ -5212,6 +5205,13 @@
 
           La valeur de la règle doit être indiquée en millisecondes. Elle doit également être inférieure ou égale au délai d'arrêt de l'écran (le cas échéant) et au délai d'inactivité.</translation>
 <translation id="7680437377926096177">Ne plus afficher la boîte de dialogue de déconnexion sur la dernière fenêtre fermée.</translation>
+<translation id="7681958144280390173">Si cette règle est activée, tous les sites sont isolés (chaque site exécute son propre processus). Sachez qu'Android isole certains sites sensibles par défaut depuis <ph name="PRODUCT_NAME" /> 77. Cette règle étend ce mode d'isolation par défaut à tous les sites.
+
+      Si cette règle est désactivée, toute forme d'isolation de sites l'est aussi, y compris l'isolation des sites sensibles et des tests en conditions réelles d'IsolateOriginsAndroid et de SitePerProcessAndroid, et les autres modes d'isolation de sites. Les utilisateurs peuvent toujours activer manuellement la règle.
+
+      Si cette règle n'est pas configurée, les utilisateurs ne peuvent pas modifier ce paramètre.
+
+      Remarque : Il est possible que l'isolation de tous les sites sur Android entraîne actuellement des problèmes de performances, surtout sur les appareils bas de gamme. Des améliorations vont donc y être apportées. Cette règle ne concerne que les appareils Android dans Chrome, qui ont plus de 1 Go de RAM. Pour isoler des sites spécifiques en limitant l'impact sur les performances pour les utilisateurs, servez-vous de <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> avec une liste des sites que vous voulez isoler.  Pour l'appliquer sur des plates-formes autres qu'Android, utilisez <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation>
 <translation id="7683777542468165012">Actualisation dynamique des stratégies</translation>
 <translation id="7687943045976362719">Si cette règle est configurée, les types de contenus spécifiés sont traités par <ph name="PRODUCT_FRAME_NAME" />.
 
@@ -5922,6 +5922,7 @@
       Si elle n'est pas configurée, la page "Nouvel onglet" s'affiche au démarrage.
 
       Sous <ph name="MS_WIN_NAME" />, cette règle n'est disponible que sur les instances associées à un domaine <ph name="MS_AD_NAME" />, exécutées sous Windows 10 Pro ou qui bénéficient de la <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />. Sous <ph name="MAC_OS_NAME" />, elle n'est disponible que sur les instances gérées via MDM ou associées à un domaine via MCX.</translation>
+<translation id="8671119576957984818">Activer le hub de partage du bureau</translation>
 <translation id="8672321184841719703">Cibler une version pour les mises à jour automatiques</translation>
 <translation id="867410340948518937">U2F (Deuxième facteur universel)</translation>
 <translation id="8676959842615154675">Si cette règle est activée, l'hôte d'accès à distance compare le nom de l'utilisateur local auquel il est associé au nom du compte Google enregistré en tant que propriétaire de l'hôte (par exemple, "pierredupont" si l'hôte appartient à pierredupont@example.com). Cet hôte ne démarre pas si le nom de son propriétaire diffère de celui de l'utilisateur local auquel l'hôte est associé. Pour faire en sorte que le compte Google du propriétaire soit associé à un domaine spécifique, utilisez la règle avec "<ph name="REMOTE_ACCESS_HOST_DOMAIN_POLICY_NAME" />".
diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb
index 15ec9a0..36e7603 100644
--- a/components/policy/resources/policy_templates_id.xtb
+++ b/components/policy/resources/policy_templates_id.xtb
@@ -3154,11 +3154,6 @@
 <translation id="5078623750797048009">Mengaktifkan Anotasi PDF</translation>
 <translation id="5082572440690475059">Izinkan akses baca melalui File System API di situs ini</translation>
 <translation id="5085647276663819155">Nonaktifkan Pratinjau Cetak</translation>
-<translation id="5087424855041813182">Menyetel kebijakan memungkinkan Anda menetapkan daftar pola URL yang menentukan situs yang dapat menampilkan notifikasi.
-
-      Tidak menyetel kebijakan berarti <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> akan berlaku untuk semua situs, jika disetel. Jika tidak, setelan pribadi pengguna akan digunakan.
-
-      Untuk informasi selengkapnya tentang pola <ph name="URL_LABEL" /> yang valid, lihat https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> bukanlah nilai yang diterima untuk kebijakan ini.</translation>
 <translation id="5090791951240382356">Mengizinkan penggabungan kebijakan kamus dari sumber berbeda</translation>
 <translation id="5091315650312105069">Mengizinkan autentikasi <ph name="BASIC_AUTH" /> untuk HTTP</translation>
 <translation id="5103112931744164177">Kebijakan ini mengontrol stack software yang digunakan untuk berkomunikasi dengan server DNS: klien DNS Sistem Operasi, atau klien DNS bawaan dari <ph name="PRODUCT_NAME" />. Kebijakan ini tidak memengaruhi server DNS mana yang digunakan: misalnya, jika sistem operasi dikonfigurasi untuk menggunakan server DNS perusahaan, server yang sama tersebut akan digunakan oleh klien DNS bawaan. Kebijakan ini juga tidak akan mengontrol jika DNS-over-HTTPS digunakan; <ph name="PRODUCT_NAME" /> akan selalu menggunakan resolver bawaan untuk permintaan DNS-over-HTTPS. Silakan lihat kebijakan <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> untuk mengetahui informasi mengenai pengontrolan DNS-over-HTTPS.
@@ -4512,26 +4507,6 @@
 
           Catatan: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> akan mengganti kebijakan ini jika kebijakan tersebut ditentukan.</translation>
 <translation id="6833988859168635883">Halaman Awal, Halaman Beranda, dan halaman Tab Baru</translation>
-<translation id="6834298774555537368">Menyetel kebijakan akan mengonfigurasi setelan proxy untuk Chrome dan aplikasi ARC, yang mengabaikan semua opsi terkait proxy yang ditentukan dari command line.
-
-       Jika kebijakan tidak disetel, pengguna dapat memilih setelan proxy mereka.
-
-       Menyetel kebijakan <ph name="PROXY_SETTINGS_POLICY_NAME" /> akan menyetujui kolom berikut:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, yang memungkinkan Anda menentukan server proxy yang digunakan oleh Chrome dan mencegah pengguna mengubah setelan proxy
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />, URL ke file .pac proxy
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />, URL server proxy
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />, daftar host proxy yang diabaikan
-
-       Kolom <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> tidak digunakan lagi dan digantikan dengan kolom <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Untuk <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, jika Anda memilih nilai:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, proxy tidak akan pernah digunakan dan semua kolom lainnya akan diabaikan.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, proxy sistem akan digunakan dan semua kolom lainnya akan diabaikan.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, semua kolom lainnya akan diabaikan.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, kolom <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> dan <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> akan digunakan.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, kolom <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> dan <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> akan digunakan.
-
-      Catatan: Untuk contoh yang lebih mendetail, buka Project Chromium ( https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett ).</translation>
 <translation id="6835883744948188639">Tampilkan permintaan berulang kepada pengguna yang menunjukkan bahwa peluncuran ulang direkomendasikan</translation>
 <translation id="683688607121170501">Setelan ini memungkinkan pengguna beralih ke Akun Google lain di dalam area konten jendela browser dan aplikasi Android setelah mereka login ke perangkat <ph name="PRODUCT_OS_NAME" />.
 
@@ -4833,11 +4808,6 @@
 <translation id="7126928806195745404">Setelan JavaScript</translation>
 <translation id="7127892035367404455">Rollback ke versi target</translation>
 <translation id="7127980134843952133">Histori download</translation>
-<translation id="7129052644387688634">Menyetel kebijakan memungkinkan Anda menetapkan daftar pola URL yang menentukan situs yang tidak dapat menampilkan notifikasi.
-
-      Tidak menyetel kebijakan berarti <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> akan berlaku untuk semua situs, jika disetel. Jika tidak, setelan pribadi pengguna akan digunakan.
-
-      Untuk informasi selengkapnya tentang pola <ph name="URL_LABEL" /> yang valid, lihat https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> bukanlah nilai yang diterima untuk kebijakan ini.</translation>
 <translation id="712963038874313213">Menyediakan playbook Ansible yang harus dijalankan di penampung Crostini default.
 
       Dengan kebijakan ini, playbook Ansible akan dapat diterapkan ke penampung Crostini default jika tersedia pada perangkat tertentu dan diizinkan oleh kebijakan.
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb
index 70c48b2..35cd26d 100644
--- a/components/policy/resources/policy_templates_it.xtb
+++ b/components/policy/resources/policy_templates_it.xtb
@@ -366,7 +366,7 @@
       Se il criterio non viene configurato, <ph name="PRODUCT_NAME" /> prova a rilevare se un server è presente sulla Intranet. Solo allora risponderà alle richieste IWA. Se viene rilevato un server su Internet, <ph name="PRODUCT_NAME" /> ignora le richieste IWA provenienti da tale server.
 
       Nota: se ci sono più server, separane i nomi utilizzando virgole. I caratteri jolly (<ph name="WILDCARD_VALUE" />) sono consentiti.</translation>
-<translation id="1495817006535797003">Se il criterio viene configurato, ciascuna delle origini denominate in un elenco separato da virgole viene eseguita nel proprio processo e le origini denominate da sottodomini vengono isolate. Ad esempio, se si specifica https://example.com/, l'origine https://foo.example.com/ viene isolata in quanto parte del sito https://example.com/.  Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> versione 77 e il criterio si estende a questa modalità per isolare origini aggiuntive specifiche.
+<translation id="1495817006535797003">Se il criterio viene configurato, ciascuna delle origini denominate in un elenco separato da virgole viene eseguita nel proprio processo e le origini denominate da sottodomini vengono isolate. Ad esempio, se si specifica https://example.com/, l'origine https://foo.example.com/ viene isolata in quanto parte del sito https://example.com/.  Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> versione 77 e il criterio estende questa modalità per isolare origini aggiuntive specifiche.
 
       Se il criterio viene impostato su Disattivato, vengono disattivati tutti i tipi di isolamento dei siti, inclusi quelli di siti sensibili, prove sul campo di IsolateOriginsAndroid, SitePerProcessAndroid e altre modalità di isolamento dei siti. Gli utenti possono comunque attivare IsolateOrigins manualmente usando il flag della riga di comando.
 
@@ -2924,7 +2924,7 @@
 <translation id="4820432864264617413">È vietata l'esecuzione di <ph name="BOREALIS_NAME" /> per un utente</translation>
 <translation id="4826326557828204741">Azione da compiere quando il ritardo di inattività viene raggiunto durante l'utilizzo della batteria</translation>
 <translation id="482803100714220060">Mostra URL completi</translation>
-<translation id="4832852360828533362">Rapporti su dispositivi e utenti</translation>
+<translation id="4832852360828533362">Report su dispositivi e utenti</translation>
 <translation id="4834526953114077364">Gli utenti utilizzati meno di recente che non hanno eseguito l'accesso negli ultimi tre mesi vengono rimossi fino alla disponibilità di spazio libero sufficiente</translation>
 <translation id="483544442646753291">Controlla l'esperienza utente delle funzionalità disattivate che sono elencate in <ph name="SYSTEM_FEATURES_DISABLE_LIST" />.
 
@@ -3128,11 +3128,6 @@
 <translation id="5078623750797048009">Attiva annotazioni PDF</translation>
 <translation id="5082572440690475059">Consenti l'accesso di lettura tramite l'API file system su questi siti</translation>
 <translation id="5085647276663819155">Disattiva anteprima di stampa</translation>
-<translation id="5087424855041813182">Se il criterio viene configurato, puoi impostare un elenco di pattern URL che specificano i siti che possono mostrare notifiche.
-
-      Se il criterio non viene configurato, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> si applica per tutti i siti, se impostato. In caso contrario, viene applicata l'impostazione personale dell'utente.
-
-      Per informazioni dettagliate sui pattern <ph name="URL_LABEL" /> validi, visita la pagina https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> non è un valore accettato per questo criterio.</translation>
 <translation id="5090791951240382356">Consenti l'unione dei criteri del dizionario provenienti da origini diverse</translation>
 <translation id="5091315650312105069">Consenti l'autenticazione <ph name="BASIC_AUTH" /> per HTTP</translation>
 <translation id="5103112931744164177">Questo criterio consente di controllare quale stack software viene utilizzato per comunicare con il server DNS: il client DNS del sistema operativo o quello integrato di <ph name="PRODUCT_NAME" />. Questo criterio non influisce sui server DNS utilizzati: se, ad esempio, il sistema operativo viene configurato in modo da usare un server DNS aziendale, lo stesso server viene usato dal client DNS integrato. Non consente nemmeno di controllare se viene utilizzato il protocollo DNS-over-HTTPS; <ph name="PRODUCT_NAME" /> userà sempre il resolver integrato per le richieste DNS-over-HTTPS. Per informazioni relative al controllo del protocollo DNS-over-HTTPS, consulta il criterio <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />.
@@ -4460,26 +4455,6 @@
 
           Nota: se specificato, <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> sostituisce questo criterio.</translation>
 <translation id="6833988859168635883">Avvio, pagina iniziale e pagina Nuova scheda</translation>
-<translation id="6834298774555537368">L'impostazione del criterio consente di configurare le impostazioni del proxy per Chrome e le app ARC, ignorando tutte le opzioni relative al proxy specificate dalla riga di comando.
-
-       Se il criterio non viene configurato, gli utenti possono scegliere le impostazioni del proxy.
-
-       L'impostazione del criterio <ph name="PROXY_SETTINGS_POLICY_NAME" /> consente di accettare i seguenti campi:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, che consente di specificare il server proxy utilizzato da Chrome e impedisce agli utenti di modificare le impostazioni del proxy
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />, un URL a un file proxy .pac
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />, un URL a un server proxy
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />, un elenco di host per i quali il proxy verrà bypassato
-
-       Il campo <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> è deprecato a favore del campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Per il campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, se scegli il valore:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, non viene mai utilizzato un proxy e tutti gli altri campi vengono ignorati.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, viene utilizzato il proxy del sistema e tutti gli altri campi vengono ignorati.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, tutti gli altri campi vengono ignorati.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, vengono utilizzati i campi <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> e <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, vengono utilizzati i campi <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> e <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-
-      Nota: per esempi più dettagliati, consulta la pagina The Chromium Projects (https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett).</translation>
 <translation id="6835883744948188639">Mostra all'utente un messaggio ricorrente che indica che è consigliato eseguire un riavvio</translation>
 <translation id="683688607121170501">Questa impostazione consente agli utenti di passare da un Account Google a un altro all'interno dell'area dei contenuti della finestra del browser e nelle applicazioni Android, dopo avere eseguito l'accesso al dispositivo <ph name="PRODUCT_OS_NAME" />.
 
@@ -4781,11 +4756,6 @@
 <translation id="7126928806195745404">Impostazioni JavaScript</translation>
 <translation id="7127892035367404455">Rollback alla versione target</translation>
 <translation id="7127980134843952133">Cronologia download</translation>
-<translation id="7129052644387688634">Se il criterio viene configurato, puoi impostare un elenco di pattern URL che specificano i siti che non possono mostrare notifiche.
-
-      Se il criterio non viene configurato, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> si applica per tutti i siti, se impostato. In caso contrario, viene applicata l'impostazione personale dell'utente.
-
-      Per informazioni dettagliate sui pattern <ph name="URL_LABEL" /> validi, visita la pagina https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> non è un valore accettato per questo criterio.</translation>
 <translation id="712963038874313213">Fornisce un playbook Ansible che deve essere eseguito nel contenitore Crostini predefinito.
 
       Questo criterio consente di specificare un playbook Ansible da applicare al contenitore Crostini predefinito, se disponibile sul dispositivo e se consentito dai criteri.
@@ -5214,7 +5184,7 @@
 
           Il valore del criterio deve essere specificato in millisecondi. I valori devono essere inferiori o uguali al ritardo di disattivazione dello schermo (se impostato) e al ritardo di inattività.</translation>
 <translation id="7680437377926096177">Impedisci la visualizzazione della finestra di dialogo di disconnessione nell'ultima finestra chiusa.</translation>
-<translation id="7681958144280390173">Se il criterio viene impostato su Attivato, tutti i siti vengono isolati (ogni sito viene eseguito nel proprio processo). Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> versione 77 e il criterio si estende a questa modalità di isolamento dei siti predefinita affinché venga applicata a tutti i siti.
+<translation id="7681958144280390173">Se il criterio viene impostato su Attivato, tutti i siti vengono isolati (ogni sito viene eseguito nel proprio processo). Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> versione 77 e il criterio estende questa modalità di isolamento dei siti predefinita affinché venga applicata a tutti i siti.
 
       Se il criterio viene impostato su Disattivato, vengono disattivati tutti i tipi di isolamento dei siti, inclusi quelli di siti sensibili, prove sul campo di IsolateOriginsAndroid, SitePerProcessAndroid e altre modalità di isolamento dei siti. Gli utenti possono comunque attivare il criterio manualmente.
 
diff --git a/components/policy/resources/policy_templates_ja.xtb b/components/policy/resources/policy_templates_ja.xtb
index 65ca64d..7eba7e3 100644
--- a/components/policy/resources/policy_templates_ja.xtb
+++ b/components/policy/resources/policy_templates_ja.xtb
@@ -3054,11 +3054,6 @@
 <translation id="5078623750797048009">PDF の注釈を有効にする</translation>
 <translation id="5082572440690475059">File System API 経由での読み取りアクセスを許可するサイトを指定する</translation>
 <translation id="5085647276663819155">印刷プレビューを無効にする</translation>
-<translation id="5087424855041813182">このポリシーでは、通知の表示を許可するサイトの URL パターンリストを指定できます。
-
-      このポリシーを未設定のままにした場合、<ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> が設定されていればその設定がすべてのサイトで使用され、設定されていなければユーザーの個人設定が適用されます。
-
-      有効な <ph name="URL_LABEL" /> パターンについて詳しくは、https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns をご覧ください。このポリシーの値に「<ph name="WILDCARD_VALUE" />」は使用できません。</translation>
 <translation id="5090791951240382356">ソースの異なる辞書ポリシーの統合を許可する</translation>
 <translation id="5091315650312105069">HTTP で <ph name="BASIC_AUTH" /> 認証を許可する</translation>
 <translation id="5103112931744164177">このポリシーでは、DNS サーバーとの通信にオペレーティング システムの DNS クライアントと <ph name="PRODUCT_NAME" /> の組み込みの DNS クライアントのどちらのソフトウェア スタックを使用するかを管理できます。このポリシーは、使用する DNS サーバーの選択には影響しません。たとえば、オペレーティング システムで企業の DNS サーバーを使用するよう設定されている場合、組み込みの DNS クライアントでも同じサーバーが使用されます。また、DNS-over-HTTPS が使用されている場合は、このポリシーの対象となりません。<ph name="PRODUCT_NAME" /> では DNS-over-HTTPS リクエストに対して、常に組み込みのリゾルバを使用します。DNS-over-HTTPS の管理については、<ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> ポリシーをご覧ください。
@@ -4336,26 +4331,6 @@
 
           注: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> が指定されている場合はこのポリシーより優先されます。</translation>
 <translation id="6833988859168635883">起動ページ、ホームページ、新しいタブページ</translation>
-<translation id="6834298774555537368">このポリシーでは、Chrome と ARC アプリのプロキシ設定を行います。いずれもコマンドラインで指定されたプロキシ関連の設定はすべて無視されます。
-
-       このポリシーを未設定のままにした場合、ユーザーはプロキシ設定を選択できます。
-
-       <ph name="PROXY_SETTINGS_POLICY_NAME" /> ポリシーを設定すると、次のフィールドを受け取れるようになります。
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />: Chrome で使用するプロキシ サーバーを指定して、ユーザーがプロキシ設定を変更できないようにします
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />: プロキシ .pac ファイルへの URL
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />: プロキシ サーバーの URL
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />: プロキシを使用しないホストのリスト
-
-       <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> フィールドは非推奨となりました。代わりに <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> フィールドを使用してください。
-
-        <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> については、以下のいずれかの値を指定します。
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />: プロキシは一切使用せず、他のフィールドをすべて無視します。
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />: システムのプロキシを使用して、他のフィールドをすべて無視します。
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />: 他のフィールドをすべて無視します。
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />: <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> フィールドと <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> フィールドを使用します。
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />: <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> フィールドと <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> フィールドを使用します。
-
-      注: 詳しい例については、Chromium プロジェクトの説明(https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett)をご覧ください。</translation>
 <translation id="6835883744948188639">再起動が推奨されることを示すメッセージをユーザーに繰り返し表示する</translation>
 <translation id="683688607121170501">ユーザーが <ph name="PRODUCT_OS_NAME" /> デバイスにログインした後に、ブラウザ ウィンドウのコンテンツ領域内や Android アプリケーションで Google アカウントを切り替えることができるかどうかを制御します。
 
@@ -4646,11 +4621,6 @@
 <translation id="7126928806195745404">JavaScript 設定</translation>
 <translation id="7127892035367404455">対象バージョンへのロールバック</translation>
 <translation id="7127980134843952133">ダウンロード履歴</translation>
-<translation id="7129052644387688634">このポリシーでは、通知の表示を許可しないサイトの URL パターンリストを指定できます。
-
-      このポリシーを未設定のままにした場合、<ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> が設定されていればその設定がすべてのサイトで使用され、設定されていなければユーザーの個人設定が適用されます。
-
-      有効な <ph name="URL_LABEL" /> パターンについて詳しくは、https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns をご覧ください。このポリシーの値に「<ph name="WILDCARD_VALUE" />」は使用できません。</translation>
 <translation id="712963038874313213">デフォルトの Crostini コンテナで実行する Ansible playbook を指定します。
 
       Crostini が対象デバイスで利用可能で、ポリシーで許可されている場合は、このポリシーを使用して、デフォルトの Crostini コンテナに適用する Ansible playbook を指定できます。
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb
index 29abdcff..d1db3daec 100644
--- a/components/policy/resources/policy_templates_ko.xtb
+++ b/components/policy/resources/policy_templates_ko.xtb
@@ -3150,11 +3150,6 @@
 <translation id="5078623750797048009">PDF 주석 사용 설정</translation>
 <translation id="5082572440690475059">다음 사이트에서 File System API를 통한 읽기 액세스 허용</translation>
 <translation id="5085647276663819155">인쇄 미리보기 사용 안함</translation>
-<translation id="5087424855041813182">정책을 설정하면 알림 표시가 가능한 사이트를 지정하는 URL 패턴 목록을 설정할 수 있습니다.
-
-      정책을 설정하지 않았을 때 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" />이 설정되어 있으면 모든 사이트에 적용되며 설정되어 있지 않다면 사용자의 개인 설정이 적용됩니다.
-
-      유효한 <ph name="URL_LABEL" /> 패턴에 관해 자세히 알아보려면 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns를 참고하세요. <ph name="WILDCARD_VALUE" />는 이 정책에 허용되는 값이 아닙니다.</translation>
 <translation id="5090791951240382356">출처가 서로 다른 사전 정책의 병합 허용</translation>
 <translation id="5091315650312105069">HTTP 연결에 <ph name="BASIC_AUTH" /> 인증 허용</translation>
 <translation id="5103112931744164177">이 정책은 운영 체제 DNS 서버나 <ph name="PRODUCT_NAME" />의 내장 DNS 클라이언트와 같이 DNS 서버와의 통신에 사용되는 소프트웨어 스택을 제어합니다. 이 정책은 사용되는 DNS 서버에 영향을 미치지 않습니다. 예를 들어 엔터프라이즈 DNS 서버를 사용하도록 운영 체제가 구성된 경우 내장 DNS 클라이언트에도 동일한 서버가 사용됩니다. DNS-over-HTTPS가 사용되는 경우에도 영향을 미치지 않습니다. <ph name="PRODUCT_NAME" />에서는 항상 DNS-over-HTTPS 요청에 관한 내장 리졸버를 사용합니다. DNS-over-HTTPS 제어에 관한 자세한 내용은 <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> 정책을 참고하세요.
@@ -4507,26 +4502,6 @@
 
           참고: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />이(가) 지정된 경우 이 정책을 재정의합니다.</translation>
 <translation id="6833988859168635883">시작, 홈페이지, 새 탭 페이지</translation>
-<translation id="6834298774555537368">정책을 설정하면 Chrome 및 ARC 앱에 프록시 설정이 구성되어 명령줄로 지정된 모든 프록시 관련 옵션이 무시됩니다.
-
-       설정하지 않으면 사용자가 프록시 설정을 선택할 수 있습니다.
-
-       <ph name="PROXY_SETTINGS_POLICY_NAME" /> 정책을 설정하면 다음 필드를 가질 수 있습니다.
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />: Chrome의 프록시 서버를 지정할 수 있고 사용자가 프록시 설정을 변경하지 못함
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />: 프록시 .pac 파일 URL
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />: 프록시 서버 URL
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />: 프록시를 우회할 호스트 목록
-
-       <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> 필드가 지원 중단되고 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> 필드로 대체되었습니다.
-
-        선택할 수 있는 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />의 값과 그에 따른 결과입니다.
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />: 프록시가 사용되지 않고 다른 모든 필드가 무시됩니다.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />: 시스템 프록시가 사용되고 다른 모든 필드가 무시됩니다.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />: 다른 모든 필드가 무시됩니다.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />: <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> 및 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 필드가 사용됩니다.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />: <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> 및 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 필드가 사용됩니다.
-
-      참고: 자세한 예시를 보려면 Chromium 프로젝트(https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett)를 참고하세요.</translation>
 <translation id="6835883744948188639">사용자에게 재실행하는 것이 좋다는 메시지를 반복하여 표시</translation>
 <translation id="683688607121170501">이 설정은 사용자가 <ph name="PRODUCT_OS_NAME" /> 기기에 로그인한 후 브라우저 창의 콘텐츠 영역 및 Android 애플리케이션에서 Google 계정 간에 전환하도록 허용합니다.
 
@@ -4828,11 +4803,6 @@
 <translation id="7126928806195745404">자바스크립트 설정</translation>
 <translation id="7127892035367404455">대상 버전으로 롤백</translation>
 <translation id="7127980134843952133">다운로드 기록</translation>
-<translation id="7129052644387688634">정책을 설정하면 알림 표시가 불가능한 사이트를 지정하는 URL 패턴 목록을 설정할 수 있습니다.
-
-      정책을 설정하지 않았을 때 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" />이 설정되어 있으면 모든 사이트에 적용되며 설정되어 있지 않다면 사용자의 개인 설정이 적용됩니다.
-
-      유효한 <ph name="URL_LABEL" /> 패턴에 관해 자세히 알아보려면 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns를 참고하세요.  <ph name="WILDCARD_VALUE" />는 이 정책에 허용되는 값이 아닙니다.</translation>
 <translation id="712963038874313213">기본 Crostini 컨테이너로 실행되어야 할 Ansible 플레이북을 제공합니다.
 
       이 정책은 특정 기기에서 사용 가능하며 정책에서 허용되는 경우 기본 Crostini 컨테이너에 적용될 Ansible 플레이북을 제공하도록 허용합니다.
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb
index df7fbc2..b9e54f0 100644
--- a/components/policy/resources/policy_templates_nl.xtb
+++ b/components/policy/resources/policy_templates_nl.xtb
@@ -3109,11 +3109,6 @@
 <translation id="5078623750797048009">Pdf-annotaties aanzetten</translation>
 <translation id="5082572440690475059">Alleen leestoegang via de File System API toestaan op deze sites</translation>
 <translation id="5085647276663819155">Afdrukvoorbeeld uitzetten</translation>
-<translation id="5087424855041813182">Als je het beleid instelt, kun je een lijst met URL-patronen instellen van de sites die meldingen mogen weergeven.
-
-      Als je het beleid niet instelt, is <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (indien ingesteld) van toepassing op alle sites. Zo niet, dan gelden de persoonlijke instellingen van de gebruiker.
-
-      Ga naar https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns voor gedetailleerde informatie over geldige <ph name="URL_LABEL" />-patronen. <ph name="WILDCARD_VALUE" /> is geen geaccepteerde waarde voor dit beleid.</translation>
 <translation id="5090791951240382356">Toestaan dat woordenboekbeleid van verschillende bronnen wordt samengevoegd</translation>
 <translation id="5091315650312105069"><ph name="BASIC_AUTH" />-verificatie toestaan voor HTTP</translation>
 <translation id="5103112931744164177">Dit beleid beheert welke softwarestack wordt gebruikt voor communicatie met de DNS-server: de DNS-client van het besturingssysteem of de ingebouwde DNS-client van <ph name="PRODUCT_NAME" />. Dit beleid heeft geen invloed op welke DNS-servers worden gebruikt: als het besturingssysteem bijvoorbeeld is geconfigureerd voor gebruik van een zakelijke DNS-server, wordt diezelfde server gebruikt door de ingebouwde DNS-client. Ook wordt met dit beleid niet beheerd of DNS-over-HTTPS wordt gebruikt: <ph name="PRODUCT_NAME" /> gebruikt altijd de ingebouwde resolver voor DNS-over-HTTPS-verzoeken. Zie het <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />-beleid voor informatie over het beheer van DNS-over-HTTPS.
@@ -4434,26 +4429,6 @@
 
           Opmerking: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> overschrijft dit beleid als het is opgegeven.</translation>
 <translation id="6833988859168635883">Startpagina, homepage en pagina 'Nieuw tabblad'</translation>
-<translation id="6834298774555537368">Als je het beleid instelt, bepaal je de proxyinstellingen voor Chrome en ARC-apps, die alle proxygerelateerde opties negeren die via de opdrachtregel worden opgegeven.
-
-       Als je het beleid niet instelt, kunnen gebruikers hun proxyinstellingen kiezen.
-
-       Als je het beleid <ph name="PROXY_SETTINGS_POLICY_NAME" /> instelt, worden de volgende velden geaccepteerd:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />: Hiermee kun je de proxyserver opgeven die Chrome gebruikt en voorkomen dat gebruikers de proxyinstellingen wijzigen.
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />: Een URL naar een pac-bestand van de proxy.
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />: Een URL van de proxyserver.
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />: Een lijst met proxyhosts die de proxy omzeilen.
-
-Het veld <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> is beëindigd ten gunste van het veld <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Als je voor <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> de volgende waarde kiest:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />: Er wordt nooit een proxy gebruikt en alle andere velden worden genegeerd.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />: De proxy van het systeem wordt gebruikt en alle andere velden worden genegeerd.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />: Alle andere velden worden genegeerd.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />: De velden <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> en <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> worden gebruikt.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />: De velden <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> en <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> worden gebruikt.
-
-      Opmerking: Voor gedetailleerdere voorbeelden ga je naar The Chromium Projects ( https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett ).</translation>
 <translation id="6835883744948188639">Toon de gebruiker een terugkerende prompt om aan te geven dat opnieuw opstarten wordt aanbevolen</translation>
 <translation id="683688607121170501">Deze instelling biedt gebruikers de mogelijkheid om in het contentgedeelte van hun browservenster tussen Google-accounts te schakelen nadat ze zijn ingelogd bij hun <ph name="PRODUCT_OS_NAME" />-apparaat.
 
@@ -4753,11 +4728,6 @@
 <translation id="7126928806195745404">Instellingen voor JavaScript</translation>
 <translation id="7127892035367404455">Doelversie herstellen</translation>
 <translation id="7127980134843952133">Downloadgeschiedenis</translation>
-<translation id="7129052644387688634">Als je het beleid instelt, kun je een lijst met URL-patronen instellen van de sites die geen meldingen mogen weergeven.
-
-      Als je het beleid niet instelt, is <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (indien ingesteld) van toepassing op alle sites. Zo niet, dan gelden de persoonlijke instellingen van de gebruiker.
-
-      Ga naar https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns voor gedetailleerde informatie over geldige <ph name="URL_LABEL" />-patronen.  <ph name="WILDCARD_VALUE" /> is geen geaccepteerde waarde voor dit beleid.</translation>
 <translation id="712963038874313213">Hiermee wordt een Ansible-playbook geboden dat moet worden uitgevoerd in de standaard Crostini-container.
 
       Dit beleid staat het bieden van een Ansible-playbook toe die mag worden toegepast op de standaard Crostini-container, als deze beschikbaar is op het opgegeven apparaat en is toegestaan door het beleid.
diff --git a/components/policy/resources/policy_templates_pt-BR.xtb b/components/policy/resources/policy_templates_pt-BR.xtb
index 5f9166f..1627266 100644
--- a/components/policy/resources/policy_templates_pt-BR.xtb
+++ b/components/policy/resources/policy_templates_pt-BR.xtb
@@ -3136,11 +3136,6 @@
 <translation id="5078623750797048009">Ativar anotações no PDF</translation>
 <translation id="5082572440690475059">Permitir acesso de leitura com a API File System nestes sites</translation>
 <translation id="5085647276663819155">Desativar visualização da impressão</translation>
-<translation id="5087424855041813182">Se a política for definida, será possível configurar uma lista de padrões de URL que especifica os sites que podem exibir notificações.
-
-      Se a política não tiver definição, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> será aplicada a todos os sites, se estiver definida. Caso contrário, a configuração pessoal do usuário será aplicada.
-
-      Para informações detalhadas sobre padrões de <ph name="URL_LABEL" /> válidos, consulte https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns (link em inglês). <ph name="WILDCARD_VALUE" /> não é um valor aceitável para esta política.</translation>
 <translation id="5090791951240382356">Permitir a mescla de políticas de dicionário de diferentes fontes</translation>
 <translation id="5091315650312105069">Permitir autenticação <ph name="BASIC_AUTH" /> para conexões HTTP</translation>
 <translation id="5103112931744164177">Esta política controla qual pilha de software é usada para se comunicar com o servidor DNS: o cliente DNS do sistema operacional ou o cliente DNS integrado do <ph name="PRODUCT_NAME" />. Esta política não afeta qual servidor DNS será usado. Se, por exemplo, o sistema operacional estiver configurado para usar um servidor DNS empresarial, o mesmo servidor será usado pelo cliente DNS integrado. Ela também não controla como o DNS sobre HTTPS é usado. O <ph name="PRODUCT_NAME" /> sempre usará o resolvedor integrado para solicitações DNS sobre HTTPS. Consulte a política <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> para ver informações sobre como controlar o DNS sobre HTTPS.
@@ -4484,26 +4479,6 @@
 
           Observação: se <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> for especificada, ela substituirá esta política.</translation>
 <translation id="6833988859168635883">Inicialização, página inicial e página "Nova guia"</translation>
-<translation id="6834298774555537368">Se a política for definida, haverá configurações de proxy para o Chrome e apps ARC, ignorando todas as opções relacionadas a proxy especificadas na linha de comando.
-
-       Se a política não for definida, os usuários poderão escolher as configurações de proxy.
-
-       Se a política <ph name="PROXY_SETTINGS_POLICY_NAME" /> for definida, os campos a seguir serão aceitos:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, permite especificar o servidor proxy usado pelo Chrome e evitar que os usuários mudem as configurações de proxy.
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />, um URL de um arquivo de proxy .pac.
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />, um URL do servidor de proxy.
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />, uma lista de hosts pelos quais o proxy será ignorado.
-
-       O uso do campo <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> foi suspenso em favor do campo <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Para <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, se você escolher o valor:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, um proxy nunca será usado e todos os outros campos serão ignorados;
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, o proxy do sistema será usado e todos os outros campos serão ignorados;
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, todos os outros campos serão ignorados;
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, os campos <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> e <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> serão usados;
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, os campos <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> e <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> serão usados.
-
-      Observação: para ver mais exemplos detalhados, acesse The Chromium Projects em https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett (link em inglês).</translation>
 <translation id="6835883744948188639">Mostrar um prompt recorrente ao usuário indicando que a reinicialização é necessária</translation>
 <translation id="683688607121170501">Esta configuração permite que os usuários alternem entre Contas do Google na área de conteúdo da janela do navegador e nos aplicativos Android, depois de fazer login no dispositivo <ph name="PRODUCT_OS_NAME" />.
 
@@ -4803,11 +4778,6 @@
 <translation id="7126928806195745404">Configurações de JavaScript</translation>
 <translation id="7127892035367404455">Reverter para a versão de destino</translation>
 <translation id="7127980134843952133">Histórico de downloads</translation>
-<translation id="7129052644387688634">Se a política for definida, será possível configurar uma lista de padrões de URL que especifica os sites que não podem exibir notificações.
-
-      Se a política não tiver definição, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> será aplicada a todos os sites, se estiver definida. Caso contrário, a configuração pessoal do usuário será aplicada.
-
-      Para informações detalhadas sobre padrões de <ph name="URL_LABEL" /> válidos, consulte https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns (link em inglês).  <ph name="WILDCARD_VALUE" /> não é um valor aceitável para esta política.</translation>
 <translation id="712963038874313213">Fornece um playbook Ansible que precisa ser executado no contêiner Crostini padrão.
 
       Esta política permite fornecer um playbook Ansible a ser aplicado ao contêiner Crostini padrão se estiver disponível no dispositivo fornecido e for permitido pelas políticas.
diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb
index fb879755..53973c8 100644
--- a/components/policy/resources/policy_templates_ru.xtb
+++ b/components/policy/resources/policy_templates_ru.xtb
@@ -363,7 +363,7 @@
       Если правило не настроено, <ph name="PRODUCT_NAME" /> отвечает на запросы IWA только после того, как определяет, находится ли сервер в интранете. Если сервер находится в Интернете, <ph name="PRODUCT_NAME" /> игнорирует поступающие от него запросы IWA.
 
       Примечание. Названия серверов нужно разделять запятыми. Допустимы подстановочные знаки (<ph name="WILDCARD_VALUE" />).</translation>
-<translation id="1495817006535797003">Если правило включено, то для каждого сайта из списка, разделенного запятыми, запускается отдельный процесс, а сайты изолируются по субдоменам. Например, если указать сайт https://example.com/, его субдомен https://foo.example.com/ также будет изолирован.  Обратите внимание, что, начиная с <ph name="PRODUCT_NAME" /> версии 77, на Android по умолчанию используется режим изоляции в отношении определенных конфиденциальных сайтов. В этом правиле описывается применение режима изоляции к отдельным дополнительным источникам.
+<translation id="1495817006535797003">Если правило включено, то для каждого сайта из списка, разделенного запятыми, запускается отдельный процесс, а сайты изолируются по субдоменам. Например, если указать сайт https://example.com/, его субдомен https://foo.example.com/ также будет изолирован.  Обратите внимание, что, начиная с <ph name="PRODUCT_NAME" /> версии 77, на Android по умолчанию используется режим изоляции в отношении определенных конфиденциальных сайтов. С этим правилом режим изоляции применяется к отдельным дополнительным источникам.
 
       Если правило отключено, то не работают все формы изоляции, в том числе изоляция конфиденциальных сайтов, экспериментальные функции IsolateOriginsAndroid и SitePerProcessAndroid, а также другие режимы изоляции сайтов. Пользователи смогут включать правило IsolateOrigins вручную с помощью параметра командной строки.
 
@@ -3118,11 +3118,6 @@
 <translation id="5078623750797048009">Разрешить добавление заметок в PDF-файлах</translation>
 <translation id="5082572440690475059">Разрешить на этих сайтах доступ для чтения через File System API</translation>
 <translation id="5085647276663819155">Отключить предварительный просмотр</translation>
-<translation id="5087424855041813182">Позволяет задать список шаблонов URL для указания сайтов, которым разрешено показывать уведомления.
-
-      Если правило не настроено, для всех сайтов действует правило <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> при условии, что оно задано. В противном случае применяются персональные настройки пользователя.
-
-      Подробнее о допустимых шаблонах <ph name="URL_LABEL" />: https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. Значение <ph name="WILDCARD_VALUE" /> не поддерживается для этого правила.</translation>
 <translation id="5090791951240382356">Разрешить объединять правила со словарями из разных источников</translation>
 <translation id="5091315650312105069">Разрешить аутентификацию типа "<ph name="BASIC_AUTH" />" при подключении по HTTP</translation>
 <translation id="5103112931744164177">Правило позволяет выбрать, какой программный стек использовать для взаимодействия с DNS-сервером: клиент DNS операционной системы или встроенный в <ph name="PRODUCT_NAME" /> клиент DNS. Это не влияет на выбор DNS-серверов. Например, если операционная система использует корпоративный DNS-сервер, то встроенный клиент DNS будет использовать этот же сервер. Это правило также не влияет на выбор протокола "DNS поверх HTTPS". <ph name="PRODUCT_NAME" /> всегда отправляет запросы по этому протоколу через встроенный преобразователь. Подробные сведения об управлении "DNS поверх HTTPS" можно найти в правиле <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />.
@@ -4468,26 +4463,6 @@
 
           Примечание. Если настроено правило <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />, его значение будет иметь приоритет над этим правилом.</translation>
 <translation id="6833988859168635883">Главная страница и страница быстрого доступа при запуске</translation>
-<translation id="6834298774555537368">Правило позволяет задать настройки прокси-сервера для Chrome и ARC-приложений, игнорируя все настройки прокси, указанные с помощью командной строки.
-
-       Если правило не задано, пользователи могут самостоятельно настраивать прокси-сервер.
-
-       Правило <ph name="PROXY_SETTINGS_POLICY_NAME" /> позволяет указать значения следующих полей:
-         * поле <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> задает прокси-сервер для Chrome и запрещает пользователям изменять эти настройки;
-         * поле <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> задает URL PAC-файла прокси-сервера;
-         * поле <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> задает URL прокси-сервера;
-         * поле <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> задает список хостов, для которых прокси-сервер будет игнорироваться.
-
-       Поле <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> заменено полем <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Выбор значения поля <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" /> – прокси-сервер никогда не будет использоваться, а значения остальных полей будут игнорироваться.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" /> – будут использоваться системные настройки прокси-сервера, значения остальных полей будут игнорироваться.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" /> – значения остальных полей будут игнорироваться.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" /> – будут использоваться поля <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> и <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" /> – будут использоваться поля <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> и <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-
-      Примечание. Подробную информацию можно найти здесь: https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett.</translation>
 <translation id="6835883744948188639">Уведомлять пользователя о том, что рекомендуется перезапустить браузер</translation>
 <translation id="683688607121170501">Позволяет переключаться между несколькими аккаунтами Google в Android-приложениях и в окне браузера после входа в аккаунт на устройстве с <ph name="PRODUCT_OS_NAME" />.
 
@@ -4787,11 +4762,6 @@
 <translation id="7126928806195745404">Настройки JavaScript</translation>
 <translation id="7127892035367404455">Откат к целевой версии</translation>
 <translation id="7127980134843952133">История скачиваний</translation>
-<translation id="7129052644387688634">Позволяет задать список шаблонов URL для указания сайтов, которым запрещено показывать уведомления.
-
-      Если правило не настроено, для всех сайтов действует правило <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> при условии, что оно задано. В противном случае применяются персональные настройки пользователя.
-
-      Подробнее о допустимых шаблонах <ph name="URL_LABEL" />: https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  Значение <ph name="WILDCARD_VALUE" /> не поддерживается для этого правила.</translation>
 <translation id="712963038874313213">Позволяет создать сценарий Ansible, который должен быть выполнен в контейнере Crostini, использующемся по умолчанию.
 
       Это правило позволяет создать сценарий Ansible, который можно применить к контейнеру Crostini по умолчанию, если он доступен на выбранном устройстве и его использование разрешено правилами.
@@ -5219,13 +5189,13 @@
 
           Значение указывается в миллисекундах и не должно превышать время задержки до отключения экрана (если оно задано) и до перехода в режим бездействия.</translation>
 <translation id="7680437377926096177">Не показывать диалоговое окно подтверждения выхода, когда закрыто последнее окно</translation>
-<translation id="7681958144280390173">Если это правило включено, изолируются все сайты (для каждого из них запускается отдельный процесс). Обратите внимание, что, начиная с <ph name="PRODUCT_NAME" /> версии 77, на Android по умолчанию используется режим изоляции в отношении определенных конфиденциальных сайтов. В этом правиле описывается применение изоляции ко всем сайтам.
+<translation id="7681958144280390173">Если это правило включено, изолируются все сайты (для каждого из них запускается отдельный процесс). Обратите внимание, что, начиная с <ph name="PRODUCT_NAME" /> версии 77, на Android по умолчанию используется режим изоляции в отношении определенных конфиденциальных сайтов. С этим правилом режим изоляции по умолчанию применяется ко всем сайтам.
 
       Если правило отключено, то не работают все формы изоляции, в том числе изоляция конфиденциальных сайтов, экспериментальные функции IsolateOriginsAndroid и SitePerProcessAndroid, а также другие режимы изоляции сайтов. Пользователи по-прежнему могут включить это правило вручную.
 
       Если правило не задано, пользователи могут изменять эту настройку.
 
-      Примечание. Поддержка изоляции сайтов на устройствах Android улучшится, но в настоящее время это может вызвать проблемы с производительностью, особенно на устройствах низкого класса. Это правило действует только в Chrome на устройствах Android, имеющих больше 1 ГБ оперативной памяти. Чтобы изолировать определенные сайты и ограничить влияние на производительность, используйте правило <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> и список сайтов, которые нужно изолировать.  На других платформах используйте правило <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation>
+      Примечание. Поддержка изоляции всех сайтов на устройствах Android улучшится, но в настоящее время это может вызвать проблемы с производительностью, особенно на устройствах низкого класса. Это правило действует только в Chrome на устройствах Android, имеющих больше 1 ГБ оперативной памяти. Чтобы изолировать определенные сайты и при этом избежать значительного снижения производительности, используйте правило <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> и список сайтов, которые нужно изолировать.  На других платформах используйте правило <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation>
 <translation id="7683777542468165012">Динамическое обновление правил</translation>
 <translation id="7687943045976362719">Если правило настроено, указанные типы контента обрабатываются <ph name="PRODUCT_FRAME_NAME" />.
 
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb
index 449fc470..f7cf398 100644
--- a/components/policy/resources/policy_templates_th.xtb
+++ b/components/policy/resources/policy_templates_th.xtb
@@ -366,6 +366,13 @@
       การไม่ตั้งค่านโยบายหมายความว่า <ph name="PRODUCT_NAME" /> จะพยายามตรวจหาว่าเซิร์ฟเวอร์อยู่บนอินทราเน็ตไหม หากใช่ก็จะตอบรับคำขอ IWA หากมีการตรวจพบว่าเซิร์ฟเวอร์เป็นอินเทอร์เน็ต <ph name="PRODUCT_NAME" /> จะไม่สนใจคำขอ IWA จากเซิร์ฟเวอร์
 
       หมายเหตุ: คั่นชื่อเซิร์ฟเวอร์หลายรายการด้วยเครื่องหมายจุลภาค ใช้ไวลด์การ์ด (<ph name="WILDCARD_VALUE" />) ได้</translation>
+<translation id="1495817006535797003">การตั้งค่านโยบายหมายความว่าต้นทางแต่ละแห่งที่มีชื่อในรายการที่คั่นด้วยจุลภาคจะทำงานในกระบวนการของตัวเอง และจะแยกต้นทางที่ตั้งชื่อตามโดเมนย่อย เช่น การระบุ https://example.com/ จะเป็นการแยก https://foo.example.com/ เนื่องจากเป็นส่วนหนึ่งของเว็บไซต์ https://example.com/  โปรดทราบว่า Android จะแยกเว็บไซต์ที่มีความละเอียดอ่อนบางเว็บไซต์โดยค่าเริ่มต้นใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 เป็นต้นไป และนโยบายนี้จะขยายการทำงานของโหมดดังกล่าวให้แยกต้นทางบางรายการเพิ่มเติม
+
+      การตั้งค่านโยบายเป็น "ปิดใช้" จะปิดการแยกเว็บไซต์ทุกรูปแบบ เช่น การแยกเว็บไซต์ที่มีความละเอียดอ่อน รวมถึงการทดลองใช้งานจริงของ IsolateOriginsAndroid และ SitePerProcessAndroid ตลอดจนโหมดการแยกเว็บไซต์อื่นๆ ผู้ใช้ยังคงเปิด IsolateOrigins ด้วยตนเองได้ผ่านการติดธงบรรทัดคำสั่ง
+
+      การไม่ตั้งค่านโยบายจะทำให้ผู้ใช้เปลี่ยนการตั้งค่าได้
+
+      หมายเหตุ: การแยกเว็บไซต์จำนวนมากเกินไปใน Android อาจก่อให้เกิดปัญหาด้านประสิทธิภาพ โดยเฉพาะกับอุปกรณ์ระดับโลว์เอนด์ นโยบายนี้มีผลเฉพาะกับ Chrome ใน Android ที่ทำงานในอุปกรณ์ที่มี RAM มากกว่า 1 GB เท่านั้น หากต้องการใช้นโยบายกับแพลตฟอร์มที่ไม่ใช่ Android ให้ใช้ <ph name="ISOLATE_ORIGINS_POLICY_NAME" /></translation>
 <translation id="1502843533062797703">เปิดใช้การบล็อกการแทรกซอฟต์แวร์ของบุคคลที่สาม</translation>
 <translation id="1503969899251962413">การตั้งค่านโยบายจะระบุรหัสสัญญาอนุญาต <ph name="PLUGIN_VM_NAME" /> สำหรับอุปกรณ์นี้
 
@@ -700,6 +707,7 @@
 <translation id="1930127294345368978">จำนวนแผ่นงานสูงสุดที่อนุญาตให้ใช้สำหรับงานพิมพ์ 1 งาน</translation>
 <translation id="193259052151668190">รายการที่อนุญาตพิเศษของอุปกรณ์ USB ที่ถอดได้</translation>
 <translation id="1933378685401357864">รูปภาพวอลเปเปอร์</translation>
+<translation id="1942626390957213764">ปิดใช้ฮับการแชร์เดสก์ท็อป</translation>
 <translation id="1945994447126139909">นโยบายระดับองค์กรนี้มีไว้สำหรับการใช้งานในระยะสั้น และเราจะนำนโยบายนี้ออกใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 88
 
       นโยบาย URL ที่มาตามค่าเริ่มต้นของ Chrome เข้มงวดขึ้น จากค่า "ไม่มี URL ที่มาเมื่อดาวน์เกรด" ในปัจจุบันเป็นค่า "ต้นทางที่เข้มงวดเมื่อข้ามต้นทาง" ที่ปลอดภัยยิ่งขึ้นผ่านการทยอยเปิดตัวที่มีเป้าหมายเป็นรุ่น Chrome 85 เวอร์ชันเสถียร
@@ -2423,6 +2431,9 @@
 <translation id="4086150283035515220">การตั้งค่านโยบายเป็น "เปิดใช้" หมายความว่าระบบจะถามผู้ใช้ว่าจะบันทึกไฟล์ไว้ที่ไหนก่อนที่จะดาวน์โหลด การตั้งค่านโยบายเป็น "ปิดใช้" จะทำให้การดาวน์โหลดเริ่มต้นทันที และระบบจะไม่ถามผู้ใช้ว่าจะบันทึกไฟล์ไว้ที่ไหน
 
       การไม่ตั้งค่านโยบายจะทำให้ผู้ใช้เปลี่ยนการตั้งค่าได้</translation>
+<translation id="4087476676669545471">การตั้งค่านโยบายเป็น "จริง" หรือไม่ตั้งค่าจะทำให้ผู้ใช้แชร์หรือบันทึกหน้าเว็บปัจจุบันได้โดยใช้การทำงานที่ฮับการแชร์เดสก์ท็อปมีให้ ฮับการแชร์สามารถเข้าถึงได้ผ่านไอคอนในแถบอเนกประสงค์หรือเมนู 3 จุด
+
+       การตั้งค่านโยบายเป็น "เท็จ" จะนำไอคอนแชร์ออกจากแถบอเนกประสงค์และนำการแชร์ออกจากเมนู 3 จุด</translation>
 <translation id="4088589230932595924">บังคับใช้โหมดไม่ระบุตัวตน</translation>
 <translation id="4089849819635523136">หาก <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> เปิดอยู่ การตั้งค่า <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" /> จะระบุคีย์เวิร์ดหรือทางลัดที่ใช้ในแถบที่อยู่เพื่อทริกเกอร์การค้นหาสำหรับผู้ให้บริการรายนี้
 
@@ -3093,11 +3104,6 @@
 <translation id="5078623750797048009">เปิดใช้คำอธิบายประกอบ PDF</translation>
 <translation id="5082572440690475059">อนุญาตสิทธิ์การเข้าถึงในการอ่านผ่าน File System API ในเว็บไซต์เหล่านี้</translation>
 <translation id="5085647276663819155">ปิดใช้งานหน้าตัวอย่างก่อนพิมพ์</translation>
-<translation id="5087424855041813182">การตั้งค่านโยบายจะให้คุณสร้างรายการรูปแบบ URL ซึ่งระบุเว็บไซต์ที่แสดงการแจ้งเตือนได้
-
-      การไม่ตั้งค่านโยบายหมายความว่า <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> จะมีผลกับทุกเว็บไซต์ (หากตั้งค่าไว้) แต่หากไม่ได้ตั้งค่าไว้ การตั้งค่าส่วนตัวของผู้ใช้จะมีผล
-
-      ดูข้อมูลโดยละเอียดเกี่ยวกับรูปแบบ <ph name="URL_LABEL" /> ที่ถูกต้องได้ที่ https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns <ph name="WILDCARD_VALUE" /> ไม่ใช่ค่าที่ยอมรับสำหรับนโยบายนี้</translation>
 <translation id="5090791951240382356">อนุญาตให้รวมนโยบายพจนานุกรมจากแหล่งที่มาต่างๆ</translation>
 <translation id="5091315650312105069">อนุญาตการตรวจสอบสิทธิ์<ph name="BASIC_AUTH" />สำหรับ HTTP</translation>
 <translation id="5103112931744164177">นโยบายนี้ควบคุมกลุ่มซอฟต์แวร์ที่จะใช้เพื่อสื่อสารกับเซิร์ฟเวอร์ DNS ซึ่งได้แก่ ไคลเอ็นต์ DNS ของระบบปฏิบัติการ หรือไคลเอ็นต์ DNS ในตัวของ <ph name="PRODUCT_NAME" /> นโยบายนี้ไม่มีผลกับเซิร์ฟเวอร์ DNS ที่จะใช้ เช่น หากมีการกำหนดค่าให้ระบบปฏิบัติการใช้เซิร์ฟเวอร์ DNS ขององค์กร ไคลเอ็นต์ DNS ในตัวก็จะใช้เซิร์ฟเวอร์เดียวกันนี้ด้วย นอกจากนี้ นโยบายยังไม่ได้ควบคุมว่าจะใช้ DNS-over-HTTPS หรือไม่ <ph name="PRODUCT_NAME" /> จะใช้รีโซลเวอร์ในตัวเมื่อมีคำขอ DNS-over-HTTPS เสมอ โปรดดูข้อมูลเกี่ยวกับการควบคุม DNS-over-HTTPS ในนโยบาย <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />
@@ -3373,6 +3379,7 @@
 
           หากตั้งค่านโยบายนี้เป็น "ปิดใช้" ระบบจะบังคับให้ปิดใช้ฟีเจอร์
           </translation>
+<translation id="5435888298115339571">เปิดใช้การแชร์เดสก์ท็อปในแถบอเนกประสงค์และเมนู 3 จุด</translation>
 <translation id="5442026853063570579">นโยบายนี้ยังควบคุมการเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ของ Android เช่นกัน หากคุณตั้งค่านโยบายนี้เป็น "DeveloperToolsDisallowed" (ค่า 2) ผู้ใช้จะเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่ได้ หากตั้งค่านโยบายเป็นค่าอื่นหรือไม่ได้ตั้งค่า ผู้ใช้จะเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ได้ด้วยการแตะหมายเลขบิลด์ 7 ครั้งในแอปการตั้งค่าของ Android</translation>
 <translation id="5445596354079213552">นโยบายนี้มีผลเฉพาะเมื่อการอัปเดตอัตโนมัติของอุปกรณ์ถึงวันหมดอายุแล้วและอุปกรณ์มีเวอร์ชันไม่ตรงตามเวอร์ชันขั้นต่ำที่อนุญาตของ <ph name="PRODUCT_OS_NAME" /> ซึ่งตั้งค่าผ่านนโยบาย <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" />
 
@@ -4217,6 +4224,17 @@
       หากไม่ได้ตั้งค่านโยบายหรือนโยบายเป็นรายการที่ว่างเปล่า ก็จะไม่มีบัญชีในอุปกรณ์แสดงเลย</translation>
 <translation id="6584541828182430328">ปิดใช้การแสดงการแจ้งเตือนโหมดเต็มหน้าจอ</translation>
 <translation id="6598235178374410284">รูปโปรไฟล์ของผู้ใช้</translation>
+<translation id="6601311299236772162">นโยบายนี้ควบคุมลักษณะที่ <ph name="PRODUCT_NAME" /> ตีความนโยบายรายการเว็บไซต์/รายการที่ต้องสงสัยของฟีเจอร์การรองรับเบราว์เซอร์เวอร์ชันเก่า ซึ่งจะส่งผลต่อนโยบาย <ph name="URL_LIST_POLICY_NAME" />, <ph name="URL_GREYLIST_POLICY_NAME" />, <ph name="USE_IE_SITELIST_POLICY_NAME" />, <ph name="EXTERNAL_SITELIST_POLICY_NAME" /> และ <ph name="EXTERNAL_GREYLIST_POLICY_NAME" />
+
+      หากเป็น "ค่าเริ่มต้น" (0) หรือไม่ได้ตั้งค่า การจับคู่ URL จะไม่เข้มงวดนัก กฎที่ไม่มีอักขระ "/" จะค้นหาสตริงย่อยจากทุกส่วนในชื่อโฮสต์ของ URL
+
+      หากเป็น "เข้มงวด" (1) การจับคู่ URL จะเข้มงวดยิ่งขึ้น กฎที่ไม่มีอักขระ "/" จะจับคู่ที่ส่วนท้ายของชื่อโฮสต์เท่านั้น และต้องอยู่ที่ขอบเขตของชื่อโดเมนด้วย นโยบายนี้เข้ากันกับ <ph name="MS_IE_PRODUCT_NAME" /> และ <ph name="MS_EDGE_PRODUCT_NAME" /> ได้ดีกว่า
+
+      ตัวอย่างเช่น เมื่อใช้กฎ "example.com"
+
+      "http://example.com/" และ "http://subdomain.example.com/" ถือว่าตรงกันไม่ว่าจะเปิดใช้โหมดการแยกวิเคราะห์หรือไม่ก็ตาม
+
+      ส่วน "http://notexample.com/", "http://example.com.invalid.com/" และ "http://example.comabc/" จะถือว่าตรงกันเมื่อเปิดใช้โหมด "ค่าเริ่มต้น" เท่านั้น</translation>
 <translation id="6603004149426829878">ส่งสัญญาณแจ้งตำแหน่งใดก็ตามที่มีอยู่ไปยังเซิร์ฟเวอร์ทุกครั้งขณะค้นหาเขตเวลา</translation>
 <translation id="6604049565198492174">การตั้งค่านโยบายจะทำให้กำหนดค่าเครือข่ายแบบพุชสำหรับผู้ใช้แต่ละคนของอุปกรณ์ <ph name="PRODUCT_NAME" /> แต่ละเครื่องได้ การกำหนดค่าเครือข่ายจะเป็นสตริงรูปแบบ JSON ตามที่กำหนดโดยรูปแบบการกำหนดค่าเครือข่ายแบบเปิด (Open Network Configuration)</translation>
 <translation id="660567106648774919">นโยบายนี้เลิกใช้งานไปแล้ว โปรดใช้นโยบาย <ph name="TOS_DIALOG_BEHAVIOR_POLICY_NAME" /> แทน
@@ -4406,26 +4424,6 @@
 
           หมายเหตุ: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> จะลบล้างนโยบายนี้หากระบุนโยบายเดิมไว้</translation>
 <translation id="6833988859168635883">เริ่มต้นใช้งาน หน้าแรก และหน้าแท็บใหม่</translation>
-<translation id="6834298774555537368">การตั้งค่านโยบายนี้จะกำหนดค่าพร็อกซีสำหรับ Chrome และแอป ARC โดยไม่พิจารณาตัวเลือกเกี่ยวกับพร็อกซีทั้งหมดที่ระบุจากบรรทัดคำสั่ง
-
-       การไม่ตั้งค่านโยบายนี้จะทำให้ผู้ใช้เลือกการตั้งค่าพร็อกซีได้
-
-       การตั้งค่านโยบาย <ph name="PROXY_SETTINGS_POLICY_NAME" /> จะยอมรับช่องต่อไปนี้
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> ซึ่งช่วยให้คุณระบุพร็อกซีเซิร์ฟเวอร์ที่ Chrome จะใช้ได้ และป้องกันไม่ให้ผู้ใช้เปลี่ยนการตั้งค่าพร็อกซี
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> URL ไปยังไฟล์ .pac ของพร็อกซี
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> URL ของพร็อกซีเซิร์ฟเวอร์
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> รายการโฮสต์ที่จะข้ามพร็อกซี
-
-       ช่อง <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> เลิกใช้งานแล้วเพื่อใช้ช่อง <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> แทน
-
-        สำหรับ <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> หากคุณเลือกค่าต่อไปนี้
-          * <ph name="PROXY_MODE_ENUM_DIRECT" /> ระบบจะไม่ใช้พร็อกซีและจะไม่พิจารณาช่องอื่นๆ ทั้งหมด
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" /> ระบบจะใช้พร็อกซีของระบบและจะไม่พิจารณาช่องอื่นๆ ทั้งหมด
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" /> ระบบจะไม่พิจารณาช่องอื่นๆ ทั้งหมด
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" /> ระบบจะใช้ช่อง <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> และ <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" /> ระบบจะใช้ช่อง <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> และ <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />
-
-      หมายเหตุ: ดูตัวอย่างโดยละเอียดเพิ่มเติมได้ที่ The Chromium Projects ( https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett )</translation>
 <translation id="6835883744948188639">แสดงข้อความแจ้งที่ปรากฏขึ้นซ้ำๆ แก่ผู้ใช้เพื่อแจ้งว่าควรเปิดเบราว์เซอร์ขึ้นมาใหม่</translation>
 <translation id="683688607121170501">การตั้งค่านี้ทำให้ผู้ใช้สลับการใช้งานระหว่างบัญชี Google ได้ภายในพื้นที่เนื้อหาของหน้าต่างเบราว์เซอร์และในแอปพลิเคชันของ Android หลังจากที่ลงชื่อเข้าใช้อุปกรณ์ <ph name="PRODUCT_OS_NAME" />
 
@@ -4727,11 +4725,6 @@
 <translation id="7126928806195745404">การตั้งค่า JavaScript</translation>
 <translation id="7127892035367404455">ย้อนกลับไปเวอร์ชันเป้าหมาย</translation>
 <translation id="7127980134843952133">ประวัติการดาวน์โหลด</translation>
-<translation id="7129052644387688634">การตั้งค่านโยบายจะให้คุณสร้างรายการรูปแบบ URL ซึ่งระบุเว็บไซต์ที่แสดงการแจ้งเตือนไม่ได้
-
-      การไม่ตั้งค่านโยบายหมายความว่า <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> จะมีผลกับทุกเว็บไซต์ (หากตั้งค่าไว้) แต่หากไม่ได้ตั้งค่าไว้ การตั้งค่าส่วนตัวของผู้ใช้จะมีผล
-
-      ดูข้อมูลโดยละเอียดเกี่ยวกับรูปแบบ <ph name="URL_LABEL" /> ที่ถูกต้องได้ที่ https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns  <ph name="WILDCARD_VALUE" /> ไม่ใช่ค่าที่ยอมรับสำหรับนโยบายนี้</translation>
 <translation id="712963038874313213">นโยบายที่มี Ansible Playbook ที่ควรจะเรียกใช้ในคอนเทนเนอร์ Crostini เริ่มต้น
 
       นโยบายนี้อนุญาตให้มี Ansible Playbook ที่จะใช้ในคอนเทนเนอร์ Crostini เริ่มต้นหากมีในอุปกรณ์นั้นๆ และนโยบายต่างๆ อนุญาตให้ใช้ได้
@@ -5160,6 +5153,13 @@
 
           ควรระบุค่าของนโยบายเป็นมิลลิวินาที ค่าจะถูกบีบให้น้อยกว่าหรือเท่ากับระยะหน่วงเวลาการปิดหน้าจอ (หากตั้งค่า) และระยะหน่วงเวลาของการไม่มีความเคลื่อนไหว</translation>
 <translation id="7680437377926096177">ระงับการแสดงกล่องโต้ตอบการออกจากระบบเมื่อปิดหน้าต่างสุดท้าย</translation>
+<translation id="7681958144280390173">การตั้งค่านโยบายเป็น "เปิดใช้" จะแยกเว็บไซต์ทั้งหมด (แต่ละเว็บไซต์จะทำงานด้วยกระบวนการของตัวเอง) โปรดทราบว่า Android จะแยกเว็บไซต์ที่มีความละเอียดอ่อนบางเว็บไซต์โดยค่าเริ่มต้นใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 เป็นต้นไป และนโยบายนี้จะขยายการทำงานของโหมดการแยกเว็บไซต์ตามค่าเริ่มต้นให้มีผลกับเว็บไซต์ทั้งหมด
+
+      การตั้งค่านโยบายเป็น "ปิดใช้" จะปิดการแยกเว็บไซต์ทุกรูปแบบ เช่น การแยกเว็บไซต์ที่มีความละเอียดอ่อน รวมถึงการทดลองใช้งานจริงของ IsolateOriginsAndroid และ SitePerProcessAndroid ตลอดจนโหมดการแยกเว็บไซต์อื่นๆ ผู้ใช้ยังคงเปิดใช้นโยบายด้วยตนเองได้
+
+      การไม่ตั้งค่านโยบายจะทำให้ผู้ใช้เปลี่ยนการตั้งค่านี้ได้
+
+      หมายเหตุ: เราจะปรับปรุงการรองรับการแยกทุกเว็บไซต์ใน Android แต่ปัจจุบันฟีเจอร์นี้อาจก่อให้เกิดปัญหาด้านประสิทธิภาพ โดยเฉพาะกับอุปกรณ์ระดับโลว์เอนด์ นโยบายนี้มีผลเฉพาะกับ Chrome ใน Android ที่ทำงานในอุปกรณ์ที่มี RAM มากกว่า 1 GB เท่านั้น หากต้องการแยกบางเว็บไซต์ในขณะที่ป้องกันไม่ให้ผู้ใช้ได้รับผลกระทบด้านประสิทธิภาพมากนัก ให้ใช้ <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> กับรายชื่อเว็บไซต์ที่ต้องการแยก  หากต้องการใช้นโยบายกับแพลตฟอร์มที่ไม่ใช่ Android ให้ใช้ <ph name="SITE_PER_PROCESS_POLICY_NAME" /></translation>
 <translation id="7683777542468165012">การรีเฟรชนโยบายแบบไดนามิก</translation>
 <translation id="7687943045976362719">หากตั้งค่านโยบายนี้ <ph name="PRODUCT_FRAME_NAME" /> จะจัดการประเภทของเนื้อหาที่ระบุไว้
 
@@ -5870,6 +5870,7 @@
       หากไม่ได้ตั้งค่า หน้าแท็บใหม่จะเปิดเมื่อเริ่มต้นใช้งาน
 
       ใน <ph name="MS_WIN_NAME" /> ฟังก์ชันการทำงานนี้ใช้ได้เฉพาะในอินสแตนซ์ที่เข้าร่วมโดเมน <ph name="MS_AD_NAME" />, ทำงานใน Windows 10 Pro หรือลงทะเบียนใน<ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" /> ใน <ph name="MAC_OS_NAME" /> ฟังก์ชันการทำงานนี้ใช้ได้เฉพาะในอินสแตนซ์ที่จัดการผ่าน MDM หรือเข้าร่วมโดเมนผ่าน MCX</translation>
+<translation id="8671119576957984818">เปิดใช้ฮับการแชร์เดสก์ท็อป</translation>
 <translation id="8672321184841719703">กำหนดเป้าหมายรุ่นที่อัปเดตอัตโนมัติ</translation>
 <translation id="867410340948518937">U2F (Universal Second Factor)</translation>
 <translation id="8676959842615154675">การตั้งค่านโยบายเป็น "เปิดใช้" จะทำให้โฮสต์การเข้าถึงระยะไกลเปรียบเทียบชื่อของผู้ใช้เครือข่ายภายในที่เชื่อมโยงกับโฮสต์กับชื่อบัญชี Google ที่ลงทะเบียนเป็นเจ้าของโฮสต์ ("johndoe" หากเจ้าของโฮสต์คือ "johndoe@example.com") โฮสต์นี้จะไม่เริ่มหากชื่อของเจ้าของโฮสต์แตกต่างจากชื่อผู้ใช้เครือข่ายภายในที่เชื่อมโยงกับโฮสต์ หากต้องการยืนยันให้บัญชี Google ของเจ้าของเชื่อมโยงกับโดเมนที่เจาะจง ให้ใช้นโยบายกับ <ph name="REMOTE_ACCESS_HOST_DOMAIN_POLICY_NAME" />
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb
index 7073fd0..9e53694 100644
--- a/components/policy/resources/policy_templates_tr.xtb
+++ b/components/policy/resources/policy_templates_tr.xtb
@@ -3124,11 +3124,6 @@
 <translation id="5078623750797048009">PDF Ek Açıklamalarını etkinleştir</translation>
 <translation id="5082572440690475059">Bu sitelerde File System API üzerinden okuma erişimine izin ver</translation>
 <translation id="5085647276663819155">Baskı Önizlemeyi Devre Dışı Bırak</translation>
-<translation id="5087424855041813182">Politikayı ayarlamak bildirimleri görüntüleyebilen siteleri belirten URL kalıpları için bir liste yapmanıza olanak tanır.
-
-      Politika ayarlanmadan bırakılırsa <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (etkinse) bütün siteler için geçerli olur. Aksi takdirde kullanıcının kişisel ayarları geçerlidir.
-
-      Geçerli <ph name="URL_LABEL" /> kalıpları hakkında ayrıntılı bilgi için https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns adresine bakabilirsiniz. <ph name="WILDCARD_VALUE" />, bu politikada kabul edilen bir değer değildir.</translation>
 <translation id="5090791951240382356">Farklı kaynaklara ait sözlük politikalarını birleştirmeye izin ver</translation>
 <translation id="5091315650312105069">HTTP için <ph name="BASIC_AUTH" /> kimlik doğrulamasına izin ver</translation>
 <translation id="5103112931744164177">Bu politika, DNS sunucusuyla iletişim kurmak için hangi yazılım yığınının kullanıldığını kontrol eder: İşletim Sistemi DNS istemcisi veya <ph name="PRODUCT_NAME" /> ürününün yerleşik DNS istemcisi. Bu politika hangi DNS sunucularının kullanıldığını etkilemez: Örneğin, işletim sistemi kurumsal DNS sunucusu kullanacak şekilde yapılandırılmışsa aynı sunucu, yerleşik DNS istemcisi tarafından da kullanılır. Ayrıca DNS-over-HTTPS kullanılıp kullanılmadığını da kontrol etmez; <ph name="PRODUCT_NAME" />, DNS-over-HTTPS istekleri için her zaman yerleşik çözümleyici kullanır. DNS-over-HTTPS'nin kontrolüyle ilgili bilgi için <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> politikasına bakın.
@@ -4450,26 +4445,6 @@
 
           Not: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> belirtilmişse bu politikayı geçersiz kılar.</translation>
 <translation id="6833988859168635883">Başlangıç, Ana sayfa ve Yeni Sekme sayfası</translation>
-<translation id="6834298774555537368">Politikanın ayarlanması, komut satırında proxy ile ilgili belirtilen tüm seçenekleri yok sayan Chrome ve ARC-uygulamaları için proxy ayarlarını yapılandırır.
-
-       Politika ayarlanmazsa kullanıcılar kendi proxy ayarlarını seçebilir.
-
-       <ph name="PROXY_SETTINGS_POLICY_NAME" /> politikası ayarlandığında aşağıdaki alanlar kabul edilmiş olur:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, Chrome'un kullandığı proxy sunucusunu belirtmenizi sağlar ve kullanıcıların proxy ayarlarını değiştirmesini önler
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />, proxy .pac dosyası için URL
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />, proxy sunucu URL'si
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />, proxy'nin atlanmasını sağlayan sunucuların listesi
-
-       <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> alanı kullanımdan kaldırılmış, yerine <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> alanı getirilmiştir.
-
-        <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> için aşağıdaki değerleri seçerseniz:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, proxy hiçbir zaman kullanılmaz ve diğer tüm alanlar yok sayılır.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, sisteme ait proxy kullanılır ve diğer tüm alanlar yok sayılır.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, diğer tüm alanlar yok sayılır.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> ve <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> alanları kullanılır.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> ve <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> alanları kullanılır.
-
-      Not: Daha ayrıntılı örnekler için Chromium Projeleri'ni ziyaret edin (https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett).</translation>
 <translation id="6835883744948188639">Kullanıcıya yeniden başlatmanın önerildiğini belirten yinelenen bir istem gösterme</translation>
 <translation id="683688607121170501">Bu ayar, kullanıcıların <ph name="PRODUCT_OS_NAME" /> cihazlarında oturum açtıktan sonra tarayıcı pencerelerinin içerik alanındaki Google Hesapları arasında geçiş yapmalarına olanak tanır.
 
@@ -4771,11 +4746,6 @@
 <translation id="7126928806195745404">JavaScript ayarları</translation>
 <translation id="7127892035367404455">Hedef sürüme geri dönme</translation>
 <translation id="7127980134843952133">İndirme geçmişi</translation>
-<translation id="7129052644387688634">Politikayı ayarlamak bildirimleri görüntüleyemeyen siteleri belirten URL kalıpları için bir liste yapmanıza olanak tanır.
-
-      Politika ayarlanmadan bırakılırsa <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (etkinse) bütün siteler için geçerli olur. Aksi takdirde kullanıcının kişisel ayarları geçerlidir.
-
-      Geçerli <ph name="URL_LABEL" /> kalıpları hakkında ayrıntılı bilgi için https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns adresine bakabilirsiniz.  <ph name="WILDCARD_VALUE" />, bu politikada kabul edilen bir değer değildir.</translation>
 <translation id="712963038874313213">Varsayılan Crostini kapsayıcısında uygulanması gereken bir Ansible başucu kitabı sağlar.
 
       Bu politika, belirtilen cihazda kullanılabiliyorsa ve politika tarafından izin veriliyorsa varsayılan Crostini kapsayıcısına uygulanacak bir Ansible başucu kitabının sağlanmasına olanak tanır.
diff --git a/components/policy/resources/policy_templates_uk.xtb b/components/policy/resources/policy_templates_uk.xtb
index 476548b..3b4b417bc 100644
--- a/components/policy/resources/policy_templates_uk.xtb
+++ b/components/policy/resources/policy_templates_uk.xtb
@@ -3153,11 +3153,6 @@
 <translation id="5078623750797048009">Увімкнути примітки у файлах PDF</translation>
 <translation id="5082572440690475059">Дозволити перегляд через File System API на цих сайтах</translation>
 <translation id="5085647276663819155">Вимкнути попередній перегляд друку</translation>
-<translation id="5087424855041813182">За допомогою цього правила можна вказати список шаблонів URL-адрес, що визначають сайти, які можуть показувати сповіщення.
-
-      Якщо це правило не налаштовано, до всіх сайтів застосовуватиметься правило <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> за умови, що воно налаштоване. Якщо ні, використовуються особисті налаштування користувачів.
-
-      Докладніше про дійсні шаблони <ph name="URL_LABEL" />-адрес можна дізнатися на сторінці https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. <ph name="WILDCARD_VALUE" /> – недопустиме значення для цього правила.</translation>
 <translation id="5090791951240382356">Дає змогу об'єднувати правила словників із різних джерел</translation>
 <translation id="5091315650312105069">Дозволити автентифікацію <ph name="BASIC_AUTH" /> для з'єднань HTTP</translation>
 <translation id="5103112931744164177">Це правило вказує, який набір програмного забезпечення використовується для обміну даними з DNS-сервером (клієнт DNS операційної системи чи вбудований клієнт DNS <ph name="PRODUCT_NAME" />). Це правило не впливає на те, які DNS-сервери використовуються. Наприклад, якщо операційну систему налаштовано на використання корпоративного DNS-сервера, його також застосовуватиме вбудований клієнт DNS. Воно також не контролює, чи використовується DNS-over-HTTPS. <ph name="PRODUCT_NAME" /> завжди використовуватиме вбудований резолвер для запитів DNS-over-HTTPS. Щоб дізнатися про керування протоколом DNS-over-HTTPS, перегляньте правило <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" />.
@@ -4507,26 +4502,6 @@
 
           Примітка: якщо вказано правило <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />, воно замінює це правило.</translation>
 <translation id="6833988859168635883">Стартова й домашня сторінки та сторінка нової вкладки</translation>
-<translation id="6834298774555537368">За допомогою налаштувань цього правила можна вибрати параметри проксі для Chrome і додатків ARC, які ігнорують усі опції проксі, указані в командному рядку.
-
-       Якщо не налаштувати це правило, користувачі зможуть самостійно вибирати параметри проксі.
-
-       Якщо правило <ph name="PROXY_SETTINGS_POLICY_NAME" /> налаштовано, буде прийнято ці поля:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> визначає проксі-сервер для Chrome і забороняє користувачам змінювати ці налаштування;
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> – URL-адреса файлу .pac проксі-сервера;
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> – URL-адреса проксі-сервера;
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> – список хостів, які працюватимуть в обхід проксі-сервера.
-
-       Поле <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> застаріле. Замість нього використовується поле <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Якщо для параметра <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> вибрати значення:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, проксі ніколи не використовуватиметься, а всі інші поля ігноруватимуться;
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, використовуватимуться проксі системи, а всі інші поля ігноруватимуться;
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, усі інші поля ігноруватимуться;
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, використовуватимуться поля <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> і <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />;
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, використовуватимуться поля <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> і <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />.
-
-      Примітка: щоб переглянути детальніші приклади, відвідайте веб-сайт проектів Chromium (https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett).</translation>
 <translation id="6835883744948188639">Показувати користувачеві повторюваний запит із рекомендацією перезапуску</translation>
 <translation id="683688607121170501">Це налаштування дає змогу користувачам переходити в інші облікові записи Google у вікні контенту веб-переглядача та в додатках Android, якщо вони ввійшли на пристрої з <ph name="PRODUCT_OS_NAME" />.
 
@@ -4828,11 +4803,6 @@
 <translation id="7126928806195745404">Налаштування JavaScript</translation>
 <translation id="7127892035367404455">Відкочування до цільової версії</translation>
 <translation id="7127980134843952133">Історія завантажень</translation>
-<translation id="7129052644387688634">За допомогою цього правила можна вказати список шаблонів URL-адрес, що визначають сайти, яким заборонено показувати сповіщення.
-
-      Якщо це правило не налаштовано, до всіх сайтів застосовуватиметься правило <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> за умови, що воно налаштоване. Якщо ні, використовуються особисті налаштування користувачів.
-
-      Докладніше про дійсні шаблони <ph name="URL_LABEL" />-адрес можна дізнатися на сторінці https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  <ph name="WILDCARD_VALUE" /> – недопустиме значення для цього правила.</translation>
 <translation id="712963038874313213">Містить посібник правил Ansible, які мають виконуватися в контейнері Crostini за умовчанням.
 
       Це правило дає змогу застосовувати посібник Ansible у контейнері Crostini за умовчанням, якщо він доступний на пристрої й дозволений правилами.
diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb
index 03fbae1..e167a5d 100644
--- a/components/policy/resources/policy_templates_vi.xtb
+++ b/components/policy/resources/policy_templates_vi.xtb
@@ -3152,11 +3152,6 @@
 <translation id="5078623750797048009">Cho phép chú thích trong tệp PDF</translation>
 <translation id="5082572440690475059">Cho phép quyền đọc qua API Hệ thống tệp trên các trang web này</translation>
 <translation id="5085647276663819155">Vô hiệu hóa xem trước bản in</translation>
-<translation id="5087424855041813182">Nếu đặt chính sách này, bạn có thể thiết lập danh sách các mẫu URL chỉ định những trang web được phép hiển thị thông báo.
-
-      Khi bạn không đặt chính sách này, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (nếu được đặt) sẽ áp dụng cho tất cả trang web. Nếu không, tùy chọn cài đặt cá nhân của người dùng sẽ được áp dụng.
-
-      Để biết thông tin chi tiết về các mẫu <ph name="URL_LABEL" /> hợp lệ, vui lòng xem tại https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. Chúng tôi không chấp nhận giá trị <ph name="WILDCARD_VALUE" /> đối với chính sách này.</translation>
 <translation id="5090791951240382356">Cho phép hợp nhất các chính sách từ điển thuộc các nguồn khác nhau</translation>
 <translation id="5091315650312105069">Cho phép dùng phương thức xác thực <ph name="BASIC_AUTH" /> cho HTTP</translation>
 <translation id="5103112931744164177">Chính sách này kiểm soát ngăn phần mềm nào được dùng để giao tiếp với máy chủ DNS: ứng dụng DNS của hệ điều hành hay ứng dụng DNS tích hợp sẵn của <ph name="PRODUCT_NAME" />. Chính sách này không ảnh hưởng đến việc máy chủ DNS nào được sử dụng: chẳng hạn như nếu hệ điều hành được định cấu hình để sử dụng một máy chủ DNS của doanh nghiệp, thì ứng dụng DNS tích hợp sẵn sẽ sử dụng chính máy chủ đó. Chính sách này cũng không kiểm soát việc DNS qua HTTPS có được sử dụng hay không. <ph name="PRODUCT_NAME" /> sẽ luôn sử dụng trình phân giải tích hợp sẵn cho các yêu cầu DNS qua HTTPS. Vui lòng xem chính sách <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> để biết thông tin về cách kiểm soát DNS qua HTTPS.
@@ -4511,26 +4506,6 @@
 
           Lưu ý: <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" /> (nếu đã được chỉ định) sẽ ghi đè chính sách này.</translation>
 <translation id="6833988859168635883">Trang Khởi động, Trang chủ và trang Thẻ mới</translation>
-<translation id="6834298774555537368">Khi bạn đặt chính sách này, các chế độ cài đặt proxy cho Chrome và các ứng dụng dùng App Runtime for Chrome (ARC) sẽ được định cấu hình. Chrome và các ứng dụng này sẽ bỏ qua mọi tùy chọn liên quan đến proxy được chỉ định thông qua dòng lệnh.
-
-       Nếu bạn không đặt chính sách này, người dùng có thể chọn các chế độ cài đặt proxy.
-
-       Nếu đặt chính sách <ph name="PROXY_SETTINGS_POLICY_NAME" />, bạn chấp nhận những trường sau đây:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, cho phép bạn chỉ định máy chủ proxy mà Chrome sẽ sử dụng và ngăn người dùng thay đổi các chế độ cài đặt proxy
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />, một URL dẫn tới một tệp proxy .pac
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />, một URL của máy chủ proxy
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />, một danh sách các máy chủ mà Chrome sẽ bỏ qua proxy
-
-       Trường <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> không còn dùng nữa mà thay bằng trường <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />.
-
-        Đối với <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />, nếu bạn chọn giá trị:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />, proxy sẽ không bao giờ được dùng và tất cả các trường khác sẽ bị bỏ qua.
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />, proxy của các hệ thống sẽ được dùng và tất cả các trường khác sẽ bị bỏ qua.
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />, tất cả các trường khác sẽ bị bỏ qua.
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />, các trường <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> và <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> sẽ được dùng.
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />, các trường <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> và <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> sẽ được dùng.
-
-      Lưu ý: Để xem thêm ví dụ cụ thể, hãy truy cập vào trang The Chromium Projects (https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett).</translation>
 <translation id="6835883744948188639">Nên hiển thị lời nhắc định kỳ cho người dùng cho biết cần chạy lại</translation>
 <translation id="683688607121170501">Tùy chọn cài đặt này cho phép người dùng chuyển đổi giữa các Tài khoản Google trong vùng nội dung của cửa sổ trình duyệt và trong các ứng dụng Android sau khi họ đăng nhập vào thiết bị <ph name="PRODUCT_OS_NAME" />.
 
@@ -4832,11 +4807,6 @@
 <translation id="7126928806195745404">Cài đặt JavaScript</translation>
 <translation id="7127892035367404455">Khôi phục về phiên bản đích</translation>
 <translation id="7127980134843952133">Dữ liệu về các tệp đã tải xuống</translation>
-<translation id="7129052644387688634">Nếu đặt chính sách này, bạn có thể thiết lập danh sách các mẫu URL chỉ định những trang web không được phép hiển thị thông báo.
-
-      Khi bạn không đặt chính sách này, <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> (nếu được đặt) sẽ áp dụng cho tất cả trang web. Nếu không, tùy chọn cài đặt cá nhân của người dùng sẽ được áp dụng.
-
-      Để biết thông tin chi tiết về các mẫu <ph name="URL_LABEL" /> hợp lệ, vui lòng xem tại https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.  Chúng tôi không chấp nhận giá trị <ph name="WILDCARD_VALUE" /> đối với chính sách này.</translation>
 <translation id="712963038874313213">Cung cấp playbook Ansible sẽ được thực thi trong vùng chứa Crostini mặc định.
 
       Chính sách này cho phép cung cấp playbook Ansible được áp dụng cho vùng chứa Crostini mặc định nếu playbook đó có trên thiết bị cho sẵn và được các chính sách cho phép.
diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb
index 2cfd2d0..2176765 100644
--- a/components/policy/resources/policy_templates_zh-CN.xtb
+++ b/components/policy/resources/policy_templates_zh-CN.xtb
@@ -363,6 +363,13 @@
       如果您不设置此政策,<ph name="PRODUCT_NAME" /> 将会尝试检测某台服务器是否在内网上,确认在内网后才会响应它发出的 IWA 请求。如果检测到某台服务器是在互联网上,<ph name="PRODUCT_NAME" /> 将会忽略这台服务器发出的 IWA 请求。
 
       注意:若要指定多个服务器名称,请用英文逗号分隔。允许使用通配符 <ph name="WILDCARD_VALUE" />。</translation>
+<translation id="1495817006535797003">如果您设置了此政策,逗号分隔列表中指定的每个来源都将在自己的进程中运行,以子网域形式指定的来源也会被隔离。例如,指定 https://example.com/ 会导致 https://foo.example.com/ 被隔离(作为 https://example.com/ 网站的一部分)。请注意,从 <ph name="PRODUCT_NAME" /> 版本 77 起,Android 会在默认情况下隔离某些敏感网站,并且此政策会扩展该模式,以隔离其他特定的来源。
+
+      如果将此政策设为停用,系统会关闭所有形式的网站隔离功能,包括隔离敏感网站、IsolateOriginsAndroid 和 SitePerProcessAndroid 的现场试验,以及其他网站隔离模式。不过,用户仍可以通过命令行标记手动开启 IsolateOrigins。
+
+      如果您不设置此政策,用户便可更改此设置。
+
+      注意:在 Android 上隔离过多网站可能会导致性能问题,尤其是在低内存设备上。此政策仅适用于在符合条件(RAM 不小于 1 GB)的设备上运行的 Android 版 Chrome。如需在非 Android 平台上应用此政策,请改用 <ph name="ISOLATE_ORIGINS_POLICY_NAME" />。</translation>
 <translation id="1502843533062797703">禁止插入第三方软件</translation>
 <translation id="1503969899251962413">通过设置此政策,您可为该设备指定 <ph name="PLUGIN_VM_NAME" /> 许可密钥。
 
@@ -694,6 +701,7 @@
 <translation id="1930127294345368978">单个打印任务可以使用的纸张数上限</translation>
 <translation id="193259052151668190">分离式 USB 设备白名单</translation>
 <translation id="1933378685401357864">壁纸图片</translation>
+<translation id="1942626390957213764">停用桌面分享中心</translation>
 <translation id="1945994447126139909">这项企业政策只是短期的适应性措施,将在 <ph name="PRODUCT_NAME" /> 版本 88 中移除。
 
       为配合 Chrome 85 稳定版的逐步推出,Chrome 的默认引荐来源网址政策正从其当前值 no-referrer-when-downgrade 强化为更安全的 strict-origin-when-cross-origin。
@@ -2423,6 +2431,9 @@
 <translation id="4086150283035515220">如果此政策已启用,系统会在开始下载前询问用户要将相应文件保存到何处。如果此政策已停用,系统不会先询问用户要将相应文件保存到何处,而是会立即开始下载文件。
 
       如果您不设置此政策,用户便可更改此设置。</translation>
+<translation id="4087476676669545471">如果此政策设为 True 或未设置,用户便可使用桌面分享中心提供的操作分享或保存当前网页。可通过多功能框或三点状菜单访问分享中心。
+
+       如果此政策设为 False,系统会从多功能框移除分享图标,并从三点状菜单移除相应条目。</translation>
 <translation id="4088589230932595924">强制使用隐身模式</translation>
 <translation id="4089849819635523136">如果 <ph name="DEFAULT_SEARCH_PROVIDER_ENABLED_POLICY_NAME" /> 已开启,您便可通过设置 <ph name="DEFAULT_SEARCH_PROVIDER_KEYWORD_POLICY_NAME" /> 来指定关键字或快捷方式,以用于在地址栏中触发针对此提供商的搜索。
 
@@ -3093,11 +3104,6 @@
 <translation id="5078623750797048009">启用 PDF 注释</translation>
 <translation id="5082572440690475059">允许在这些网站上通过 File System API 读取内容</translation>
 <translation id="5085647276663819155">停用打印预览</translation>
-<translation id="5087424855041813182">通过设置此政策,您可以创建一个网址格式列表,从而指定哪些网站可以显示通知。
-
-      如果您未设置此政策,那么,倘若 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> 已设置,系统便会将它应用于所有网站,否则就会应用用户的个人设置。
-
-      如需详细了解有效的<ph name="URL_LABEL" />格式,请访问 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。<ph name="WILDCARD_VALUE" /> 不是此政策可接受的值。</translation>
 <translation id="5090791951240382356">允许合并来自多个不同来源的字典政策</translation>
 <translation id="5091315650312105069">允许通过 HTTP 进行<ph name="BASIC_AUTH" />身份验证</translation>
 <translation id="5103112931744164177">此政策用于控制使用哪个软件堆栈与 DNS 服务器通信:操作系统 DNS 客户端或 <ph name="PRODUCT_NAME" /> 的内置 DNS 客户端。此政策不会影响使用哪些 DNS 服务器:例如,如果操作系统已配置为使用一台企业 DNS 服务器,内置 DNS 客户端也会使用这台服务器。此政策也不会控制是否使用 DNS-over-HTTPS;<ph name="PRODUCT_NAME" /> 将始终使用内置的解析器发送 DNS-over-HTTPS 请求。如需了解如何控制 DNS-over-HTTPS,请参阅 <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> 政策。
@@ -3373,6 +3379,7 @@
 
           如果此政策已停用,系统会强制停用该功能。
           </translation>
+<translation id="5435888298115339571">在多功能框和三点状菜单中启用桌面分享功能</translation>
 <translation id="5442026853063570579">此政策亦用于控制对 Android 开发者选项的访问权限。如果此政策设为“DeveloperToolsDisallowed”(值为 2),用户将无法访问开发者选项。如果此政策设为其他值或未设置,用户只需在 Android 的“设置”应用中连续点按 7 次版本号即可访问开发者选项。</translation>
 <translation id="5445596354079213552">仅当设备的自动更新期限已过且不符合允许使用的最低 <ph name="PRODUCT_OS_NAME" />版本(通过 <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> 政策设置)的要求时,此政策才有效。
 
@@ -4217,6 +4224,17 @@
       如果您不设置此政策或此政策是空列表,则不存在设备本地帐号。</translation>
 <translation id="6584541828182430328">停用“显示全屏提醒”功能</translation>
 <translation id="6598235178374410284">用户头像图片</translation>
+<translation id="6601311299236772162">此政策用于控制 <ph name="PRODUCT_NAME" /> 如何解析“旧版浏览器支持”功能的 sitelist/greylist 政策。它会影响以下政策:<ph name="URL_LIST_POLICY_NAME" />、<ph name="URL_GREYLIST_POLICY_NAME" />、<ph name="USE_IE_SITELIST_POLICY_NAME" />、<ph name="EXTERNAL_SITELIST_POLICY_NAME" /> 和 <ph name="EXTERNAL_GREYLIST_POLICY_NAME" />。
+
+      如果此政策设为“默认”(0) 或未设置,网址匹配将不太严格。不含“/”的规则会在网址主机名中的任意位置查找子字符串。
+
+      如果此政策设为“严格”(1),网址匹配将更为严格。不含“/”的规则仅在主机名末尾处匹配。它们还必须位于域名边界。此政策可以更好地兼容 <ph name="MS_IE_PRODUCT_NAME" /> 和 <ph name="MS_EDGE_PRODUCT_NAME" />。
+
+      例如,对于规则“example.com”:
+
+      “http://example.com/”和“http://subdomain.example.com/”匹配,无论解析模式为何。
+
+      “http://notexample.com/”、“http://example.com.invalid.com/”和“http://example.comabc/”仅在“默认”模式下匹配。</translation>
 <translation id="6603004149426829878">解析时区时一律将任何可用的位置信号发送给服务器</translation>
 <translation id="6604049565198492174">通过设置此政策,您可以允许向各部 <ph name="PRODUCT_NAME" /> 设备推送要用于各个用户的网络配置。网络配置是 JSON 格式的字符串,如 Open Network Configuration 格式所定义。</translation>
 <translation id="660567106648774919">此政策已被弃用,请改用 <ph name="TOS_DIALOG_BEHAVIOR_POLICY_NAME" /> 政策。
@@ -4406,26 +4424,6 @@
 
           注意:<ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />(若已指定)会覆盖此政策。</translation>
 <translation id="6833988859168635883">启动页、主页和新标签页</translation>
-<translation id="6834298774555537368">通过设置此政策,您可为 Chrome 和 ARC 应用配置代理设置,它们会忽略从命令行中指定的所有与代理有关的选项。
-
-       如果您未设置此政策,用户便可自行选择代理设置。
-
-       设置 <ph name="PROXY_SETTINGS_POLICY_NAME" /> 政策时可使用以下字段:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />,该字段让您能够指定 Chrome 使用的代理服务器,并禁止用户更改代理设置
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" />,即代理 .pac 文件的网址
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" />,即代理服务器的网址
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" />,该字段让您能够以列表形式指定允许哪些主机绕过代理
-
-       <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> 字段已被弃用且已被 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> 字段取代。
-
-        对于 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" />,如果您选择以下值:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />,系统永远不会使用代理,并且会忽略所有其他字段。
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />,系统会使用自己的代理,并且会忽略所有其他字段。
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />,系统会忽略所有其他字段。
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />,系统会使用 <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> 和 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 字段。
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />,系统会使用 <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> 和 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 字段。
-
-      注意:如需查看更详细的示例,请访问 Chromium 项目 ( https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett )。</translation>
 <translation id="6835883744948188639">显示建议用户重新启动浏览器的周期性提示</translation>
 <translation id="683688607121170501">通过此设置,您可允许用户在登录其 <ph name="PRODUCT_OS_NAME" />设备后从浏览器窗口的内容区域和 Android 应用中切换 Google 帐号。
 
@@ -4727,11 +4725,6 @@
 <translation id="7126928806195745404">JavaScript 设置</translation>
 <translation id="7127892035367404455">回滚到目标版本</translation>
 <translation id="7127980134843952133">下载记录</translation>
-<translation id="7129052644387688634">通过设置此政策,您可以创建一个网址格式列表,从而指定哪些网站无法显示通知。
-
-      如果您未设置此政策,那么,倘若 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> 已设置,系统便会将它应用于所有网站,否则就会应用用户的个人设置。
-
-      如需详细了解有效的 <ph name="URL_LABEL" /> 格式,请访问 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。<ph name="WILDCARD_VALUE" /> 不是此政策可接受的值。</translation>
 <translation id="712963038874313213">提供应在默认 Crostini 容器中执行的 Ansible Playbook。
 
       此政策允许提供 Ansible Playbook 以应用到默认 Crostini 容器,前提是该容器在给定设备上可用且相关政策允许。
@@ -5158,6 +5151,13 @@
 
           指定的政策值应以毫秒为单位,且不得大于屏幕关闭延迟时间(若已设置)和闲置延迟时间。</translation>
 <translation id="7680437377926096177">在用户关闭最后一个窗口时不显示让用户确认退出登录的对话框。</translation>
+<translation id="7681958144280390173">如果此政策已启用,系统会隔离所有网站(每个网站都在自己的进程内运行)。请注意,从 <ph name="PRODUCT_NAME" /> 版本 77 起,Android 会在默认情况下隔离某些敏感网站,并且此政策会扩展该默认网站隔离模式,以将其应用于所有网站。
+
+      如果将此政策设为停用,系统会关闭所有形式的网站隔离功能,包括隔离敏感网站、IsolateOriginsAndroid 和 SitePerProcessAndroid 的现场试验,以及其他网站隔离模式。不过,用户仍可以手动开启此政策。
+
+      如果您未设置此政策,用户便能更改此设置。
+
+      注意:对在 Android 设备上隔离每个网站的支持将会不断完善,但目前它可能会导致性能问题,尤其是在低端设备上。此政策仅适用于在符合条件(RAM 不小于 1 GB)的设备上运行的 Android 版 Chrome。如果想要既隔离特定网站,又减少给用户带来的性能影响,请使用 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 来指定您想隔离的一系列网站。如需在非 Android 平台上应用此政策,请改用 <ph name="SITE_PER_PROCESS_POLICY_NAME" />。</translation>
 <translation id="7683777542468165012">动态政策刷新</translation>
 <translation id="7687943045976362719">如果设置了此政策,则指定的内容类型由 <ph name="PRODUCT_FRAME_NAME" />处理。
 
@@ -5860,6 +5860,7 @@
       如果您未设置此政策,“新标签页”页面会在 Chrome 启动时打开。
 
       在 <ph name="MS_WIN_NAME" /> 上,此功能仅适用于已加入 <ph name="MS_AD_NAME" /> 网域的实例、在 Windows 10 专业版上运行的实例,或已注册 <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />的实例。在 <ph name="MAC_OS_NAME" /> 上,此功能仅适用于通过 MDM 进行管理或通过 MCX 加入网域的实例。</translation>
+<translation id="8671119576957984818">启用桌面分享中心</translation>
 <translation id="8672321184841719703">目标自动更新版本</translation>
 <translation id="867410340948518937">U2F(通用第二重因素)</translation>
 <translation id="8676959842615154675">如果此政策已启用,远程访问主机会对比这两个名称:与主机关联的本地用户的名称,以及注册为主机所有者的 Google 帐号的名称(如果主机归“johndoe@example.com”所有,Google 帐号的名称就是“johndoe”)。如果主机所有者的名称不同于与主机关联的本地用户的名称,该主机将不会启动。若要强制将所有者的 Google 帐号与特定网域关联,请将此政策与 <ph name="REMOTE_ACCESS_HOST_DOMAIN_POLICY_NAME" /> 搭配使用。
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb
index a6ea0c6..07cbe1f 100644
--- a/components/policy/resources/policy_templates_zh-TW.xtb
+++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -3104,11 +3104,6 @@
 <translation id="5078623750797048009">啟用 PDF 註解功能</translation>
 <translation id="5082572440690475059">允許這些網站透過 File System API 進行讀取</translation>
 <translation id="5085647276663819155">停用列印預覽</translation>
-<translation id="5087424855041813182">你可以透過這項政策設定網址模式清單,用於指定可顯示通知的網站。
-
-      如果未設定這項政策,系統會針對所有網站套用 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> 政策 (如果已設定)。否則系統會套用使用者的個人設定。
-
-      想進一步瞭解有效的<ph name="URL_LABEL" />模式,請參閱 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。<ph name="WILDCARD_VALUE" /> 不是這項政策許可的值。</translation>
 <translation id="5090791951240382356">允許合併不同來源的字典政策</translation>
 <translation id="5091315650312105069">允許透過 HTTP 使用<ph name="BASIC_AUTH" />驗證</translation>
 <translation id="5103112931744164177">你可以透過這項政策指定要使用哪一個軟體堆疊與 DNS 伺服器進行通訊,選項包括作業系統 DNS 用戶端,以及 <ph name="PRODUCT_NAME" /> 的內建 DNS 用戶端。這項政策不會影響所用的 DNS 伺服器;比方說,如果作業系統設定使用企業的 DNS 伺服器,內建 DNS 用戶端同樣會使用該伺服器。這項政策也不會限制是否使用 DNS-over-HTTPS;<ph name="PRODUCT_NAME" /> 一律會使用內建的解析器來處理 DNS-over-HTTPS 要求。想瞭解如何控管 DNS-over-HTTPS,請參閱 <ph name="DNS_OVER_HTTPS_MODE_POLICY_NAME" /> 政策。
@@ -4414,26 +4409,6 @@
 
           注意:如果指定 <ph name="DEVICE_LOGIN_SCREEN_HIGH_CONTRAST_ENABLED_POLICY_NAME" />,這項政策會遭到覆寫。</translation>
 <translation id="6833988859168635883">起始頁面、首頁和新分頁</translation>
-<translation id="6834298774555537368">你可以透過這項政策,設定 Chrome 和 ARC 應用程式的 Proxy 設定,系統會忽略所有從指令列所指定的 Proxy 相關選項。
-
-       如果不設定這項政策,使用者就能選擇要使用的 Proxy 設定。
-
-      設定 <ph name="PROXY_SETTINGS_POLICY_NAME" /> 政策時,可使用下列欄位:
-         * <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> 可讓你指定 Chrome 要使用的 Proxy 伺服器,並禁止使用者變更 Proxy 設定
-         * <ph name="PROXY_PAC_URL_PROXY_SETTINGS_FIELD" /> 是 Proxy .pac 檔案的網址
-         * <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> 是 Proxy 伺服器的網址
-         * <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 是會略過的 Proxy 主機清單
-
-       <ph name="PROXY_SERVER_MODE_PROXY_SETTINGS_FIELD" /> 欄位已遭淘汰,請改用 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> 欄位。
-
-        如果將 <ph name="PROXY_MODE_PROXY_SETTINGS_FIELD" /> 的值設為:
-          * <ph name="PROXY_MODE_ENUM_DIRECT" />:Chrome 一律不會使用 Proxy,且會忽略所有其他欄位。
-          * <ph name="PROXY_MODE_ENUM_SYSTEM" />:Chrome 會使用系統 Proxy,並忽略所有其他欄位。
-          * <ph name="PROXY_MODE_ENUM_AUTO_DETECT" />:Chrome 會忽略所有其他欄位。
-          * <ph name="PROXY_MODE_ENUM_FIXED_SERVERS" />:Chrome 會使用 <ph name="PROXY_SERVER_PROXY_SETTINGS_FIELD" /> 和 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 欄位。
-          * <ph name="PROXY_MODE_ENUM_PAC_SCRIPT" />:Chrome 會使用 <ph name="PROXY_BYPASS_LIST_PROXY_PAC_URL" /> 和 <ph name="PROXY_BYPASS_LIST_PROXY_SETTINGS_FIELD" /> 欄位。
-
-      注意:如需詳細範例,請前往 Chromium 計畫 (網址為 https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-sett)。</translation>
 <translation id="6835883744948188639">顯示週期性提示,建議使用者重新啟動瀏覽器</translation>
 <translation id="683688607121170501">如果啟用這項設定,當使用者登入 <ph name="PRODUCT_OS_NAME" />裝置後,將可在瀏覽器視窗的內容區域和 Android 應用程式中切換 Google 帳戶。
 
@@ -4736,11 +4711,6 @@
 <translation id="7126928806195745404">JavaScript 設定</translation>
 <translation id="7127892035367404455">復原至目標版本</translation>
 <translation id="7127980134843952133">下載記錄</translation>
-<translation id="7129052644387688634">你可以透過這項政策設定網址模式清單,用於指定無法顯示通知的網站。
-
-      如果未設定這項政策,系統會針對所有網站套用 <ph name="DEFAULT_JAVA_SCRIPT_SETTING_POLICY_NAME" /> 政策 (如果已設定)。否則系統會套用使用者的個人設定。
-
-      想進一步瞭解有效的<ph name="URL_LABEL" />模式,請參閱 https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns。<ph name="WILDCARD_VALUE" /> 不是這項政策許可的值。</translation>
 <translation id="712963038874313213">提供應在預設 Crostini 容器中執行的 Ansible Playbook。
 
       這項政策允許你提供要套用至預設 Crostini 容器的 Ansible Playbook (如果指定裝置可使用該容器,且政策允許)。
diff --git a/components/prefs/pref_value_map_unittest.cc b/components/prefs/pref_value_map_unittest.cc
index 07bd5e1..234a76c 100644
--- a/components/prefs/pref_value_map_unittest.cc
+++ b/components/prefs/pref_value_map_unittest.cc
@@ -43,9 +43,7 @@
 
   const Value* result = nullptr;
   ASSERT_TRUE(map.GetValue("key", &result));
-  double double_value = 0.;
-  EXPECT_TRUE(result->GetAsDouble(&double_value));
-  EXPECT_DOUBLE_EQ(5.5, double_value);
+  EXPECT_DOUBLE_EQ(5.5, result->GetDouble());
 }
 
 TEST(PrefValueMapTest, RemoveValue) {
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index 2427d22d..ba50faa 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -114,6 +114,8 @@
 
 const char kPageSetupScriptFormat[] = "setupHeaderFooterTemplate(%s);";
 
+constexpr int kAllowedIpcDepthForPrint = 1;
+
 void ExecuteScript(blink::WebLocalFrame* frame,
                    const char* script_format,
                    const base::Value& parameters) {
@@ -632,6 +634,43 @@
   return view_;
 }
 
+ClosuresForMojoResponse::ClosuresForMojoResponse() = default;
+
+ClosuresForMojoResponse::~ClosuresForMojoResponse() {
+  RunScriptedPrintPreviewQuitClosure();
+  RunPrintSettingFromUserQuitClosure();
+}
+
+void ClosuresForMojoResponse::SetScriptedPrintPreviewQuitClosure(
+    base::OnceClosure quit_print_preview) {
+  DCHECK(!scripted_print_preview_quit_closure_);
+  scripted_print_preview_quit_closure_ = std::move(quit_print_preview);
+}
+
+bool ClosuresForMojoResponse::HasScriptedPrintPreviewQuitClosure() const {
+  return !scripted_print_preview_quit_closure_.is_null();
+}
+
+void ClosuresForMojoResponse::RunScriptedPrintPreviewQuitClosure() {
+  if (!scripted_print_preview_quit_closure_)
+    return;
+
+  std::move(scripted_print_preview_quit_closure_).Run();
+}
+
+void ClosuresForMojoResponse::SetPrintSettingFromUserQuitClosure(
+    base::OnceClosure quit_print_setting) {
+  DCHECK(!get_print_settings_from_user_quit_closure_);
+  get_print_settings_from_user_quit_closure_ = std::move(quit_print_setting);
+}
+
+void ClosuresForMojoResponse::RunPrintSettingFromUserQuitClosure() {
+  if (!get_print_settings_from_user_quit_closure_)
+    return;
+
+  std::move(get_print_settings_from_user_quit_closure_).Run();
+}
+
 // static
 double PrintRenderFrameHelper::GetScaleFactor(double input_scale_factor,
                                               bool is_pdf) {
@@ -1088,7 +1127,9 @@
     std::unique_ptr<Delegate> delegate)
     : content::RenderFrameObserver(render_frame),
       content::RenderFrameObserverTracker<PrintRenderFrameHelper>(render_frame),
-      delegate_(std::move(delegate)) {
+      delegate_(std::move(delegate)),
+      closures_for_mojo_responses_(
+          base::MakeRefCounted<ClosuresForMojoResponse>()) {
   if (!delegate_->IsPrintPreviewEnabled())
     DisablePreview();
 
@@ -1208,7 +1249,7 @@
 
 void PrintRenderFrameHelper::PrintRequestedPages() {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
 
   blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
@@ -1232,16 +1273,16 @@
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
 void PrintRenderFrameHelper::PrintForSystemDialog() {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
 
-  if (scripted_print_preview_quit_closure_) {
+  if (closures_for_mojo_responses_->HasScriptedPrintPreviewQuitClosure()) {
     // If an in-progress print preview already created a nested loop, avoid
     // creating yet another nested loop. Instead, quit the current nested loop,
     // and call this method again.
     DCHECK(!do_deferred_print_for_system_dialog_);
     do_deferred_print_for_system_dialog_ = true;
-    std::move(scripted_print_preview_quit_closure_).Run();
+    closures_for_mojo_responses_->RunScriptedPrintPreviewQuitClosure();
     return;
   }
 
@@ -1271,7 +1312,7 @@
     mojo::PendingAssociatedRemote<mojom::PrintRenderer> print_renderer,
     bool has_selection) {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
 
   if (print_renderer) {
@@ -1296,7 +1337,7 @@
 
 void PrintRenderFrameHelper::PrintPreview(base::Value settings) {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
 
   print_preview_context_.OnPrintPreview();
@@ -1356,7 +1397,7 @@
     mojom::PrintFrameContentParamsPtr params,
     PrintFrameContentCallback callback) {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
 
   // If the last request is not finished yet, do not proceed.
@@ -1429,7 +1470,7 @@
 
 void PrintRenderFrameHelper::PrintingDone(bool success) {
   ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
-  if (ipc_nesting_level_ > 1)
+  if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
     return;
   notify_browser_of_print_failure_ = false;
   DidFinishPrinting(success ? OK : FAIL_PRINT);
@@ -2290,7 +2331,8 @@
 
   mojom::PrintPagesParamsPtr print_settings;
   base::RunLoop loop{base::RunLoop::Type::kNestableTasksAllowed};
-  get_print_settings_from_user_quit_closure_ = loop.QuitClosure();
+  closures_for_mojo_responses_->SetPrintSettingFromUserQuitClosure(
+      loop.QuitClosure());
   GetPrintManagerHost()->ScriptedPrint(
       std::move(params),
       base::BindOnce(
@@ -2458,10 +2500,11 @@
                            weak_ptr_factory_.GetWeakPtr()));
       }
       base::RunLoop loop{base::RunLoop::Type::kNestableTasksAllowed};
-      scripted_print_preview_quit_closure_ = loop.QuitClosure();
+      closures_for_mojo_responses_->SetScriptedPrintPreviewQuitClosure(
+          loop.QuitClosure());
       GetPrintManagerHost()->SetupScriptedPrintPreview(base::BindOnce(
-          &PrintRenderFrameHelper::QuitScriptedPrintPreviewRunLoop,
-          weak_ptr_factory_.GetWeakPtr()));
+          &ClosuresForMojoResponse::RunScriptedPrintPreviewQuitClosure,
+          closures_for_mojo_responses_));
       loop.Run();
 
       // Check if |this| is still valid.
@@ -2879,13 +2922,11 @@
 }
 
 void PrintRenderFrameHelper::QuitScriptedPrintPreviewRunLoop() {
-  if (scripted_print_preview_quit_closure_)
-    std::move(scripted_print_preview_quit_closure_).Run();
+  closures_for_mojo_responses_->RunScriptedPrintPreviewQuitClosure();
 }
 
 void PrintRenderFrameHelper::QuitGetPrintSettingsFromUserRunLoop() {
-  if (get_print_settings_from_user_quit_closure_)
-    std::move(get_print_settings_from_user_quit_closure_).Run();
+  closures_for_mojo_responses_->RunPrintSettingFromUserQuitClosure();
 }
 
 PrintRenderFrameHelper::ScopedIPC::ScopedIPC(
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index dd23fe0..9023692 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -11,6 +11,8 @@
 #include "base/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/read_only_shared_memory_region.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -84,6 +86,29 @@
   blink::WebLocalFrame* frame_;
 };
 
+// Helper to ensure that quit closures for Mojo response are called.
+class ClosuresForMojoResponse
+    : public base::RefCounted<ClosuresForMojoResponse> {
+ public:
+  ClosuresForMojoResponse();
+  ClosuresForMojoResponse(const ClosuresForMojoResponse&) = delete;
+  ClosuresForMojoResponse& operator=(const ClosuresForMojoResponse&) = delete;
+
+  void SetScriptedPrintPreviewQuitClosure(base::OnceClosure quit_print_preview);
+  bool HasScriptedPrintPreviewQuitClosure() const;
+  void RunScriptedPrintPreviewQuitClosure();
+  void SetPrintSettingFromUserQuitClosure(base::OnceClosure quit_print_setting);
+  void RunPrintSettingFromUserQuitClosure();
+
+ private:
+  friend class base::RefCounted<ClosuresForMojoResponse>;
+  ~ClosuresForMojoResponse();
+
+  // Stores quit closures for the runloops that are waiting for Mojo replies.
+  base::OnceClosure scripted_print_preview_quit_closure_;
+  base::OnceClosure get_print_settings_from_user_quit_closure_;
+};
+
 // PrintRenderFrameHelper handles most of the printing grunt work for
 // RenderView. We plan on making print asynchronous and that will require
 // copying the DOM of the document and creating a new WebView with the contents.
@@ -657,9 +682,8 @@
   // parameters so that it can be invoked after DidStopLoading.
   base::OnceClosure on_stop_loading_closure_;
 
-  // Stores quit closures for the runloops that are waiting for Mojo replies.
-  base::OnceClosure scripted_print_preview_quit_closure_;
-  base::OnceClosure get_print_settings_from_user_quit_closure_;
+  // Stores the quit closures of Mojo responses.
+  scoped_refptr<ClosuresForMojoResponse> closures_for_mojo_responses_;
 
   bool do_deferred_print_for_system_dialog_ = false;
 
diff --git a/components/reporting/compression/compression_module.cc b/components/reporting/compression/compression_module.cc
index b9b4ea1..48e3c3cc 100644
--- a/components/reporting/compression/compression_module.cc
+++ b/components/reporting/compression/compression_module.cc
@@ -16,11 +16,9 @@
 
 namespace reporting {
 
-// TODO(b/189130411): Make this feature default enabled once it has been fully
-// tested and available for launch.
 const base::Feature kCompressReportingPipeline{
     CompressionModule::kCompressReportingFeature,
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 
 // static
 const char CompressionModule::kCompressReportingFeature[] =
@@ -103,10 +101,10 @@
 }
 
 CompressionModule::CompressionModule(
-    uint64_t compression_threshold_,
-    CompressionInformation::CompressionAlgorithm compression_type_)
-    : compression_type_(compression_type_),
-      compression_threshold_(compression_threshold_) {}
+    uint64_t compression_threshold,
+    CompressionInformation::CompressionAlgorithm compression_type)
+    : compression_type_(compression_type),
+      compression_threshold_(compression_threshold) {}
 CompressionModule::~CompressionModule() = default;
 
 void CompressionModule::CompressRecordSnappy(
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc
index cd99c8c..6d7f9bbb 100644
--- a/components/reporting/storage/storage_queue.cc
+++ b/components/reporting/storage/storage_queue.cc
@@ -136,11 +136,11 @@
     scoped_refptr<EncryptionModuleInterface> encryption_module,
     scoped_refptr<CompressionModule> compression_module)
     : base::RefCountedDeleteOnSequence<StorageQueue>(sequenced_task_runner),
+      sequenced_task_runner_(std::move(sequenced_task_runner)),
       options_(options),
       async_start_upload_cb_(async_start_upload_cb),
       encryption_module_(encryption_module),
-      compression_module_(compression_module),
-      sequenced_task_runner_(std::move(sequenced_task_runner)) {
+      compression_module_(compression_module) {
   DETACH_FROM_SEQUENCE(storage_queue_sequence_checker_);
   DCHECK(write_contexts_queue_.empty());
 }
@@ -674,7 +674,7 @@
         must_invoke_upload_(
             EncryptionModuleInterface::is_enabled() &&
             storage_queue->encryption_module_->need_encryption_key()),
-        storage_queue_weakptr_factory_{storage_queue.get()} {
+        storage_queue_(storage_queue->weakptr_factory_.GetWeakPtr()) {
     DCHECK(storage_queue.get());
     DCHECK(async_start_upload_cb_);
     DETACH_FROM_SEQUENCE(read_sequence_checker_);
@@ -686,9 +686,7 @@
 
   void OnStart() override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
-    base::WeakPtr<StorageQueue> storage_queue =
-        storage_queue_weakptr_factory_.GetWeakPtr();
-    if (!storage_queue) {
+    if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
     }
@@ -703,27 +701,26 @@
 
   void PrepareDataFiles() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
-    base::WeakPtr<StorageQueue> storage_queue =
-        storage_queue_weakptr_factory_.GetWeakPtr();
-    if (!storage_queue) {
+    if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
     }
+
     // Fill in initial sequencing information to track progress:
     // use minimum of first_sequencing_id_ and first_unconfirmed_sequencing_id_
     // if the latter has been recorded.
-    sequencing_info_.set_generation_id(storage_queue->generation_id_);
-    if (storage_queue->first_unconfirmed_sequencing_id_.has_value()) {
+    sequencing_info_.set_generation_id(storage_queue_->generation_id_);
+    if (storage_queue_->first_unconfirmed_sequencing_id_.has_value()) {
       sequencing_info_.set_sequencing_id(
-          std::min(storage_queue->first_unconfirmed_sequencing_id_.value(),
-                   storage_queue->first_sequencing_id_));
+          std::min(storage_queue_->first_unconfirmed_sequencing_id_.value(),
+                   storage_queue_->first_sequencing_id_));
     } else {
-      sequencing_info_.set_sequencing_id(storage_queue->first_sequencing_id_);
+      sequencing_info_.set_sequencing_id(storage_queue_->first_sequencing_id_);
     }
 
     // If there are no files in the queue, do nothing and return success right
     // away. This can happen in case of key delivery request.
-    if (storage_queue->files_.empty()) {
+    if (storage_queue_->files_.empty()) {
       Response(Status::StatusOK());
       return;
     }
@@ -731,7 +728,7 @@
     // If the last file is not empty (has at least one record),
     // close it and create the new one, so that its records are
     // also included in the reading.
-    const Status last_status = storage_queue->SwitchLastFileIfNotEmpty();
+    const Status last_status = storage_queue_->SwitchLastFileIfNotEmpty();
     if (!last_status.ok()) {
       Response(last_status);
       return;
@@ -740,7 +737,7 @@
     // Collect and set aside the files in the set that might have data
     // for the Upload.
     files_ =
-        storage_queue->CollectFilesForUpload(sequencing_info_.sequencing_id());
+        storage_queue_->CollectFilesForUpload(sequencing_info_.sequencing_id());
     if (files_.empty()) {
       Response(Status(error::OUT_OF_RANGE,
                       "Sequencing id not found in StorageQueue."));
@@ -748,7 +745,7 @@
     }
 
     // Register with storage_queue, to make sure selected files are not removed.
-    ++(storage_queue->active_read_operations_);
+    ++(storage_queue_->active_read_operations_);
 
     if (uploader_) {
       // Uploader already created.
@@ -762,9 +759,7 @@
 
   void BeginUploading() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
-    base::WeakPtr<StorageQueue> storage_queue =
-        storage_queue_weakptr_factory_.GetWeakPtr();
-    if (!storage_queue) {
+    if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
     }
@@ -783,15 +778,15 @@
       return;
     }
 
-    StartUploading(storage_queue);
+    StartUploading();
   }
 
-  void StartUploading(base::WeakPtr<StorageQueue> storage_queue) {
+  void StartUploading() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
     // Read from it until the specified sequencing id is found.
     for (int64_t sequencing_id = current_file_->first;
          sequencing_id < sequencing_info_.sequencing_id(); ++sequencing_id) {
-      auto blob = EnsureBlob(storage_queue, sequencing_id);
+      auto blob = EnsureBlob(sequencing_id);
       if (blob.status().error_code() == error::OUT_OF_RANGE) {
         // Reached end of file, switch to the next one (if present).
         ++current_file_;
@@ -800,7 +795,7 @@
           return;
         }
         current_pos_ = 0;
-        blob = EnsureBlob(storage_queue, sequencing_info_.sequencing_id());
+        blob = EnsureBlob(sequencing_info_.sequencing_id());
       }
       if (!blob.ok()) {
         // File found to be corrupt. Produce Gap record till the start of next
@@ -818,7 +813,7 @@
     }
 
     // Read and upload sequencing_info_.sequencing_id().
-    CallRecordOrGap(storage_queue, sequencing_info_.sequencing_id());
+    CallRecordOrGap(sequencing_info_.sequencing_id());
     // Resume at ScheduleNextRecord.
   }
 
@@ -828,16 +823,16 @@
     if (uploader_) {
       uploader_->Completed(status);
     }
-    // If upload failed, retry it after a delay (if any).
-    if (!status.ok()) {
-      base::WeakPtr<StorageQueue> storage_queue =
-          storage_queue_weakptr_factory_.GetWeakPtr();
-      if (storage_queue &&
-          !storage_queue->options_.upload_retry_delay().is_zero()) {
-        ScheduleAfter(
-            storage_queue->options_.upload_retry_delay(),
-            base::BindOnce(&StorageQueue::Flush, storage_queue.get()));
-      }
+    // If retry delay is specified, check back after the delay.
+    // If the status was error, or if any events are still there,
+    // retry the upload.
+    if (storage_queue_ &&
+        !storage_queue_->options_.upload_retry_delay().is_zero()) {
+      ScheduleAfter(
+          storage_queue_->options_.upload_retry_delay(),
+          base::BindOnce(
+              &StorageQueue::CheckBackUpload, storage_queue_, status,
+              /*next_sequencing_id=*/sequencing_info_.sequencing_id()));
     }
   }
 
@@ -845,10 +840,8 @@
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
     // Unregister with storage_queue.
     if (!files_.empty()) {
-      base::WeakPtr<StorageQueue> storage_queue =
-          storage_queue_weakptr_factory_.GetWeakPtr();
-      if (storage_queue) {
-        const auto count = --(storage_queue->active_read_operations_);
+      if (storage_queue_) {
+        const auto count = --(storage_queue_->active_read_operations_);
         DCHECK_GE(count, 0);
       }
     }
@@ -924,9 +917,7 @@
       Response(Status::StatusOK());  // Requested to stop reading.
       return;
     }
-    base::WeakPtr<StorageQueue> storage_queue =
-        storage_queue_weakptr_factory_.GetWeakPtr();
-    if (!storage_queue) {
+    if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
     }
@@ -936,7 +927,7 @@
       return;
     }
     // sequencing_info_.sequencing_id() blob is ready.
-    CallRecordOrGap(storage_queue, sequencing_info_.sequencing_id());
+    CallRecordOrGap(sequencing_info_.sequencing_id());
     // Resume at ScheduleNextRecord.
   }
 
@@ -947,14 +938,15 @@
   // the buffer remains intact until the next call to SingleFile::Read.
   // If anything goes wrong (file is shorter than expected, or record hash does
   // not match), returns error.
-  StatusOr<base::StringPiece> EnsureBlob(
-      base::WeakPtr<StorageQueue> storage_queue,
-      int64_t sequencing_id) {
+  StatusOr<base::StringPiece> EnsureBlob(int64_t sequencing_id) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    if (!storage_queue_) {
+      return Status(error::UNAVAILABLE, "StorageQueue shut down");
+    }
 
     // Test only: simulate error, if requested.
-    if (storage_queue->test_injected_fail_sequencing_ids_.count(sequencing_id) >
-        0) {
+    if (storage_queue_->test_injected_fail_sequencing_ids_.count(
+            sequencing_id) > 0) {
       return Status(error::INTERNAL,
                     base::StrCat({"Simulated failure, seq=",
                                   base::NumberToString(sequencing_id)}));
@@ -963,7 +955,7 @@
     // Read from the current file at the current offset.
     RETURN_IF_ERROR(current_file_->second->Open(/*read_only=*/true));
     const size_t max_buffer_size =
-        RoundUpToFrameSize(storage_queue->options_.max_record_size()) +
+        RoundUpToFrameSize(storage_queue_->options_.max_record_size()) +
         RoundUpToFrameSize(sizeof(RecordHeader));
     auto read_result = current_file_->second->Read(
         current_pos_, sizeof(RecordHeader), max_buffer_size);
@@ -1029,9 +1021,13 @@
     return read_result.ValueOrDie().substr(0, header.record_size);
   }
 
-  void CallRecordOrGap(base::WeakPtr<StorageQueue> storage_queue,
-                       int64_t sequencing_id) {
-    auto blob = EnsureBlob(storage_queue, sequencing_info_.sequencing_id());
+  void CallRecordOrGap(int64_t sequencing_id) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    if (!storage_queue_) {
+      Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
+      return;
+    }
+    auto blob = EnsureBlob(sequencing_info_.sequencing_id());
     if (blob.status().error_code() == error::OUT_OF_RANGE) {
       // Reached end of file, switch to the next one (if present).
       ++current_file_;
@@ -1040,7 +1036,7 @@
         return;
       }
       current_pos_ = 0;
-      blob = EnsureBlob(storage_queue, sequencing_info_.sequencing_id());
+      blob = EnsureBlob(sequencing_info_.sequencing_id());
     }
     if (!blob.ok()) {
       // File found to be corrupt. Produce Gap record till the start of next
@@ -1104,7 +1100,7 @@
   const AsyncStartUploaderCb async_start_upload_cb_;
   const bool must_invoke_upload_;
   std::unique_ptr<UploaderInterface> uploader_;
-  base::WeakPtrFactory<StorageQueue> storage_queue_weakptr_factory_;
+  base::WeakPtr<StorageQueue> storage_queue_;
 
   SEQUENCE_CHECKER(read_sequence_checker_);
 };
@@ -1504,6 +1500,24 @@
   return Status::StatusOK();
 }
 
+void StorageQueue::CheckBackUpload(Status status, int64_t next_sequencing_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(storage_queue_sequence_checker_);
+  if (!status.ok()) {
+    // Previous upload failed, retry.
+    Flush();
+    return;
+  }
+
+  if (!first_unconfirmed_sequencing_id_.has_value() ||
+      first_unconfirmed_sequencing_id_.value() < next_sequencing_id) {
+    // Not all uploaded events were confirmed after upload, retry.
+    Flush();
+    return;
+  }
+
+  // No need to retry.
+}
+
 void StorageQueue::Flush() {
   // Note: new uploader created every time Flush is called.
   Start<ReadContext>(this);
diff --git a/components/reporting/storage/storage_queue.h b/components/reporting/storage/storage_queue.h
index 01a93889..281833b 100644
--- a/components/reporting/storage/storage_queue.h
+++ b/components/reporting/storage/storage_queue.h
@@ -289,6 +289,15 @@
   // Files on the disk remain as they were.
   void ReleaseAllFileInstances();
 
+  // Helper method to retry upload if prior one failed or if some events below
+  // |next_sequencing_id| were not uploaded.
+  void CheckBackUpload(Status status, int64_t next_sequencing_id);
+
+  // Sequential task runner for all activities in this StorageQueue
+  // (must be first member in class).
+  scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
+  SEQUENCE_CHECKER(storage_queue_sequence_checker_);
+
   // Immutable options, stored at the time of creation.
   const QueueOptions options_;
 
@@ -351,10 +360,8 @@
   // Test only: records specified to fail on reading.
   base::flat_set<int64_t> test_injected_fail_sequencing_ids_;
 
-  // Sequential task runner for all activities in this StorageQueue.
-  scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
-
-  SEQUENCE_CHECKER(storage_queue_sequence_checker_);
+  // Weak pointer factory (must be last member in class).
+  base::WeakPtrFactory<StorageQueue> weakptr_factory_{this};
 };
 
 }  // namespace reporting
diff --git a/components/reporting/storage/storage_queue_stress_test.cc b/components/reporting/storage/storage_queue_stress_test.cc
index c8f9aa4..7baff9f 100644
--- a/components/reporting/storage/storage_queue_stress_test.cc
+++ b/components/reporting/storage/storage_queue_stress_test.cc
@@ -45,7 +45,7 @@
 namespace reporting {
 namespace {
 
-constexpr int kCompressionThreshold = 512;
+constexpr size_t kCompressionThreshold = 512;
 constexpr size_t kTotalQueueStarts = 4;
 constexpr size_t kTotalWritesPerStart = 16;
 constexpr char kDataPrefix[] = "Rec";
diff --git a/components/reporting/storage/storage_queue_unittest.cc b/components/reporting/storage/storage_queue_unittest.cc
index 2f1617d..38514f8d 100644
--- a/components/reporting/storage/storage_queue_unittest.cc
+++ b/components/reporting/storage/storage_queue_unittest.cc
@@ -46,7 +46,7 @@
 
 // Metadata file name prefix.
 const base::FilePath::CharType METADATA_NAME[] = FILE_PATH_LITERAL("META");
-constexpr int kCompressionThreshold = 512;
+constexpr size_t kCompressionThreshold = 512;
 
 class MockUploadClient : public ::testing::NiceMock<UploaderInterface> {
  public:
@@ -279,12 +279,6 @@
         .set_single_file_size(GetParam());
   }
 
-  void EnableCompression() {
-    // TODO(b/189130411) Remove once compression is enabled by default.
-    scoped_feature_list_.InitFromCommandLine(
-        {CompressionModule::kCompressReportingFeature}, {});
-  }
-
   void TearDown() override {
     ResetTestStorageQueue();
     // Make sure all memory is deallocated.
@@ -1194,6 +1188,43 @@
   }
 }
 
+TEST_P(StorageQueueTest, WriteAndImmediateUploadWithoutConfirmation) {
+  CreateTestStorageQueueOrDie(BuildStorageQueueOptionsImmediate());
+
+  // Write a record as Immediate, initiating an upload which fails
+  // and then restarts.
+  {
+    test::TestCallbackAutoWaiter waiter;
+    EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
+        .WillOnce(Invoke([&waiter](MockUploadClient* mock_upload_client) {
+          MockUploadClient::SetUp(mock_upload_client, &waiter)
+              .Required(0, kData[0]);
+          return Status::StatusOK();
+        }))
+        .WillRepeatedly(Invoke(&DoNotUpload));
+    WriteStringOrDie(kData[0]);  // Immediately uploads and does not confirm.
+  }
+
+  // Let it retry upload and verify.
+  {
+    test::TestCallbackAutoWaiter waiter;
+    EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull()))
+        .WillOnce(Invoke([&waiter](MockUploadClient* mock_upload_client) {
+          MockUploadClient::SetUp(mock_upload_client, &waiter)
+              .Required(0, kData[0]);
+          return Status::StatusOK();
+        }))
+        .WillRepeatedly(Invoke(&DoNotUpload));
+    task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+  }
+
+  // Confirm 0 and make sure no retry happens (since everything is confirmed).
+  EXPECT_CALL(set_mock_uploader_expectations_, Call(NotNull())).Times(0);
+
+  ConfirmOrDie(/*sequencing_id=*/0);
+  task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+}
+
 TEST_P(StorageQueueTest, WriteEncryptFailure) {
   CreateTestStorageQueueOrDie(BuildStorageQueueOptionsPeriodic());
   DCHECK(test_encryption_module_);
@@ -1208,7 +1239,6 @@
 }
 
 TEST_P(StorageQueueTest, EnableCompression) {
-  EnableCompression();
   CreateTestStorageQueueOrDie(BuildStorageQueueOptionsPeriodic());
   WriteStringOrDie(kData[0]);
   WriteStringOrDie(kData[1]);
diff --git a/components/reporting/storage/storage_unittest.cc b/components/reporting/storage/storage_unittest.cc
index 8db5fe90..c9e7624c 100644
--- a/components/reporting/storage/storage_unittest.cc
+++ b/components/reporting/storage/storage_unittest.cc
@@ -55,7 +55,7 @@
 namespace reporting {
 namespace {
 
-constexpr int kCompressionThreshold = 512;
+constexpr size_t kCompressionThreshold = 512;
 
 // Context of single decryption. Self-destructs upon completion or failure.
 class SingleDecryptionContext {
@@ -848,6 +848,9 @@
     EXPECT_OK(storage_->Flush(MANUAL_BATCH));
   }
 
+  // Confirm written data to prevent upload retry.
+  ConfirmOrDie(MANUAL_BATCH, /*sequencing_id=*/2);
+
   // Write more data.
   WriteStringOrDie(MANUAL_BATCH, kMoreData[0]);
   WriteStringOrDie(MANUAL_BATCH, kMoreData[1]);
@@ -864,9 +867,6 @@
       .WillOnce(
           WithArg<1>(Invoke([&waiter](MockUploadClient* mock_upload_client) {
             MockUploadClient::SetUp(MANUAL_BATCH, mock_upload_client, &waiter)
-                .Required(0, kData[0])
-                .Required(1, kData[1])
-                .Required(2, kData[2])
                 .Required(3, kMoreData[0])
                 .Required(4, kMoreData[1])
                 .Required(5, kMoreData[2]);
@@ -1275,6 +1275,9 @@
 
   WriteStringOrDie(SLOW_BATCH, kMoreData[1]);
 
+  // Confirm #1 IMMEDIATE, removing data #0 and #1, to prevent upload retry.
+  ConfirmOrDie(IMMEDIATE, /*sequencing_id=*/1);
+
   // Set uploader expectations for FAST_BATCH and SLOW_BATCH.
   {
     test::TestCallbackAutoWaiter waiter;
@@ -1294,9 +1297,6 @@
   // Confirm #0 SLOW_BATCH, removing data #0
   ConfirmOrDie(SLOW_BATCH, /*sequencing_id=*/0);
 
-  // Confirm #1 IMMEDIATE, removing data #0 and #1
-  ConfirmOrDie(IMMEDIATE, /*sequencing_id=*/1);
-
   // Add more data
   {
     test::TestCallbackAutoWaiter waiter;
@@ -1305,7 +1305,6 @@
         .WillOnce(
             WithArg<1>(Invoke([&waiter](MockUploadClient* mock_upload_client) {
               MockUploadClient::SetUp(IMMEDIATE, mock_upload_client, &waiter)
-                  .Possible(1, kData[1])
                   .Required(2, kData[2]);
               return Status::StatusOK();
             })))
@@ -1314,6 +1313,9 @@
   }
   WriteStringOrDie(SLOW_BATCH, kMoreData[2]);
 
+  // Confirm #2 IMMEDIATE, to prevent upload retry.
+  ConfirmOrDie(IMMEDIATE, /*sequencing_id=*/2);
+
   // Set uploader expectations for FAST_BATCH and SLOW_BATCH.
   {
     test::TestCallbackAutoWaiter waiter;
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn
index 5947ad2..efbac60 100644
--- a/components/safe_browsing/content/browser/BUILD.gn
+++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/features.gni")
+import("//components/safe_browsing/buildflags.gni")
 
 # NOTE: This target is separated from :browser as
 # //components/safe_browsing/content/browser/web_ui, which :browser depends on, depends
@@ -34,6 +35,8 @@
     "mojo_safe_browsing_impl.h",
     "safe_browsing_controller_client.cc",
     "safe_browsing_controller_client.h",
+    "safe_browsing_metrics_collector.cc",
+    "safe_browsing_metrics_collector.h",
     "safe_browsing_network_context.cc",
     "safe_browsing_network_context.h",
     "threat_details.cc",
@@ -50,6 +53,7 @@
     "//base:i18n",
     "//components/back_forward_cache",
     "//components/history/core/browser",
+    "//components/prefs",
     "//components/safe_browsing/content/browser/web_ui:web_ui",
     "//components/safe_browsing/content/common",
     "//components/safe_browsing/content/common:interfaces",
@@ -123,6 +127,15 @@
     "//testing/gmock",
     "//testing/gtest",
   ]
+
+  if (safe_browsing_mode > 0) {
+    sources += [ "safe_browsing_metrics_collector_unittest.cc" ]
+    deps += [
+      "//components/prefs",
+      "//components/prefs:test_support",
+      "//components/safe_browsing/core/common:safe_browsing_prefs",
+    ]
+  }
 }
 
 source_set("client_side_detection") {
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc b/components/safe_browsing/content/browser/safe_browsing_metrics_collector.cc
similarity index 98%
rename from chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc
rename to components/safe_browsing/content/browser/safe_browsing_metrics_collector.cc
index 4eeaa47..6a79e03 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_metrics_collector.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h b/components/safe_browsing/content/browser/safe_browsing_metrics_collector.h
similarity index 94%
rename from chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
rename to components/safe_browsing/content/browser/safe_browsing_metrics_collector.h
index 47329d9..8c12c8ee 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector.h
+++ b/components/safe_browsing/content/browser/safe_browsing_metrics_collector.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_H_
-#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_H_
+#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_METRICS_COLLECTOR_H_
+#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_METRICS_COLLECTOR_H_
 
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -136,4 +136,4 @@
 
 }  // namespace safe_browsing
 
-#endif  // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_METRICS_COLLECTOR_H_
+#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_SAFE_BROWSING_METRICS_COLLECTOR_H_
diff --git a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc b/components/safe_browsing/content/browser/safe_browsing_metrics_collector_unittest.cc
similarity index 99%
rename from chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc
rename to components/safe_browsing/content/browser/safe_browsing_metrics_collector_unittest.cc
index 08d9fc77a..7ff87ee 100644
--- a/chrome/browser/safe_browsing/safe_browsing_metrics_collector_unittest.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_metrics_collector_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/safe_browsing/safe_browsing_metrics_collector.h"
+#include "components/safe_browsing/content/browser/safe_browsing_metrics_collector.h"
 #include <memory>
 #include <utility>
 
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc
index 3c2c9ce8..33b51b9b 100644
--- a/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc
+++ b/components/safe_browsing/content/renderer/phishing_classifier/flatbuffer_scorer.cc
@@ -192,7 +192,8 @@
   DCHECK(content::RenderThread::IsMainThread());
   if (visual_tflite_model_.IsValid()) {
     base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE, {base::TaskPriority::BEST_EFFORT},
+        FROM_HERE,
+        {base::TaskPriority::BEST_EFFORT, base::WithBaseSyncPrimitives()},
         base::BindOnce(&ApplyVisualTfLiteModelHelper, bitmap,
                        flatbuffer_model_->tflite_metadata()->input_width(),
                        flatbuffer_model_->tflite_metadata()->input_height(),
@@ -269,4 +270,4 @@
   return thresholds_;
 }
 
-}  // namespace safe_browsing
\ No newline at end of file
+}  // namespace safe_browsing
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc
index b8a5f297..135270b 100644
--- a/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc
+++ b/components/safe_browsing/content/renderer/phishing_classifier/protobuf_scorer.cc
@@ -158,7 +158,8 @@
   DCHECK(content::RenderThread::IsMainThread());
   if (visual_tflite_model_.IsValid()) {
     base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE, {base::TaskPriority::BEST_EFFORT},
+        FROM_HERE,
+        {base::TaskPriority::BEST_EFFORT, base::WithBaseSyncPrimitives()},
         base::BindOnce(&ApplyVisualTfLiteModelHelper, bitmap,
                        model_.tflite_metadata().input_width(),
                        model_.tflite_metadata().input_height(),
@@ -256,4 +257,4 @@
   return rule_score * rule.weight();
 }
 
-}  // namespace safe_browsing
\ No newline at end of file
+}  // namespace safe_browsing
diff --git a/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc b/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc
index 0e803ee8..342cb70 100644
--- a/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc
+++ b/components/safe_browsing/content/renderer/phishing_classifier/scorer.cc
@@ -48,6 +48,10 @@
                       tflite::ops::builtin::Register_MEAN());
   resolver.AddBuiltin(tflite::BuiltinOperator_SOFTMAX,
                       tflite::ops::builtin::Register_SOFTMAX());
+  resolver.AddBuiltin(tflite::BuiltinOperator_DEQUANTIZE,
+                      tflite::ops::builtin::Register_DEQUANTIZE());
+  resolver.AddBuiltin(tflite::BuiltinOperator_QUANTIZE,
+                      tflite::ops::builtin::Register_QUANTIZE());
   return std::make_unique<tflite::MutableOpResolver>(resolver);
 }
 
diff --git a/components/services/app_service/public/cpp/file_handler.cc b/components/services/app_service/public/cpp/file_handler.cc
index 1fdf1b0..fe70cd5 100644
--- a/components/services/app_service/public/cpp/file_handler.cc
+++ b/components/services/app_service/public/cpp/file_handler.cc
@@ -17,6 +17,30 @@
 FileHandler::AcceptEntry::AcceptEntry(const AcceptEntry& accept_entry) =
     default;
 
+base::Value FileHandler::AcceptEntry::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  root.SetStringKey("mime_type", mime_type);
+  base::Value& file_extensions_json =
+      *root.SetKey("file_extensions", base::Value(base::Value::Type::LIST));
+  for (const std::string& file_extension : file_extensions)
+    file_extensions_json.Append(file_extension);
+
+  return root;
+}
+
+base::Value FileHandler::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+
+  root.SetStringKey("action", action.spec());
+  base::Value& accept_json =
+      *root.SetKey("accept", base::Value(base::Value::Type::LIST));
+  for (const AcceptEntry& entry : accept)
+    accept_json.Append(entry.AsDebugValue());
+
+  return root;
+}
+
 std::set<std::string> GetMimeTypesFromFileHandlers(
     const FileHandlers& file_handlers) {
   std::set<std::string> mime_types;
@@ -38,25 +62,6 @@
   return file_extensions;
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const FileHandler::AcceptEntry& accept_entry) {
-  out << "    mime_type: " << accept_entry.mime_type << std::endl;
-  out << "    file_extensions:";
-  for (const auto& file_extension : accept_entry.file_extensions)
-    out << " " << file_extension;
-  out << std::endl;
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const FileHandler& file_handler) {
-  out << "action: " << file_handler.action << std::endl;
-  for (const auto& accept_entry : file_handler.accept) {
-    out << "  accept:" << std::endl;
-    out << accept_entry;
-  }
-  return out;
-}
-
 bool operator==(const FileHandler::AcceptEntry& accept_entry1,
                 const FileHandler::AcceptEntry& accept_entry2) {
   return std::tie(accept_entry1.mime_type, accept_entry1.file_extensions) ==
diff --git a/components/services/app_service/public/cpp/file_handler.h b/components/services/app_service/public/cpp/file_handler.h
index 346a055..992928e 100644
--- a/components/services/app_service/public/cpp/file_handler.h
+++ b/components/services/app_service/public/cpp/file_handler.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/containers/flat_set.h"
+#include "base/values.h"
 #include "url/gurl.h"
 
 namespace apps {
@@ -27,6 +28,8 @@
     ~AcceptEntry();
     AcceptEntry(const AcceptEntry& accept_entry);
 
+    base::Value AsDebugValue() const;
+
     // A MIME type that can be handled by the file handler.
     std::string mime_type;
 
@@ -35,6 +38,8 @@
     base::flat_set<std::string> file_extensions;
   };
 
+  base::Value AsDebugValue() const;
+
   // The URL that will be navigated to when dispatching on a file with a
   // matching MIME type or file extension.
   GURL action;
@@ -54,11 +59,6 @@
 std::set<std::string> GetFileExtensionsFromFileHandlers(
     const FileHandlers& file_handlers);
 
-// For logging and debug purposes.
-std::ostream& operator<<(std::ostream& out,
-                         const FileHandler::AcceptEntry& accept_entry);
-std::ostream& operator<<(std::ostream& out, const FileHandler& file_handler);
-
 bool operator==(const FileHandler::AcceptEntry& accept_entry1,
                 const FileHandler::AcceptEntry& accept_entry2);
 bool operator==(const FileHandler& file_handler1,
diff --git a/components/services/app_service/public/cpp/protocol_handler_info.cc b/components/services/app_service/public/cpp/protocol_handler_info.cc
index aa8c3640..92535881 100644
--- a/components/services/app_service/public/cpp/protocol_handler_info.cc
+++ b/components/services/app_service/public/cpp/protocol_handler_info.cc
@@ -4,8 +4,6 @@
 
 #include "components/services/app_service/public/cpp/protocol_handler_info.h"
 
-#include <ostream>
-
 namespace apps {
 
 ProtocolHandlerInfo::ProtocolHandlerInfo() = default;
@@ -20,9 +18,11 @@
   return handler1.protocol == handler2.protocol && handler1.url == handler2.url;
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const ProtocolHandlerInfo& handler) {
-  return out << "protocol: " << handler.protocol << " url: " << handler.url;
+base::Value ProtocolHandlerInfo::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("protocol", protocol);
+  root.SetStringKey("url", url.spec());
+  return root;
 }
 
 }  // namespace apps
diff --git a/components/services/app_service/public/cpp/protocol_handler_info.h b/components/services/app_service/public/cpp/protocol_handler_info.h
index 5cefeb6..0959404 100644
--- a/components/services/app_service/public/cpp/protocol_handler_info.h
+++ b/components/services/app_service/public/cpp/protocol_handler_info.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "base/values.h"
 #include "url/gurl.h"
 
 namespace apps {
@@ -18,6 +19,8 @@
   ProtocolHandlerInfo(const ProtocolHandlerInfo& other);
   ~ProtocolHandlerInfo();
 
+  base::Value AsDebugValue() const;
+
   std::string protocol;
   GURL url;
 };
@@ -25,7 +28,6 @@
 
 bool operator==(const ProtocolHandlerInfo& handler1,
                 const ProtocolHandlerInfo& handler2);
-std::ostream& operator<<(std::ostream& out, const ProtocolHandlerInfo& handler);
 
 }  // namespace apps
 
diff --git a/components/services/app_service/public/cpp/share_target.cc b/components/services/app_service/public/cpp/share_target.cc
index e8122fa..1b19ed8 100644
--- a/components/services/app_service/public/cpp/share_target.cc
+++ b/components/services/app_service/public/cpp/share_target.cc
@@ -24,6 +24,16 @@
 
 ShareTarget::Files::~Files() = default;
 
+base::Value ShareTarget::Files::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("name", name);
+  base::Value& accept_json =
+      *root.SetKey("accept", base::Value(base::Value::Type::LIST));
+  for (const std::string& entry : accept)
+    accept_json.Append(entry);
+  return root;
+}
+
 ShareTarget::Params::Params() = default;
 
 ShareTarget::Params::Params(const ShareTarget::Params&) = default;
@@ -38,6 +48,18 @@
 
 ShareTarget::Params::~Params() = default;
 
+base::Value ShareTarget::Params::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("title", title);
+  root.SetStringKey("text", text);
+  root.SetStringKey("url", url);
+  base::Value& files_json =
+      *root.SetKey("files", base::Value(base::Value::Type::LIST));
+  for (const auto& files_entry : files)
+    files_json.Append(files_entry.AsDebugValue());
+  return root;
+}
+
 ShareTarget::ShareTarget() = default;
 
 ShareTarget::ShareTarget(const ShareTarget&) = default;
@@ -70,31 +92,13 @@
   }
 }
 
-std::ostream& operator<<(std::ostream& out, const ShareTarget& share_target) {
-  out << "action: " << share_target.action << std::endl;
-  out << "method: " << ShareTarget::MethodToString(share_target.method)
-      << std::endl;
-  out << "enctype: " << ShareTarget::EnctypeToString(share_target.enctype)
-      << std::endl;
-  out << share_target.params;
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const ShareTarget::Params& params) {
-  out << "title: " << params.title << std::endl;
-  out << "text: " << params.text << std::endl;
-  out << "url: " << params.url << std::endl;
-  out << "files:" << std::endl;
-  for (const auto& files_entry : params.files)
-    out << files_entry;
-  return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const ShareTarget::Files& files) {
-  out << "  name: " << files.name << std::endl;
-  for (const auto& accept_entry : files.accept)
-    out << "    accept: " << accept_entry << std::endl;
-  return out;
+base::Value ShareTarget::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("action", action.spec());
+  root.SetStringKey("method", ShareTarget::MethodToString(method));
+  root.SetStringKey("enctype", ShareTarget::EnctypeToString(enctype));
+  root.SetKey("params", params.AsDebugValue());
+  return root;
 }
 
 bool operator==(const ShareTarget& share_target1,
diff --git a/components/services/app_service/public/cpp/share_target.h b/components/services/app_service/public/cpp/share_target.h
index 686ecf7..5b48f8c 100644
--- a/components/services/app_service/public/cpp/share_target.h
+++ b/components/services/app_service/public/cpp/share_target.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "base/strings/string_piece.h"
+#include "base/values.h"
 #include "url/gurl.h"
 
 namespace apps {
@@ -37,6 +38,8 @@
     Files& operator=(Files&&);
     ~Files();
 
+    base::Value AsDebugValue() const;
+
     std::string name;
     std::vector<std::string> accept;
   };
@@ -49,6 +52,8 @@
     Params& operator=(Params&&);
     ~Params();
 
+    base::Value AsDebugValue() const;
+
     std::string title;
     std::string text;
     std::string url;
@@ -65,6 +70,8 @@
   static const char* MethodToString(Method);
   static const char* EnctypeToString(Enctype);
 
+  base::Value AsDebugValue() const;
+
   GURL action;
 
   Method method = Method::kGet;
@@ -74,11 +81,6 @@
   Params params;
 };
 
-// For logging and debug purposes.
-std::ostream& operator<<(std::ostream& out, const ShareTarget& share_target);
-std::ostream& operator<<(std::ostream& out, const ShareTarget::Params& params);
-std::ostream& operator<<(std::ostream& out, const ShareTarget::Files& files);
-
 bool operator==(const ShareTarget& share_target1,
                 const ShareTarget& share_target2);
 bool operator==(const ShareTarget::Params& params1,
diff --git a/components/services/app_service/public/cpp/url_handler_info.cc b/components/services/app_service/public/cpp/url_handler_info.cc
index 0b176e54..fb82a8227 100644
--- a/components/services/app_service/public/cpp/url_handler_info.cc
+++ b/components/services/app_service/public/cpp/url_handler_info.cc
@@ -42,6 +42,24 @@
   exclude_paths = {};
 }
 
+base::Value UrlHandlerInfo::AsDebugValue() const {
+  base::Value root(base::Value::Type::DICTIONARY);
+  root.SetStringKey("origin", origin.GetDebugString());
+  root.SetBoolKey("has_origin_wildcard", has_origin_wildcard);
+
+  base::Value& paths_json =
+      *root.SetKey("paths", base::Value(base::Value::Type::LIST));
+  for (const std::string& path : paths)
+    paths_json.Append(path);
+
+  base::Value& exclude_paths_json =
+      *root.SetKey("exclude_paths", base::Value(base::Value::Type::LIST));
+  for (const std::string& path : exclude_paths)
+    exclude_paths_json.Append(path);
+
+  return root;
+}
+
 bool operator==(const UrlHandlerInfo& handler1,
                 const UrlHandlerInfo& handler2) {
   return handler1.origin == handler2.origin &&
@@ -62,20 +80,4 @@
                   handler2.exclude_paths);
 }
 
-std::ostream& operator<<(std::ostream& out, const UrlHandlerInfo& handler) {
-  out << "origin: " << handler.origin << std::endl;
-  out << "  has_origin_wildcard: "
-      << (handler.has_origin_wildcard ? "true" : "false") << std::endl;
-
-  out << "  paths:" << std::endl;
-  for (auto path : handler.paths)
-    out << "    " << path << std::endl;
-
-  out << "  exclude_paths:" << std::endl;
-  for (auto path : handler.exclude_paths)
-    out << "    " << path << std::endl;
-
-  return out;
-}
-
 }  // namespace apps
diff --git a/components/services/app_service/public/cpp/url_handler_info.h b/components/services/app_service/public/cpp/url_handler_info.h
index c839918..ab16cc2 100644
--- a/components/services/app_service/public/cpp/url_handler_info.h
+++ b/components/services/app_service/public/cpp/url_handler_info.h
@@ -5,10 +5,10 @@
 #ifndef COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_URL_HANDLER_INFO_H_
 #define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_URL_HANDLER_INFO_H_
 
-#include <ostream>
 #include <string>
 #include <vector>
 
+#include "base/values.h"
 #include "url/origin.h"
 
 namespace apps {
@@ -37,6 +37,8 @@
   // Reset the url handler to its default state.
   void Reset();
 
+  base::Value AsDebugValue() const;
+
   url::Origin origin;
 
   bool has_origin_wildcard = false;
@@ -58,8 +60,6 @@
 bool operator<(const UrlHandlerInfo& url_handler1,
                const UrlHandlerInfo& url_handler2);
 
-std::ostream& operator<<(std::ostream& out,
-                         const UrlHandlerInfo& url_handler_info);
 }  // namespace apps
 
 #endif  // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_URL_HANDLER_INFO_H_
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope.cc b/components/services/storage/indexed_db/scopes/leveldb_scope.cc
index b4a7fb8..b8d88da 100644
--- a/components/services/storage/indexed_db/scopes/leveldb_scope.cc
+++ b/components/services/storage/indexed_db/scopes/leveldb_scope.cc
@@ -109,6 +109,8 @@
 LevelDBScope::EmptyRangeLessThan::EmptyRangeLessThan(
     const leveldb::Comparator* comparator)
     : comparator_(comparator) {}
+LevelDBScope::EmptyRangeLessThan::EmptyRangeLessThan(
+    const LevelDBScope::EmptyRangeLessThan& other) = default;
 LevelDBScope::EmptyRangeLessThan& LevelDBScope::EmptyRangeLessThan::operator=(
     const LevelDBScope::EmptyRangeLessThan& other) = default;
 
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope.h b/components/services/storage/indexed_db/scopes/leveldb_scope.h
index 10538eaf..3e6fc380 100644
--- a/components/services/storage/indexed_db/scopes/leveldb_scope.h
+++ b/components/services/storage/indexed_db/scopes/leveldb_scope.h
@@ -116,7 +116,8 @@
     // This constructor is needed to satisfy the constraints of having default
     // construction of the |empty_ranges_| flat_map below.
     EmptyRangeLessThan();
-    EmptyRangeLessThan(const leveldb::Comparator* comparator);
+    explicit EmptyRangeLessThan(const leveldb::Comparator* comparator);
+    EmptyRangeLessThan(const EmptyRangeLessThan& other);
     EmptyRangeLessThan& operator=(const EmptyRangeLessThan& other);
 
     // The ranges are expected to be disjoint.
diff --git a/components/shared_highlighting/core/common/shared_highlighting_features.cc b/components/shared_highlighting/core/common/shared_highlighting_features.cc
index e48d42c..dded539 100644
--- a/components/shared_highlighting/core/common/shared_highlighting_features.cc
+++ b/components/shared_highlighting/core/common/shared_highlighting_features.cc
@@ -9,7 +9,7 @@
 namespace shared_highlighting {
 
 const base::Feature kPreemptiveLinkToTextGeneration{
-    "PreemptiveLinkToTextGeneration", base::FEATURE_DISABLED_BY_DEFAULT};
+    "PreemptiveLinkToTextGeneration", base::FEATURE_ENABLED_BY_DEFAULT};
 constexpr base::FeatureParam<int> kPreemptiveLinkGenTimeoutLengthMs{
     &kPreemptiveLinkToTextGeneration, "TimeoutLengthMs", 500};
 
diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
index f14ce7a..6078422a 100644
--- a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
+++ b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java
@@ -113,6 +113,7 @@
 
     @Override
     public Optional<Boolean> canOfferExtendedSyncPromos(Account account) {
+        assert account != null;
         return Optional.absent();
     }
 
diff --git a/components/signin/public/base/signin_switches.cc b/components/signin/public/base/signin_switches.cc
index 4f3cd36..016f849 100644
--- a/components/signin/public/base/signin_switches.cc
+++ b/components/signin/public/base/signin_switches.cc
@@ -32,11 +32,6 @@
     "WipeDataOnChildAccountSignin", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-const base::Feature kUseAccountManagerFacade{"kUseAccountManagerFacade",
-                                             base::FEATURE_ENABLED_BY_DEFAULT};
-#endif
-
 #if defined(OS_ANDROID) || defined(OS_IOS)
 const base::Feature kForceStartupSigninPromo{"ForceStartupSigninPromo",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/signin/public/base/signin_switches.h b/components/signin/public/base/signin_switches.h
index 4db02814..fc346a63 100644
--- a/components/signin/public/base/signin_switches.h
+++ b/components/signin/public/base/signin_switches.h
@@ -33,11 +33,6 @@
 extern const base::Feature kWipeDataOnChildAccountSignin;
 #endif  // defined(OS_ANDROID)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-// Killswitch for PO2TS migration to AccountManagerFacade.
-extern const base::Feature kUseAccountManagerFacade;
-#endif
-
 #if defined(OS_ANDROID) || defined(OS_IOS)
 // Features to trigger the startup sign-in promo at boot.
 extern const base::Feature kForceStartupSigninPromo;
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc
index fab6565..81b218a 100644
--- a/components/signin/public/identity_manager/identity_manager.cc
+++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -57,14 +57,27 @@
   // yet been received from `AccountManagerFacade`, entities can ask about the
   // Primary Account and expect it to be available pretty early. Manually seed
   // the account in `AccountTrackerService` to get around this issue.
-  const CoreAccountId account_id = account_tracker_service->SeedAccountInfo(
-      /*gaia=*/device_account.key.id, device_account.raw_email);
+  const CoreAccountId device_account_id =
+      account_tracker_service->SeedAccountInfo(
+          /*gaia=*/device_account.key.id, device_account.raw_email);
+
   // TODO(https://crbug.com/1194983): Figure out how split sync settings will
   // work here. For now, we will mimic Ash's behaviour of having sync turned on
   // by default.
-  identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount(
-      account_id, ConsentLevel::kSync);
-
+  const CoreAccountId primary_account_id =
+      identity_manager->GetPrimaryAccountId(ConsentLevel::kSync);
+  if (primary_account_id == device_account_id)
+    return;  // Already correct primary account set, nothing to do.
+  if (!primary_account_id.empty()) {
+    // Different primary account found, have to clear it first.
+    // TODO(https://crbug.com/1223364): Replace this if with a CHECK after all
+    //                                  the existing users have been migrated.
+    identity_manager->GetPrimaryAccountMutator()->ClearPrimaryAccount(
+        signin_metrics::ACCOUNT_REMOVED_FROM_DEVICE,
+        signin_metrics::SignoutDelete::kIgnoreMetric);
+  }
+  CHECK(identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount(
+      device_account_id, ConsentLevel::kSync));
   CHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
   CHECK_EQ(identity_manager->GetPrimaryAccountInfo(ConsentLevel::kSync).gaia,
            device_account.key.id);
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h
index e56a55a..7c2a221 100644
--- a/components/signin/public/identity_manager/identity_manager.h
+++ b/components/signin/public/identity_manager/identity_manager.h
@@ -515,6 +515,8 @@
       const GoogleServiceAuthError& auth_error);
 
   friend void DisableAccessTokenFetchRetries(IdentityManager* identity_manager);
+  friend void EnableAccountCapabilitiesFetches(
+      IdentityManager* identity_manager);
 
   friend void CancelAllOngoingGaiaCookieOperations(
       IdentityManager* identity_manager);
diff --git a/components/signin/public/identity_manager/identity_manager_unittest.cc b/components/signin/public/identity_manager/identity_manager_unittest.cc
index 24b0c42..3535986 100644
--- a/components/signin/public/identity_manager/identity_manager_unittest.cc
+++ b/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -2351,10 +2351,30 @@
                           PrimaryAccountManagerSetup::kNoAuthenticatedAccount);
 
   // We should have a Primary Account set up automatically.
-  ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSignin));
+  ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSync));
   EXPECT_EQ(
       kTestGaiaId,
-      identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kSignin).gaia);
+      identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kSync).gaia);
+}
+
+// TODO(https://crbug.com/1223364): Remove this when all the users are migrated.
+TEST_F(IdentityManagerTest, SetPrimaryAccountClearsExistingPrimaryAccount) {
+  signin_client()->SetInitialPrimaryAccountForTests(account_manager::Account{
+      account_manager::AccountKey{kTestGaiaId2,
+                                  account_manager::AccountType::kGaia},
+      kTestEmail2});
+
+  // RecreateIdentityManager will create PrimaryAccountManager with the primary
+  // account set to kTestGaiaId. After that, IdentityManager ctor should clear
+  // this existing primary account and set the new one to the initial value
+  // provided by the SigninClient.
+  RecreateIdentityManager(AccountConsistencyMethod::kDisabled,
+                          PrimaryAccountManagerSetup::kWithAuthenticatedAccout);
+
+  ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSync));
+  EXPECT_EQ(
+      kTestGaiaId2,
+      identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kSync).gaia);
 }
 #endif
 
diff --git a/components/signin/public/identity_manager/identity_test_utils.cc b/components/signin/public/identity_manager/identity_test_utils.cc
index 6140ce5..a7329660 100644
--- a/components/signin/public/identity_manager/identity_test_utils.cc
+++ b/components/signin/public/identity_manager/identity_test_utils.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/signin/internal/identity_manager/account_fetcher_service.h"
 #include "components/signin/internal/identity_manager/account_tracker_service.h"
 #include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h"
 #include "components/signin/internal/identity_manager/primary_account_manager.h"
@@ -456,6 +457,11 @@
       ->set_max_authorization_token_fetch_retries_for_testing(0);
 }
 
+void EnableAccountCapabilitiesFetches(IdentityManager* identity_manager) {
+  identity_manager->GetAccountFetcherService()
+      ->EnableAccountCapabilitiesFetcherForTest(true);
+}
+
 #if defined(OS_ANDROID)
 void SetUpMockAccountManagerFacade() {
   Java_AccountManagerFacadeUtil_setUpMockFacade(
diff --git a/components/signin/public/identity_manager/identity_test_utils.h b/components/signin/public/identity_manager/identity_test_utils.h
index 40dc2ed..d2bce5c 100644
--- a/components/signin/public/identity_manager/identity_test_utils.h
+++ b/components/signin/public/identity_manager/identity_test_utils.h
@@ -175,6 +175,9 @@
 // Disables internal retries of failed access token fetches.
 void DisableAccessTokenFetchRetries(IdentityManager* identity_manager);
 
+// Enables account capabilities fetches in AccountFetcherService.
+void EnableAccountCapabilitiesFetches(IdentityManager* identity_manager);
+
 #if defined(OS_ANDROID)
 // Stubs AccountManagerFacade, which requires special initialization of the java
 // subsystems.
diff --git a/components/signin/public/webdata/token_service_table.cc b/components/signin/public/webdata/token_service_table.cc
index 4e3be5a..94978ec 100644
--- a/components/signin/public/webdata/token_service_table.cc
+++ b/components/signin/public/webdata/token_service_table.cc
@@ -96,8 +96,7 @@
       db_->GetUniqueStatement("INSERT OR REPLACE INTO token_service "
                               "(service, encrypted_token) VALUES (?, ?)"));
   s.BindString(0, service);
-  s.BindBlob(1, encrypted_token.data(),
-             static_cast<int>(encrypted_token.length()));
+  s.BindBlob(1, encrypted_token);
 
   bool result = s.Run();
   LOG_IF(ERROR, !result) << "Failed to insert or replace token for " << service;
diff --git a/components/sqlite_proto/key_value_table.cc b/components/sqlite_proto/key_value_table.cc
index 601e9e1a..e4620dc 100644
--- a/components/sqlite_proto/key_value_table.cc
+++ b/components/sqlite_proto/key_value_table.cc
@@ -4,6 +4,8 @@
 
 #include "components/sqlite_proto/key_value_table.h"
 
+#include <stdint.h>
+
 #include "base/strings/stringprintf.h"
 #include "third_party/protobuf/src/google/protobuf/message_lite.h"
 
@@ -17,9 +19,9 @@
   statement->BindString(0, key);
 
   size_t size = data.ByteSizeLong();
-  std::vector<char> proto_buffer(size);
+  std::vector<uint8_t> proto_buffer(size);
   data.SerializeToArray(proto_buffer.data(), size);
-  statement->BindBlob(1, proto_buffer.data(), size);
+  statement->BindBlob(1, proto_buffer);
 }
 
 std::string GetSelectAllSql(const std::string& table_name) {
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb
index a5fbce7..e878cd88 100644
--- a/components/strings/components_strings_ar.xtb
+++ b/components/strings/components_strings_ar.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">الميزات المتوقفة</translation>
 <translation id="131405271941274527">‏يريد <ph name="URL" /> إرسال المعلومات وتلقّيها عند النقر على جهاز NFC الظاهر على هاتفك.</translation>
 <translation id="1314509827145471431">التجليد من الناحية اليمنى</translation>
+<translation id="1319245136674974084">عدم السؤال مرة أخرى عند استخدام هذا التطبيق</translation>
 <translation id="1320233736580025032">‏Prc1 (مغلف)</translation>
 <translation id="132301787627749051">البحث عن صورة الحافظة</translation>
 <translation id="1323433172918577554">إظهار مزيد من الأقسام</translation>
@@ -744,6 +745,7 @@
 <translation id="3655670868607891010">إذا تكرّر هذا الأمر، ننصحك بالاطّلاع على هذه <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">التعديل</translation>
 <translation id="3664782872746246217">الكلمات الرئيسية:</translation>
+<translation id="3671540257457995106">هل تريد السماح بتغيير الحجم؟</translation>
 <translation id="3676592649209844519">معرِّف الجهاز:</translation>
 <translation id="3677008721441257057">‏هل كنت تقصد &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;؟</translation>
 <translation id="3678029195006412963">تعذر توقيع الطلب</translation>
@@ -1104,6 +1106,7 @@
 <translation id="4953689047182316270">الاستجابة لأحداث إمكانية الوصول</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">توسيع القائمة</translation>
+<translation id="4968522289500246572">هذا التطبيق مصمّم للعمل مع الأجهزة الجوّالة وقد يتعذّر تغيير حجمه بشكل مناسب. من الممكن أن يواجه التطبيق بعض المشاكل أو يتعرّض لإعادة التشغيل.</translation>
 <translation id="4973922308112707173">عمل ثقبَين بالأعلى</translation>
 <translation id="4974590756084640048">إعادة تفعيل التحذيرات</translation>
 <translation id="4984088539114770594">هل تريد استخدام الميكروفون؟</translation>
@@ -1152,6 +1155,7 @@
 <translation id="5123063207673082822">نهاية الأسبوع</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">التحقق من بطاقتك</translation>
+<translation id="512670116361803001">قد لا يتم تغيير حجم التطبيق <ph name="APP_NAME" /> بشكل مناسب. استخدِم أحجام النوافذ المُعَدّة مسبقًا لمنع حدوث مشاكل أثناء استخدام التطبيق.</translation>
 <translation id="5135404736266831032">إدارة العناوين...</translation>
 <translation id="5138014172396933048">البطاقة الافتراضية غير متوفّرة حاليًا. يُرجى التواصل مع المصرف.</translation>
 <translation id="5138227688689900538">عرض أقل</translation>
@@ -1518,6 +1522,7 @@
 <translation id="647261751007945333">سياسات الأجهزة</translation>
 <translation id="6476284679642588870">إدارة طرق الدفع</translation>
 <translation id="6489534406876378309">بدء تحميل الأعطال</translation>
+<translation id="6493924760403974580">لا يمكن عرض هذا التطبيق إلا بهذا الحجم.</translation>
 <translation id="6499038740797743453">هل تريد إعادة ضبط كلمة المرور؟</translation>
 <translation id="6502991525169604759">بدون التغييرات التي أجريتها</translation>
 <translation id="6508722015517270189">‏إعادة تشغيل Chrome</translation>
@@ -2173,6 +2178,7 @@
 <translation id="8975263830901772334">أسماء الملفات التي طبعتها</translation>
 <translation id="8978053250194585037">‏رصد التصفح الآمن من Google عن وجود‬ <ph name="BEGIN_LINK" />تصيّد احتيالي<ph name="END_LINK" /> مؤخرًا على موقع <ph name="SITE" />، إذ تتظاهر مواقع التصيد الاحتيالي بكونها مواقع إلكترونية أخرى لخداعك.</translation>
 <translation id="8983003182662520383">‏طرق الدفع والعناوين باستخدام Google Pay</translation>
+<translation id="8983369100812962543">يمكنك الآن تغيير حجم التطبيق.</translation>
 <translation id="8987927404178983737">شهر</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" />‏ [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">يريد الموقع الإلكتروني <ph name="URL" /> رصد استخدامك النشط لهذا الجهاز.</translation>
diff --git a/components/strings/components_strings_as.xtb b/components/strings/components_strings_as.xtb
index cb33f8c6..5d067f0 100644
--- a/components/strings/components_strings_as.xtb
+++ b/components/strings/components_strings_as.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">অপ্ৰচলিত সুবিধাসমূহ</translation>
 <translation id="131405271941274527">আপুনি নিজৰ ফ’নটো কোনো NFC ডিভাইচত লগালে <ph name="URL" />এ তথ্য পঠিয়াব আৰু গ্ৰহণ কৰিবলৈ বিচাৰে</translation>
 <translation id="1314509827145471431">সোঁফালে সংযুক্ত কৰক</translation>
+<translation id="1319245136674974084">এই এপ্‌টোৰ বাবে পুনৰাই নুসুধিব</translation>
 <translation id="1320233736580025032">Prc1 (লেফাফা)</translation>
 <translation id="132301787627749051">ক্লিপব'ৰ্ডৰ প্ৰতিচ্ছবিৰ সন্ধান কৰক</translation>
 <translation id="1323433172918577554">অধিক দেখুৱাওক</translation>
@@ -741,6 +742,7 @@
 <translation id="3655670868607891010">আপুনি যদি এইটো সঘনাই দেখি আছে, <ph name="HELP_LINK" />লৈ যাওক।</translation>
 <translation id="3658742229777143148">পুনৰীক্ষণ</translation>
 <translation id="3664782872746246217">মূল শব্দ:</translation>
+<translation id="3671540257457995106">আকাৰ সলনি কৰাৰ অনুমতি দিবনে?</translation>
 <translation id="3676592649209844519">ডিভাইচ আইডি:</translation>
 <translation id="3677008721441257057">আপুনি &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;ৰ কথা কৈছে নেকি?</translation>
 <translation id="3678029195006412963">অনুৰোধ ছাইন কৰিব পৰা নগ’ল</translation>
@@ -1099,6 +1101,7 @@
 <translation id="4953689047182316270">সাধ্যসুবিধাৰ অনুষ্ঠানলৈ সঁহাৰি জনাওক</translation>
 <translation id="4955242332710481440">A5-অতিৰিক্ত</translation>
 <translation id="4958444002117714549">তালিকা প্ৰসাৰিত কৰক</translation>
+<translation id="4968522289500246572">এই এপ্‌টো ম’বাইলৰ বাবে ডিজাইন কৰা হৈছে আৰু ইয়াৰ আকাৰ ভালদৰে সলনি নহ’ব পাৰে। এপ্‌টো সমস্যাৰ সন্মুখীন অথবা ৰিষ্টাৰ্ট হ’ব পাৰে।</translation>
 <translation id="4973922308112707173">ওপৰৰ অংশত দুবাৰ পাঞ্চ কৰক</translation>
 <translation id="4974590756084640048">সতর্কবার্তাসমূহ পুনৰ সক্ষম কৰক</translation>
 <translation id="4984088539114770594">মাইক্র’ফ’ন ব্যৱহাৰ কৰিবনে?</translation>
@@ -1147,6 +1150,7 @@
 <translation id="5123063207673082822">সপ্তাহৰ অন্ত</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">আপোনাৰ কাৰ্ডখন সত্যাপন কৰক</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" />ৰ আকাৰ ভালদৰে সলনি নহ’ব পাৰে। এপ্‌টো সমস্যাৰ সন্মুখীন হোৱাত বাধা দিবলৈ পূৰ্বে ছেট কৰি থোৱা ৱিণ্ড’ৰ আকাৰ ব্যৱহাৰ কৰক।</translation>
 <translation id="5135404736266831032">ঠিকনাসমূহ পৰিচালনা কৰক...</translation>
 <translation id="5138014172396933048">এই মুহূৰ্তত ভাৰ্চুৱেল কাৰ্ডখন উপলব্ধ নহয়, অনুগ্ৰহ কৰি আপোনাৰ বেংকৰ সৈতে যোগাযোগ কৰক</translation>
 <translation id="5138227688689900538">কমকৈ দেখুৱাওক</translation>
@@ -1511,6 +1515,7 @@
 <translation id="647261751007945333">ডিভাইচৰ নীতি</translation>
 <translation id="6476284679642588870">পৰিশোধ পদ্ধতিসমূহ পৰিচালনা কৰক</translation>
 <translation id="6489534406876378309">ক্ৰেশ্ব আপল’ড কৰা আৰম্ভ কৰক</translation>
+<translation id="6493924760403974580">এই এপ্‌টোৱে কেৱল এইটো আকাৰ সমৰ্থন কৰে।</translation>
 <translation id="6499038740797743453">পাছৱৰ্ড ৰিছেট কৰিবনে?</translation>
 <translation id="6502991525169604759">আপোনাৰ সালসলনিসমূহ অবিহনে</translation>
 <translation id="6508722015517270189">Chrome ৰিষ্টাৰ্ট কৰক</translation>
@@ -2162,6 +2167,7 @@
 <translation id="8975263830901772334">আপুনি প্ৰিণ্ট কৰা ফাইলসমূহৰ নাম</translation>
 <translation id="8978053250194585037">Googleৰ সুৰক্ষিত ব্ৰাউজিঙে শেহতীয়াকৈ <ph name="SITE" />ত <ph name="BEGIN_LINK" />ফিশ্বিং চিনাক্ত কৰিছে<ph name="END_LINK" />। ফিশ্বিং ছাইটে অন্য কোনো ছাইটৰ ৰূপ লৈ আপোনাক সমস্যাত পেলাব পাৰে।</translation>
 <translation id="8983003182662520383">Google Pay ব্যৱহাৰ কৰি থকা পৰিশোধৰ পদ্ধতি আৰু ঠিকনা</translation>
+<translation id="8983369100812962543">আপুনি এতিয়া এপ্‌টোৰ আকাৰ সলনি কৰিব পাৰে</translation>
 <translation id="8987927404178983737">মাহ</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">আপুনি এই ডিভাইচটো সক্ৰিয়ভাৱে ব্যৱহাৰ কৰি থকাৰ বিষয়ে <ph name="URL" />এ জানিব বিচাৰে</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb
index afa4631..9e690e83 100644
--- a/components/strings/components_strings_bn.xtb
+++ b/components/strings/components_strings_bn.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">শীঘ্রই বন্ধ করা হবে এমন ফিচার</translation>
 <translation id="131405271941274527">NFC ডিভাইসে আপনার ফোন ট্যাপ করলে <ph name="URL" /> তথ্য পাঠাতে এবং পেতে চায়</translation>
 <translation id="1314509827145471431">ডানদিকে বাঁধাই করুন</translation>
+<translation id="1319245136674974084">এই অ্যাপের জন্য আর জিজ্ঞাসা করবেন না</translation>
 <translation id="1320233736580025032">Prc1 (Envelope)</translation>
 <translation id="132301787627749051">ক্লিপবোর্ডে ছবির জন্য সার্চ করুন</translation>
 <translation id="1323433172918577554">আরও দেখুন</translation>
@@ -745,6 +746,7 @@
 <translation id="3655670868607891010">আপনি যদি এটি প্রায়শই দেখতে পান, তাহলে <ph name="HELP_LINK" /> চেষ্টা করে দেখুন৷</translation>
 <translation id="3658742229777143148">পুনর্বিবেচনা</translation>
 <translation id="3664782872746246217">কীওয়ার্ড:</translation>
+<translation id="3671540257457995106">ছোট বড় করতে অনুমতি দেবেন?</translation>
 <translation id="3676592649209844519">ডিভাইস আইডি:</translation>
 <translation id="3677008721441257057">আপনি কি &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; বোঝাতে চাইছেন?</translation>
 <translation id="3678029195006412963">অনুরোধটি স্বাক্ষরিত করা যায়নি</translation>
@@ -1105,6 +1107,7 @@
 <translation id="4953689047182316270">ব্যবহারযোগ্যতা সংক্রান্ত ইভেন্টে প্রতিবার্তা দিতে চায়</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">তালিকা প্রসারিত করুন</translation>
+<translation id="4968522289500246572">এই অ্যাপটি মোবাইল ডিভাইসের জন্য তৈরি করা হয়েছে এবং সঠিকভাবে ছোট বড় করা নাও যেতে পারে। এই অ্যাপ ব্যবহার করতে হয়ত সমস্যা হতে পারে বা এটি রিস্টার্ট করতে হতে পারে।</translation>
 <translation id="4973922308112707173">উপরে ডুয়াল পাঞ্চ</translation>
 <translation id="4974590756084640048">সতর্কবার্তাগুলি পুনঃসক্ষম করুন</translation>
 <translation id="4984088539114770594">মাইক্রোফোন ব্যবহার করবেন?</translation>
@@ -1153,6 +1156,7 @@
 <translation id="5123063207673082822">সপ্তাহান্ত</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">আপনার কার্ডটি যাচাই করুন</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> সঠিকভাবে ছোট বড় করা নাও যেতে পারে। অ্যাপটি ব্যবহার করতে সমস্যা এড়াতে প্রিসেট উইন্ডো সাইজ ব্যবহার করুন।</translation>
 <translation id="5135404736266831032">ঠিকানাগুলি পরিচালনা করুন...</translation>
 <translation id="5138014172396933048">ভার্চুয়াল কার্ড এই মুহূর্তে উপলভ্য নেই, আপনার ব্যাঙ্কের সাথে যোগাযোগ করুন</translation>
 <translation id="5138227688689900538">কম দেখুন</translation>
@@ -1518,6 +1522,7 @@
 <translation id="647261751007945333">ডিভাইস নীতিগুলি</translation>
 <translation id="6476284679642588870">পেমেন্টের পদ্ধতি ম্যানেজ করুন</translation>
 <translation id="6489534406876378309">ক্র্যাশগুলি আপলোড করা শুরু করুন</translation>
+<translation id="6493924760403974580">অ্যাপটি এই সাইজেই কাজ করে।</translation>
 <translation id="6499038740797743453">পাসওয়ার্ড রিসেট করবেন?</translation>
 <translation id="6502991525169604759">আপনার করা এডিট ছাড়া</translation>
 <translation id="6508722015517270189">Chrome পুনরায় চালু করুন</translation>
@@ -2172,6 +2177,7 @@
 <translation id="8975263830901772334">আপনার প্রিন্ট করা ফাইলগুলির নাম</translation>
 <translation id="8978053250194585037">Google Safe Browsing সম্প্রতি <ph name="SITE" /> এ <ph name="BEGIN_LINK" />ফিশিং শনাক্ত করেছে<ph name="END_LINK" />। ফিশিং সাইটগুলি আপনাকে প্রতারিত করার জন্য অন্যান্য সাইট যেমন হয় সেইরকম ভান করে।</translation>
 <translation id="8983003182662520383">Google Pay ব্যবহার করে এমন পেমেন্টের পদ্ধতি এবং ঠিকানা</translation>
+<translation id="8983369100812962543">আপনি এখন অ্যাপ ছোট বড় করতে পারবেন</translation>
 <translation id="8987927404178983737">মাস</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> জানতে চায় আপনি সক্রিয়ভাবে কখন এই ডিভাইস ব্যবহার করেন</translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb
index 4152a2c..cdb6c344 100644
--- a/components/strings/components_strings_de.xtb
+++ b/components/strings/components_strings_de.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Eingestellte Funktionen</translation>
 <translation id="131405271941274527"><ph name="URL" /> möchte Informationen senden und empfangen, wenn Sie Ihr Smartphone an NFC-Geräte halten</translation>
 <translation id="1314509827145471431">Bindung rechts</translation>
+<translation id="1319245136674974084">Für diese App nicht mehr nachfragen</translation>
 <translation id="1320233736580025032">Prc1 (Umschlag)</translation>
 <translation id="132301787627749051">Nach Bild aus Zwischenablage suchen</translation>
 <translation id="1323433172918577554">Mehr anzeigen</translation>
@@ -738,6 +739,7 @@
 <translation id="3655670868607891010">Sollte Ihnen diese Meldung häufiger angezeigt werden, sehen Sie sich unsere <ph name="HELP_LINK" /> an.</translation>
 <translation id="3658742229777143148">Überarbeitung</translation>
 <translation id="3664782872746246217">Suchbegriffe:</translation>
+<translation id="3671540257457995106">Größenanpassung zulassen?</translation>
 <translation id="3676592649209844519">Geräte-ID:</translation>
 <translation id="3677008721441257057">Meinten Sie vielleicht &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
 <translation id="3678029195006412963">Anfrage konnte nicht signiert werden</translation>
@@ -1093,6 +1095,7 @@
 <translation id="4953689047182316270">Auf Bedienungshilfen reagieren</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Liste einblenden</translation>
+<translation id="4968522289500246572">Diese App wurde für Mobilgeräte entwickelt. Ihre Größe kann deshalb eventuell nicht richtig angepasst werden. Außerdem können Probleme auftreten und sie wird möglicherweise neu gestartet.</translation>
 <translation id="4973922308112707173">Doppelte Lochung oben</translation>
 <translation id="4974590756084640048">Warnmeldungen wieder aktivieren</translation>
 <translation id="4984088539114770594">Mikrofon verwenden?</translation>
@@ -1141,6 +1144,7 @@
 <translation id="5123063207673082822">Wochenende</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Karte bestätigen</translation>
+<translation id="512670116361803001">Die Größe von <ph name="APP_NAME" /> kann eventuell nicht richtig angepasst werden. Verwenden Sie voreingestellte Fenstergrößen, damit die App ordnungsgemäß funktioniert.</translation>
 <translation id="5135404736266831032">Adressen verwalten…</translation>
 <translation id="5138014172396933048">Die virtuelle Karte ist zurzeit nicht verfügbar, bitte kontaktieren Sie Ihre Bank</translation>
 <translation id="5138227688689900538">Weniger anzeigen</translation>
@@ -1507,6 +1511,7 @@
 <translation id="647261751007945333">Geräterichtlinien</translation>
 <translation id="6476284679642588870">Zahlungsmethoden verwalten</translation>
 <translation id="6489534406876378309">Hochladen von Abstürzen starten</translation>
+<translation id="6493924760403974580">Diese App unterstützt nur diese Größe.</translation>
 <translation id="6499038740797743453">Passwort zurücksetzen?</translation>
 <translation id="6502991525169604759">Ohne meine Änderungen</translation>
 <translation id="6508722015517270189">Chrome neu starten</translation>
@@ -2162,6 +2167,7 @@
 <translation id="8975263830901772334">Namen von Dateien, die Sie drucken</translation>
 <translation id="8978053250194585037">Google Safe Browsing hat kürzlich <ph name="BEGIN_LINK" />Phishingaktivitäten<ph name="END_LINK" /> auf <ph name="SITE" /> festgestellt. Phishingwebsites geben sich als andere Websites aus, um Sie zu täuschen.</translation>
 <translation id="8983003182662520383">Bei Google Pay gespeicherte Zahlungsmethoden und Adressen</translation>
+<translation id="8983369100812962543">Sie können die Größe der App jetzt ändern</translation>
 <translation id="8987927404178983737">Monat</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> möchte Informationen zu Ihrer aktiven Nutzung dieses Geräts abrufen</translation>
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb
index 058fae4..5c90bbb 100644
--- a/components/strings/components_strings_en-GB.xtb
+++ b/components/strings/components_strings_en-GB.xtb
@@ -1589,6 +1589,7 @@
 <translation id="6775759552199460396">JIS B2</translation>
 <translation id="67862343314499040">Violet</translation>
 <translation id="6786747875388722282">Extensions</translation>
+<translation id="678982761784843853">Protected content IDs</translation>
 <translation id="6790428901817661496">Play</translation>
 <translation id="679355240208270552">Ignored because default search is not enabled by policy.</translation>
 <translation id="6794951432696553238">Confirm your cards faster by using Windows Hello from now on</translation>
diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb
index 45e6b57..970b0ed 100644
--- a/components/strings/components_strings_es-419.xtb
+++ b/components/strings/components_strings_es-419.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Funciones obsoletas</translation>
 <translation id="131405271941274527"><ph name="URL" /> quiere enviar y recibir información cuando presionas tu teléfono en un dispositivo NFC</translation>
 <translation id="1314509827145471431">Encuadernado a la derecha</translation>
+<translation id="1319245136674974084">No volver a preguntar sobre esta app</translation>
 <translation id="1320233736580025032">Prc1 (Envelope)</translation>
 <translation id="132301787627749051">Buscar imagen del portapapeles</translation>
 <translation id="1323433172918577554">Mostrar más</translation>
@@ -741,6 +742,7 @@
 <translation id="3655670868607891010">Si este mensaje aparece con frecuencia, haz clic aquí: <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">Revisión</translation>
 <translation id="3664782872746246217">Palabras clave:</translation>
+<translation id="3671540257457995106">¿Deseas permitir el cambio de tamaño?</translation>
 <translation id="3676592649209844519">ID de dispositivo:</translation>
 <translation id="3677008721441257057">¿Quisiste decir &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
 <translation id="3678029195006412963">La solicitud no se pudo firmar</translation>
@@ -1096,6 +1098,7 @@
 <translation id="4953689047182316270">Responder a los eventos de accesibilidad</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Mostrar lista</translation>
+<translation id="4968522289500246572">Esta app está diseñada para dispositivos móviles y es posible que el cambio de tamaño no funcione correctamente. Posiblemente la app se reiniciará o presentará problemas.</translation>
 <translation id="4973922308112707173">Perforación doble en la parte superior</translation>
 <translation id="4974590756084640048">Volver a habilitar las advertencias</translation>
 <translation id="4984088539114770594">¿Permitir el uso del micrófono?</translation>
@@ -1144,6 +1147,7 @@
 <translation id="5123063207673082822">Fin de semana</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Verifica tu tarjeta</translation>
+<translation id="512670116361803001">Es posible que el cambio de tamaño de <ph name="APP_NAME" /> no funcione correctamente. Utiliza los tamaños predeterminados de ventana para que no se generen problemas en la app.</translation>
 <translation id="5135404736266831032">Administrar direcciones…</translation>
 <translation id="5138014172396933048">La tarjeta virtual no está disponible ahora mismo; comunícate con tu banco.</translation>
 <translation id="5138227688689900538">Mostrar menos</translation>
@@ -1510,6 +1514,7 @@
 <translation id="647261751007945333">Políticas de dispositivos</translation>
 <translation id="6476284679642588870">Administrar las formas de pago</translation>
 <translation id="6489534406876378309">Comenzar a cargar fallos</translation>
+<translation id="6493924760403974580">No se permite cambiar el tamaño de esta app.</translation>
 <translation id="6499038740797743453">¿Deseas restablecer la contraseña?</translation>
 <translation id="6502991525169604759">Sin tus cambios</translation>
 <translation id="6508722015517270189">Reinicia Chrome.</translation>
@@ -2165,6 +2170,7 @@
 <translation id="8975263830901772334">Nombres de los archivos que imprimes</translation>
 <translation id="8978053250194585037">Recientemente, la navegación segura de Google <ph name="BEGIN_LINK" />detectó un intento de suplantación de identidad (phishing)<ph name="END_LINK" /> en <ph name="SITE" />. Los sitios de suplantación de identidad imitan a otros sitios web para engañarte.</translation>
 <translation id="8983003182662520383">Formas de pago y direcciones con Google Pay</translation>
+<translation id="8983369100812962543">Ahora puedes cambiar el tamaño de la app.</translation>
 <translation id="8987927404178983737">Mes</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> quiere saber en qué momento estás usando activamente este dispositivo</translation>
diff --git a/components/strings/components_strings_eu.xtb b/components/strings/components_strings_eu.xtb
index d71b731..67f4af91 100644
--- a/components/strings/components_strings_eu.xtb
+++ b/components/strings/components_strings_eu.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Eginbide zaharkituak</translation>
 <translation id="131405271941274527"><ph name="URL" /> webguneak informazioa bidali eta jaso nahi du telefonoarekin NFC bidezko gailu bat ukituz gero</translation>
 <translation id="1314509827145471431">Koadernatu eskuinetik</translation>
+<translation id="1319245136674974084">Ez galdetu berriro aplikazio honen kasuan</translation>
 <translation id="1320233736580025032">Prc1 (gutun-azala)</translation>
 <translation id="132301787627749051">Bilatu arbeleko irudia</translation>
 <translation id="1323433172918577554">Erakutsi gehiago</translation>
@@ -736,6 +737,7 @@
 <translation id="3655670868607891010">Hau maiz agertzen bazaizu, saiatu honekin: <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">Zuzenketa</translation>
 <translation id="3664782872746246217">Gako-hitzak:</translation>
+<translation id="3671540257457995106">Tamaina aldatzeko baimena ematen duzu?</translation>
 <translation id="3676592649209844519">Gailuaren IDa:</translation>
 <translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; esan nahi al zenuen?</translation>
 <translation id="3678029195006412963">Ezin izan da sinatu eskaera</translation>
@@ -1091,6 +1093,7 @@
 <translation id="4953689047182316270">Erantzun erabilerraztasun-gertaerei</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Zabaldu zerrenda</translation>
+<translation id="4968522289500246572">Mugikorretan erabiltzeko dago diseinatuta aplikazioa, eta agian ez da behar bezala aldatuko tamaina. Litekeena da aplikazioak arazoak izatea edo berrabiaraztea.</translation>
 <translation id="4973922308112707173">Bi zulo goian</translation>
 <translation id="4974590756084640048">Gaitu berriro abisuak</translation>
 <translation id="4984088539114770594">Mikrofonoa erabili nahi duzu?</translation>
@@ -1139,6 +1142,7 @@
 <translation id="5123063207673082822">Asteburua</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Egiaztatu txartela</translation>
+<translation id="512670116361803001">Agian ez da behar bezala aldatuko <ph name="APP_NAME" /> aplikazioaren tamaina. Aplikazioak arazorik ez izateko, erabili aurrezarritako leiho-tamainak.</translation>
 <translation id="5135404736266831032">Kudeatu helbideak…</translation>
 <translation id="5138014172396933048">Txartel birtuala ez dago erabilgarri une honetan. Jarri bankuarekin harremanetan.</translation>
 <translation id="5138227688689900538">Erakutsi gutxiago</translation>
@@ -1504,6 +1508,7 @@
 <translation id="647261751007945333">Gailuaren gidalerroak</translation>
 <translation id="6476284679642588870">Kudeatu ordainketa-metodoak</translation>
 <translation id="6489534406876378309">Hasi hutsegite-txostenak kargatzen</translation>
+<translation id="6493924760403974580">Tamaina honetan soilik dago erabilgarri aplikazioa.</translation>
 <translation id="6499038740797743453">Pasahitza berrezarri nahi duzu?</translation>
 <translation id="6502991525169604759">Aldaketarik gabe</translation>
 <translation id="6508722015517270189">Berrabiarazi Chrome</translation>
@@ -2158,6 +2163,7 @@
 <translation id="8975263830901772334">Inprimatzen dituzun fitxategien izenak</translation>
 <translation id="8978053250194585037">Berriki, Google-ren Arakatze seguruak <ph name="BEGIN_LINK" />phishinga hauteman du<ph name="END_LINK" /> <ph name="SITE" /> webgunean. Phishing-webguneek beste webgune batzuk direnaren plantak egiten dituzte zu iruzurtzeko.</translation>
 <translation id="8983003182662520383">Google Pay-rekin erabiltzen dituzun ordainketa-metodoak eta helbideak</translation>
+<translation id="8983369100812962543">Orain, aplikazioaren tamaina alda dezakezu</translation>
 <translation id="8987927404178983737">Hilabetea</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> (<ph name="COUNTRY" />)</translation>
 <translation id="899688752321268742">Gailua noiz erabiltzen ari zaren jakin nahi du <ph name="URL" /> webguneak</translation>
diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb
index 3191546..231ae102 100644
--- a/components/strings/components_strings_fr.xtb
+++ b/components/strings/components_strings_fr.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Fonctionnalités obsolètes</translation>
 <translation id="131405271941274527"><ph name="URL" /> souhaite envoyer et recevoir des informations lorsque votre téléphone entre en contact avec un appareil NFC</translation>
 <translation id="1314509827145471431">Reliure à droite</translation>
+<translation id="1319245136674974084">Ne plus me demander pour cette appli</translation>
 <translation id="1320233736580025032">Prc1 (enveloppe)</translation>
 <translation id="132301787627749051">Rechercher l'image du presse-papier</translation>
 <translation id="1323433172918577554">Afficher plus</translation>
@@ -744,6 +745,7 @@
 <translation id="3655670868607891010">Si ce message s'affiche régulièrement, essayez ces <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">Révision</translation>
 <translation id="3664782872746246217">Mots-clés :</translation>
+<translation id="3671540257457995106">Autoriser le redimensionnement ?</translation>
 <translation id="3676592649209844519">ID de l'appareil :</translation>
 <translation id="3677008721441257057">Vouliez-vous accéder à &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ?</translation>
 <translation id="3678029195006412963">Impossible de signer la demande</translation>
@@ -1104,6 +1106,7 @@
 <translation id="4953689047182316270">Répondre aux événements d'accessibilité</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Développer la liste</translation>
+<translation id="4968522289500246572">Cette appli est conçue pour les mobiles et ne sera peut-être pas bien redimensionnée. Elle pourrait rencontrer des problèmes ou redémarrer.</translation>
 <translation id="4973922308112707173">Double perforation en haut</translation>
 <translation id="4974590756084640048">Réactiver les avertissements</translation>
 <translation id="4984088539114770594">Utiliser le micro ?</translation>
@@ -1152,6 +1155,7 @@
 <translation id="5123063207673082822">Week-end</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Valider votre carte</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> ne sera peut-être pas bien redimensionnée. Pour que l'appli fonctionne correctement, utilisez des tailles de fenêtre prédéfinies.</translation>
 <translation id="5135404736266831032">Gérer les adresses…</translation>
 <translation id="5138014172396933048">La carte virtuelle n'est pas disponible pour le moment. Veuillez contacter votre banque.</translation>
 <translation id="5138227688689900538">Afficher moins</translation>
@@ -1518,6 +1522,7 @@
 <translation id="647261751007945333">Règles relatives aux appareils</translation>
 <translation id="6476284679642588870">Gérer les modes de paiement</translation>
 <translation id="6489534406876378309">Lancer l'importation des plantages</translation>
+<translation id="6493924760403974580">Cette appli n'est compatible qu'avec cette taille.</translation>
 <translation id="6499038740797743453">Réinitialiser le mot de passe ?</translation>
 <translation id="6502991525169604759">Sans vos modifications</translation>
 <translation id="6508722015517270189">Relancez Chrome</translation>
@@ -2173,6 +2178,7 @@
 <translation id="8975263830901772334">Noms des fichiers que vous imprimez</translation>
 <translation id="8978053250194585037">La fonctionnalité de navigation sécurisée Google a récemment permis de <ph name="BEGIN_LINK" />détecter une tentative d'hameçonnage<ph name="END_LINK" /> sur le site <ph name="SITE" />. Un site d'hameçonnage se présente comme un site légitime dans le but de vous tromper.</translation>
 <translation id="8983003182662520383">Modes de paiement et adresses utilisés dans Google Pay</translation>
+<translation id="8983369100812962543">Vous pouvez désormais redimensionner l'appli</translation>
 <translation id="8987927404178983737">Mois</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> souhaite savoir si vous utilisez activement cet appareil</translation>
diff --git a/components/strings/components_strings_gl.xtb b/components/strings/components_strings_gl.xtb
index 1e0dc89..7732ee62 100644
--- a/components/strings/components_strings_gl.xtb
+++ b/components/strings/components_strings_gl.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Funcións obsoletas</translation>
 <translation id="131405271941274527"><ph name="URL" /> quere enviar e recibir información cando o teu teléfono toque un dispositivo NFC</translation>
 <translation id="1314509827145471431">Encadernación na parte dereita</translation>
+<translation id="1319245136674974084">Non volver preguntar para esta aplicación</translation>
 <translation id="1320233736580025032">Prc1 (sobre)</translation>
 <translation id="132301787627749051">Buscar imaxe do portapapeis</translation>
 <translation id="1323433172918577554">Mostrar máis</translation>
@@ -743,6 +744,7 @@
 <translation id="3655670868607891010">Se esta mensaxe aparece con frecuencia, proba a solucionalo con estas <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">Revisión</translation>
 <translation id="3664782872746246217">Palabras clave:</translation>
+<translation id="3671540257457995106">Queres permitir que a aplicación cambie de tamaño?</translation>
 <translation id="3676592649209844519">Código de identificación do dispositivo:</translation>
 <translation id="3677008721441257057">Quizais querías dicir &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
 <translation id="3678029195006412963">Non se puido asinar a solicitude</translation>
@@ -1103,6 +1105,7 @@
 <translation id="4953689047182316270">Responder a eventos de accesibilidade</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Ampliar lista</translation>
+<translation id="4968522289500246572">Esta aplicación está deseñada para dispositivos móbiles e pode que non cambie ben de tamaño. É posible que se reinicie ou que se produza algún problema co seu funcionamento.</translation>
 <translation id="4973922308112707173">Dúas perforacións na parte superior</translation>
 <translation id="4974590756084640048">Volver activar advertencias</translation>
 <translation id="4984088539114770594">Queres utilizar o micrófono?</translation>
@@ -1151,6 +1154,7 @@
 <translation id="5123063207673082822">Fin de semana</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Verificar a túa tarxeta</translation>
+<translation id="512670116361803001">É posible que <ph name="APP_NAME" /> non cambie ben de tamaño. Para evitar que se produzan problemas co funcionamento da aplicación, usa os tamaños de ventá predeterminados.</translation>
 <translation id="5135404736266831032">Xestiona os enderezos…</translation>
 <translation id="5138014172396933048">A tarxeta virtual non está dispoñible neste intres. Ponte en contacto co teu banco</translation>
 <translation id="5138227688689900538">Mostrar menos</translation>
@@ -1517,6 +1521,7 @@
 <translation id="647261751007945333">Políticas de dispositivo</translation>
 <translation id="6476284679642588870">Xestionar métodos de pago</translation>
 <translation id="6489534406876378309">Comezar a cargar erros</translation>
+<translation id="6493924760403974580">Esta aplicación só admite este tamaño.</translation>
 <translation id="6499038740797743453">Queres restablecer o contrasinal?</translation>
 <translation id="6502991525169604759">Sen os teus cambios</translation>
 <translation id="6508722015517270189">Reinicia Chrome</translation>
@@ -2171,6 +2176,7 @@
 <translation id="8975263830901772334">Nomes dos ficheiros que imprimes</translation>
 <translation id="8978053250194585037">A función de navegación segura de Google <ph name="BEGIN_LINK" />detectou actividades de phishing<ph name="END_LINK" /> recentemente no sitio <ph name="SITE" />. Os sitios de phishing fanse pasar por outros sitios web para enganar os usuarios.</translation>
 <translation id="8983003182662520383">Métodos de pago e enderezos que usan Google Pay</translation>
+<translation id="8983369100812962543">Xa podes cambiar o tamaño da aplicación</translation>
 <translation id="8987927404178983737">Mes</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> quere saber se estás utilizando este dispositivo de maneira activa</translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb
index 3e9214417..ed98c06a 100644
--- a/components/strings/components_strings_gu.xtb
+++ b/components/strings/components_strings_gu.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">નાપસંદ કરેલી સુવિધાઓ</translation>
 <translation id="131405271941274527">જ્યારે તમે NFC ડિવાઇસ પર તમારા ફોન પર ટૅપ કરો, ત્યારે <ph name="URL" /> માહિતી મોકલવા અને પ્રાપ્ત કરવા માગે છે</translation>
 <translation id="1314509827145471431">જમણી બાજુએ જોડો</translation>
+<translation id="1319245136674974084">આ ઍપ માટે ફરીથી પૂછશો નહીં</translation>
 <translation id="1320233736580025032">Prc1 (એન્વલપ)</translation>
 <translation id="132301787627749051">ક્લિપબોર્ડ છબી શોધો</translation>
 <translation id="1323433172918577554">વધુ બતાવો</translation>
@@ -743,6 +744,7 @@
 <translation id="3655670868607891010">જો તમે આ વારંવાર જોઈ રહ્યાં છો, તો આ <ph name="HELP_LINK" /> અજમાવી જુઓ.</translation>
 <translation id="3658742229777143148">પુનરાવર્તન</translation>
 <translation id="3664782872746246217">કીવર્ડ:</translation>
+<translation id="3671540257457995106">કદ બદલવાની મંજૂરી આપીએ?</translation>
 <translation id="3676592649209844519">ડિવાઇસ ID:</translation>
 <translation id="3677008721441257057">શું તમારો અર્થ &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; હતો?</translation>
 <translation id="3678029195006412963">વિનંતી પર સહી કરી શક્યાં નથી</translation>
@@ -1103,6 +1105,7 @@
 <translation id="4953689047182316270">ઍક્સેસિબિલિટી ઇવેન્ટનો જવાબ આપો</translation>
 <translation id="4955242332710481440">A5-અતિરિક્ત</translation>
 <translation id="4958444002117714549">સૂચિ વિસ્તૃત કરો</translation>
+<translation id="4968522289500246572">આ ઍપ મોબાઇલ માટે બનાવવામાં આવી છે અને કદાચ તે યોગ્ય રીતે કદ બદલી શકશે નહીં. ઍપમાં સમસ્યાઓ આવી શકે છે અથવા તે ફરી શરૂ થઈ શકે છે.</translation>
 <translation id="4973922308112707173">ઉપરની બાજુએ બે કાણાં પાડો</translation>
 <translation id="4974590756084640048">ચેતવણીઓ ફરીથી ચાલુ કરો</translation>
 <translation id="4984088539114770594">માઇક્રોફોનનો ઉપયોગ કરીએ?</translation>
@@ -1151,6 +1154,7 @@
 <translation id="5123063207673082822">વીકએન્ડ</translation>
 <translation id="5125394840236832993">B-પ્લસ</translation>
 <translation id="5126510351761255129">તમારું કાર્ડ ચકાસો</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> કદાચ યોગ્ય રીતે કદ બદલી શકશે નહીં. ઍપમાં અનુભવાતી સમસ્યા અટકાવવા માટે, વિન્ડોના પ્રીસેટ કરેલા કદનો ઉપયોગ કરો.</translation>
 <translation id="5135404736266831032">સરનામા મેનેજ કરો…</translation>
 <translation id="5138014172396933048">હમણાં વર્ચ્યુઅલ કાર્ડ ઉપલબ્ધ નથી, કૃપા કરીને તમારી બેંકનો સંપર્ક કરો</translation>
 <translation id="5138227688689900538">ઓછું બતાવો</translation>
@@ -1517,6 +1521,7 @@
 <translation id="647261751007945333">ડિવાઇસ પૉલિસીઓ</translation>
 <translation id="6476284679642588870">ચુકવણી પદ્ધતિઓ મેનેજ કરો</translation>
 <translation id="6489534406876378309">ક્રેશ અપલોડ કરવાનું શરૂ કરો</translation>
+<translation id="6493924760403974580">આ ઍપ માત્ર આ કદને સપોર્ટ કરે છે.</translation>
 <translation id="6499038740797743453">પાસવર્ડ રીસેટ કરીએ?</translation>
 <translation id="6502991525169604759">તમારા ફેરફારો વિના</translation>
 <translation id="6508722015517270189">Chrome ને પુનઃપ્રારંભ કરો</translation>
@@ -2171,6 +2176,7 @@
 <translation id="8975263830901772334">તમે પ્રિન્ટ કરો તે ફાઇલોના નામ</translation>
 <translation id="8978053250194585037">Google Safe Browsingને <ph name="SITE" /> પર તાજેતરમાં <ph name="BEGIN_LINK" />ફિશિંગ થયાનું જાણવા મળ્યું છે<ph name="END_LINK" />. ફિશિંગ વેબસાઇટ તમને છેતરવા માટે અન્ય વેબસાઇટ હોવાનો ઢોંગ કરે છે.</translation>
 <translation id="8983003182662520383">Google Payનો ઉપયોગ કરતી ચુકવણી પદ્ધતિઓ અને ઍડ્રેસ</translation>
+<translation id="8983369100812962543">તમે હવે ઍપનું કદ બદલી શકો છો</translation>
 <translation id="8987927404178983737">મહિનો</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> જાણવા માગે છે કે તમે સક્રિય રૂપે આ ડિવાઇસનો ઉપયોગ ક્યારે કરો છો</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb
index b1eb52e93..e227374 100644
--- a/components/strings/components_strings_hi.xtb
+++ b/components/strings/components_strings_hi.xtb
@@ -745,7 +745,7 @@
 <translation id="3655670868607891010">अगर आपको यह बार-बार दिखाई दे रहा हो, तो इन <ph name="HELP_LINK" /> को आज़माएं.</translation>
 <translation id="3658742229777143148">पुनरीक्षण</translation>
 <translation id="3664782872746246217">कीवर्ड:</translation>
-<translation id="3671540257457995106">क्या आप साइज़ बदलने की अनुमति देते हैं?</translation>
+<translation id="3671540257457995106">डिसप्ले का साइज़ बदलना चाहते हैं?</translation>
 <translation id="3676592649209844519">डिवाइस आईडी:</translation>
 <translation id="3677008721441257057">क्या आपका मतलब &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; से था?</translation>
 <translation id="3678029195006412963">अनुरोध पर हस्ताक्षर नहीं किया जा सका</translation>
@@ -1106,7 +1106,7 @@
 <translation id="4953689047182316270">सुलभता इवेंट का जवाब दें</translation>
 <translation id="4955242332710481440">ए5-एक्स्ट्रा</translation>
 <translation id="4958444002117714549">पूरी सूची दिखाएं</translation>
-<translation id="4968522289500246572">यह ऐप्लिकेशन, मोबाइल के लिए डिज़ाइन किया गया है और हो सकता है कि इसका साइज़ सही तरीके से न बदले. इस ऐप्लिकेशन को इस्तेमाल करने में आपको समस्याएं आ सकती हैं या रीस्टार्ट करना पड़ सकता है.</translation>
+<translation id="4968522289500246572">यह ऐप्लिकेशन, मोबाइल के लिए डिज़ाइन किया गया है और हो सकता है कि इसका डिसप्ले, डिवाइस के विंडो साइज़ के हिसाब से न बदले. इस ऐप्लिकेशन को इस्तेमाल करते समय आपको समस्याओं का सामना करना पड़ सकता है या इसे रीस्टार्ट करना पड़ सकता है.</translation>
 <translation id="4973922308112707173">सबसे ऊपर ड्युएल पंच</translation>
 <translation id="4974590756084640048">चेतावनियां फिर से चालू करें</translation>
 <translation id="4984088539114770594">क्या आप माइक्रोफ़ोन का इस्तेमाल करना चाहते हैं?</translation>
@@ -1155,7 +1155,7 @@
 <translation id="5123063207673082822">शनिवार और रविवार</translation>
 <translation id="5125394840236832993">बी-प्लस</translation>
 <translation id="5126510351761255129">कार्ड की पुष्टि करें</translation>
-<translation id="512670116361803001">हो सकता है कि <ph name="APP_NAME" /> का साइज़ सही तरीके से न बदले. ऐप्लिकेशन में समस्याओं से बचने के लिए, प्रीसेट विंडो साइज़ का इस्तेमाल करें.</translation>
+<translation id="512670116361803001">हो सकता है कि <ph name="APP_NAME" /> का डिसप्ले, डिवाइस के वि़ंडो साइज़ के हिसाब से न बदले. ऐप्लिकेशन इस्तेमाल करने में आने वाली समस्याओं से बचने के लिए, प्रीसेट विंडो साइज़ का इस्तेमाल करें.</translation>
 <translation id="5135404736266831032">पते प्रबंधित करें...</translation>
 <translation id="5138014172396933048">इस समय वर्चुअल कार्ड उपलब्ध नहीं है, कृपया अपने बैंक से संपर्क करें</translation>
 <translation id="5138227688689900538">कम दिखाएं</translation>
@@ -1522,7 +1522,7 @@
 <translation id="647261751007945333">डिवाइस नीतियां</translation>
 <translation id="6476284679642588870">भुगतान के तरीकों को प्रबंधित करें</translation>
 <translation id="6489534406876378309">क्रैश अपलोड करना प्रारंभ करें</translation>
-<translation id="6493924760403974580">यह ऐप्लिकेशन सिर्फ़ इसी साइज़ पर काम करता है.</translation>
+<translation id="6493924760403974580">इस ऐप्लिकेशन का डिसप्ले, सिर्फ़ मोबाइल के वि़ंडो साइज़ के लिए तैयार किया गया है</translation>
 <translation id="6499038740797743453">क्या पासवर्ड रीसेट करना चाहते हैं?</translation>
 <translation id="6502991525169604759">बिना बदलाव के मूल दस्तावेज़ डाउनलोड करें</translation>
 <translation id="6508722015517270189">Chrome को फिर से शुरू करें</translation>
@@ -2178,7 +2178,7 @@
 <translation id="8975263830901772334">उन फ़ाइलों के नाम जिन्हें आप प्रिंट करते हैं</translation>
 <translation id="8978053250194585037">Google सुरक्षित ब्राउज़िंग को <ph name="SITE" /> पर हाल ही में <ph name="BEGIN_LINK" />फ़िशिंग का पता चला है<ph name="END_LINK" />. फ़िशिंग साइटें आपको भ्रमित करने के लिए अन्य वेबसाइटें होने का दिखावा करती हैं.</translation>
 <translation id="8983003182662520383">Google Pay का इस्तेमाल करने वाले भुगतान के तरीके और पते</translation>
-<translation id="8983369100812962543">अब आप ऐप्लिकेशन का साइज़ बदल सकते हैं</translation>
+<translation id="8983369100812962543">अब आप ऐप्लिकेशन का डिसप्ले, डिवाइस के वि़ंडो साइज़ के हिसाब से बदल सकते हैं.</translation>
 <translation id="8987927404178983737">माह</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> को यह जानना है कि आप इस डिवाइस का इस्तेमाल कब करते हैं</translation>
diff --git a/components/strings/components_strings_ml.xtb b/components/strings/components_strings_ml.xtb
index 3d97e4a..7524e3b 100644
--- a/components/strings/components_strings_ml.xtb
+++ b/components/strings/components_strings_ml.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">അവസാനിപ്പിച്ച ഫീച്ചറുകൾ</translation>
 <translation id="131405271941274527">ഒരു NFC ഉപകരണത്തിൽ നിങ്ങളുടെ ഫോൺ ടാപ്പ് ചെയ്യുമ്പോൾ വിവരങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും <ph name="URL" /> താൽപ്പര്യപ്പെടുന്നു</translation>
 <translation id="1314509827145471431">വലതുവശത്ത് ബൈൻഡ് ചെയ്യുക</translation>
+<translation id="1319245136674974084">ഈ ആപ്പിൽ വീണ്ടും ആവശ്യപ്പെടരുത്</translation>
 <translation id="1320233736580025032">Prc1 (എൻവലപ്പ്)</translation>
 <translation id="132301787627749051">ക്ലിപ്പ്ബോർഡ് ചിത്രത്തിനായി തിരയുക</translation>
 <translation id="1323433172918577554">കൂടുതൽ കാണിക്കുക</translation>
@@ -738,6 +739,7 @@
 <translation id="3655670868607891010">നിങ്ങൾ ഇത് പതിവായി കാണുന്നുണ്ടെങ്കിൽ, ഈ <ph name="HELP_LINK" /> പരീക്ഷിക്കൂ.</translation>
 <translation id="3658742229777143148">പുനരവലോകനം</translation>
 <translation id="3664782872746246217">കീവേഡുകൾ:</translation>
+<translation id="3671540257457995106">വലുപ്പം മാറ്റാൻ അനുവദിക്കണോ?</translation>
 <translation id="3676592649209844519">ഉപകരണ ഐഡി:</translation>
 <translation id="3677008721441257057">&lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; എന്നാണോ ഉദ്ദേശിച്ചത്?</translation>
 <translation id="3678029195006412963">അഭ്യർത്ഥന സൈൻ ചെയ്യാനായില്ല</translation>
@@ -1096,6 +1098,7 @@
 <translation id="4953689047182316270">ഉപയോഗസഹായി ഇവന്റുകളോട് പ്രതികരിക്കുക</translation>
 <translation id="4955242332710481440">A5-അധികം</translation>
 <translation id="4958444002117714549">ലിസ്റ്റ് വിപുലീകരിക്കുക</translation>
+<translation id="4968522289500246572">ഈ ആപ്പ് മൊബൈലിനായി രൂപകൽപ്പന ചെയ്തതാണ്, അതിന്റെ വലുപ്പം ഉദ്ദേശിക്കുന്ന രീതിയിൽ മാറ്റാൻ കഴിഞ്ഞേക്കില്ല. ആപ്പിന് പ്രശ്നങ്ങൾ നേരിട്ടേക്കാം അല്ലെങ്കിൽ അത് റീസ്റ്റാർട്ട് ചെയ്തേക്കാം.</translation>
 <translation id="4973922308112707173">മുകളിൽ ഇരട്ട പഞ്ച് ചെയ്യുക</translation>
 <translation id="4974590756084640048">മുന്നറിയിപ്പുകൾ വീണ്ടും പ്രവർത്തനക്ഷമമാക്കുക</translation>
 <translation id="4984088539114770594">മൈക്രോഫോൺ ഉപയോഗിക്കണോ?</translation>
@@ -1144,6 +1147,7 @@
 <translation id="5123063207673082822">വാരാന്ത്യം</translation>
 <translation id="5125394840236832993">B-പ്ലസ്</translation>
 <translation id="5126510351761255129">നിങ്ങളുടെ കാർഡ് പരിശോധിച്ചുറപ്പിക്കുക</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> ഉദ്ദേശിക്കുന്ന രീതിയിൽ വലുപ്പം മാറ്റാൻ കഴിഞ്ഞേക്കില്ല. പ്രശ്‌നങ്ങൾ നേരിടുന്നതിൽ നിന്ന് ആപ്പിനെ തടയാൻ പ്രീസെറ്റ് വിൻഡോ വലുപ്പങ്ങൾ ഉപയോഗിക്കുക.</translation>
 <translation id="5135404736266831032">വിലാസങ്ങൾ മാനേജ് ചെയ്യുക...</translation>
 <translation id="5138227688689900538">കുറച്ച് കാണിക്കുക</translation>
 <translation id="514010763713772514">അടുത്ത തവണ കൂടുതൽ വേഗത്തിൽ ചെക്ക് ഔട്ട് ചെയ്യുക</translation>
@@ -1508,6 +1512,7 @@
 <translation id="647261751007945333">ഉപകരണ നയങ്ങൾ</translation>
 <translation id="6476284679642588870">പേയ്മെൻ്റ് രീതികൾ മാനേജ് ചെയ്യുക</translation>
 <translation id="6489534406876378309">ക്രാഷുകൾ അപ്‌ലോഡുചെയ്യുന്നത് ആരംഭിക്കുക</translation>
+<translation id="6493924760403974580">ഈ ആപ്പ് ഈ വലുപ്പം മാത്രമേ പിന്തുണയ്ക്കുന്നുള്ളൂ.</translation>
 <translation id="6499038740797743453">പാസ്‌വേഡ് റീസെറ്റ് ചെയ്യണോ?</translation>
 <translation id="6502991525169604759">നിങ്ങൾ വരുത്തിയ മാറ്റങ്ങൾ ഇല്ലാതെ</translation>
 <translation id="6508722015517270189">Chrome റീസ്‌റ്റാർട്ടുചെയ്യുക</translation>
@@ -2157,6 +2162,7 @@
 <translation id="8975263830901772334">നിങ്ങൾ പ്രിൻ്റ് ചെയ്യുന്ന ഫയലുകളുടെ പേരുകൾ</translation>
 <translation id="8978053250194585037">Google സുരക്ഷിത ബ്രൗസിംഗ് ഈയിടെ <ph name="SITE" />-ൽ <ph name="BEGIN_LINK" />ഫിഷിംഗ് കണ്ടെത്തി<ph name="END_LINK" />. നിങ്ങളെ കബളിപ്പിക്കാൻ ഫിഷിംഗ് സൈറ്റുകൾ മറ്റു വെബ്‌സൈറ്റുകളെന്ന നിലയിൽ ഭാവിക്കും.</translation>
 <translation id="8983003182662520383">Google Pay ഉപയോഗിക്കുന്ന വിലാസങ്ങളും പേയ്മെന്റ് രീതികളും</translation>
+<translation id="8983369100812962543">നിങ്ങൾക്ക് ഇപ്പോൾ ആപ്പിന്റെ വലുപ്പം മാറ്റാനാകും</translation>
 <translation id="8987927404178983737">മാസം</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">നിങ്ങൾ ഈ ഉപകരണം സജീവമായി ഉപയോഗിക്കുന്നത് അറിയാൻ <ph name="URL" /> ആഗ്രഹിക്കുന്നു</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb
index f607a5d6e0..503fa77c 100644
--- a/components/strings/components_strings_mr.xtb
+++ b/components/strings/components_strings_mr.xtb
@@ -1105,7 +1105,7 @@
 <translation id="4953689047182316270">ॲक्सेसिबिलिटी कामक्रमांना प्रतिसाद द्या</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">सूची विस्तार करा</translation>
-<translation id="4968522289500246572">हे ॲप मोबाइलसाठी डिझाइन केले असून योग्यप्रकारे आकार बदलू शकणार नाही. अ‍ॅपमध्ये समस्या येऊ शकतात किंवा रीस्टार्ट करा.</translation>
+<translation id="4968522289500246572">हे ॲप मोबाइलसाठी डिझाइन केले असून योग्यप्रकारे आकार बदलू शकणार नाही. अ‍ॅपमध्ये समस्या येऊ शकतात किंवा रीस्टार्ट होऊ शकते.</translation>
 <translation id="4973922308112707173">ड्युअल पंच टॉप</translation>
 <translation id="4974590756084640048">चेतावण्या पुन्हा सुरू करा</translation>
 <translation id="4984088539114770594">मायक्रोफोन वापरायचा का?</translation>
diff --git a/components/strings/components_strings_ne.xtb b/components/strings/components_strings_ne.xtb
index 9209742..28bc7a0 100644
--- a/components/strings/components_strings_ne.xtb
+++ b/components/strings/components_strings_ne.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">चल्तीबाट हटाइएका सुविधाहरू</translation>
 <translation id="131405271941274527"><ph name="URL" /> तपाईंले NFC यन्त्रहरूमा ट्याप गर्दा जानकारी पठाउन तथा प्राप्त गर्न चाहन्छ</translation>
 <translation id="1314509827145471431">दायाँ बाइन्ड</translation>
+<translation id="1319245136674974084">यो एपका हकमा फेरि नसोधियोस्</translation>
 <translation id="1320233736580025032">Prc1 (Envelope)</translation>
 <translation id="132301787627749051">क्लिपबोर्डको छवि खोज्नुहोस्</translation>
 <translation id="1323433172918577554">थप देखाउनुहोस्</translation>
@@ -741,6 +742,7 @@
 <translation id="3655670868607891010">यदि तपाईं यो बारम्बार रूपमा देखिरहनुभएको छ भने, यिनीहरू गर्ने प्रयास गर्नुहोस् <ph name="HELP_LINK" />।</translation>
 <translation id="3658742229777143148">संशोधन</translation>
 <translation id="3664782872746246217">किवर्डहरू:</translation>
+<translation id="3671540257457995106">आकार बदल्न दिने हो?</translation>
 <translation id="3676592649209844519">यन्त्रको ID:</translation>
 <translation id="3677008721441257057">तपाईंले &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; भन्न खोज्नुभएको हो?</translation>
 <translation id="3678029195006412963">अनुरोधमा हस्ताक्षर गर्न सकिएन</translation>
@@ -1100,6 +1102,7 @@
 <translation id="4953689047182316270">पहुँचसम्बन्धी कार्यक्रमहरूमा प्रतिक्रिया दिनुहोस्</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">सूची विस्तारित गर्नुहोस्</translation>
+<translation id="4968522289500246572">यो एप मोबाइलमा चलाउने प्रयोजनले बनाइएको हो र यसको आकार सही तरिकाले परिवर्तन नहुन सक्छ। यो एपमा समस्या देखिन सक्छ वा यो एप आफैँ रिस्टार्ट हुन सक्छ।</translation>
 <translation id="4973922308112707173">सिरानमा दुई प्वाल</translation>
 <translation id="4974590756084640048">चेतावनीहरूलाई पुन:सक्षम पार्नुहोस्</translation>
 <translation id="4984088539114770594">माइक्रोफोन प्रयोग गर्ने हो?</translation>
@@ -1148,6 +1151,7 @@
 <translation id="5123063207673082822">सप्ताहान्त</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">आफ्नो कार्ड पुष्टि गर्नुहोस्</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> को आकार सही तरिकाले परिवर्तन नहुन सक्छ। एपमा कुनै समस्या नआओस् भन्नाका खातिर विन्डोको पूर्वनिर्धारित आकार प्रयोग गर्नुहोस्।</translation>
 <translation id="5135404736266831032">ठेगानाहरू व्यवस्थित गर्नुहोस्...</translation>
 <translation id="5138014172396933048">भर्चुअल कार्ड हाल उपलब्ध छैन। कृपया आफ्नो बैंकमा सम्पर्क गर्नुहोस्</translation>
 <translation id="5138227688689900538">कम देखाउनुहोस्</translation>
@@ -1514,6 +1518,7 @@
 <translation id="647261751007945333">यन्त्र नीतिहरू</translation>
 <translation id="6476284679642588870">भुक्तानी विधिहरू व्यवस्थित गर्नुहोस्</translation>
 <translation id="6489534406876378309">क्रयासहरू अपलोड गर्न सुरु गर्नुहोस्</translation>
+<translation id="6493924760403974580">यो एप यो आकारमा मात्र चल्छ।</translation>
 <translation id="6499038740797743453">पासवर्ड रिसेट गर्ने हो?</translation>
 <translation id="6502991525169604759">तपाईंले गर्नुभएका परिवर्तन लागू नगरी</translation>
 <translation id="6508722015517270189">Chrome पुनः सुरु गर्नुहोस्</translation>
@@ -2168,6 +2173,7 @@
 <translation id="8975263830901772334">तपाईंले प्रिन्ट गर्ने फाइलका नामहरू</translation>
 <translation id="8978053250194585037">Google Safe Browsing ले हालै <ph name="SITE" /> मा <ph name="BEGIN_LINK" />फिसिङ पत्ता लगायो<ph name="END_LINK" />। फिसिङमार्फत आक्रमण गर्ने साइटहरूले तपाईंलाई झुक्याउन आफूलाई अन्य बेवसाइटका रूपमा प्रस्तुत गर्दछन्।</translation>
 <translation id="8983003182662520383">Google Pay को प्रयोग गर्ने भुक्तानी विधि र ठेगानाहरू</translation>
+<translation id="8983369100812962543">तपाईं अब एपको आकार बदल्न सक्नुहुन्छ</translation>
 <translation id="8987927404178983737">महिना</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> ले तपाईं यो डिभाइस चलाउँदै हुनुहुन्छ कि हुनुहुन्छ भन्ने कुराको जानकारी माग्दै छ</translation>
diff --git a/components/strings/components_strings_or.xtb b/components/strings/components_strings_or.xtb
index a4a9e19..8eabac6 100644
--- a/components/strings/components_strings_or.xtb
+++ b/components/strings/components_strings_or.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">ଅଗ୍ରାହ୍ୟ କରାଯାଇଥିବା ଫିଚର୍‍ଗୁଡ଼ିକ</translation>
 <translation id="131405271941274527">ଏକ NFC ଡିଭାଇସ୍‌ରେ ଆପଣ ନିଜର ଫୋନ୍ ଟାପ୍ କରିବା ପରେ <ph name="URL" /> ସୂଚନା ପଠାଇବାକୁ ତଥା ପ୍ରାପ୍ତ କରିବାକୁ ଚାହେଁ</translation>
 <translation id="1314509827145471431">ଡାହାଣ ପଟରେ ବାଇଣ୍ଡ</translation>
+<translation id="1319245136674974084">ଏହି ଆପ୍ ପାଇଁ ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ</translation>
 <translation id="1320233736580025032">Prc1 (ଏନଭଲପ୍)</translation>
 <translation id="132301787627749051">କ୍ଲିପ୍‌ବୋର୍ଡ ଛବି ଖୋଜନ୍ତୁ</translation>
 <translation id="1323433172918577554">ଅଧିକ ଦେଖାନ୍ତୁ</translation>
@@ -737,6 +738,7 @@
 <translation id="3655670868607891010">ଯଦି ଆପଣ ଏହାକୁ ବାରମ୍ବାର ଦେଖୁଛନ୍ତି, ତେବେ ଏହି <ph name="HELP_LINK" />କୁ ଦେଖିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।</translation>
 <translation id="3658742229777143148">ପୁନରାବୃତ୍ତି</translation>
 <translation id="3664782872746246217">କୀୱାର୍ଡଗୁଡ଼ିକ:</translation>
+<translation id="3671540257457995106">ରିସାଇଜ୍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ?</translation>
 <translation id="3676592649209844519">ଡିଭାଇସ୍‌ ID:</translation>
 <translation id="3677008721441257057">ଆପଣଙ୍କର କହିବା ଅର୍ଥ &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;କି?</translation>
 <translation id="3678029195006412963">ଅନୁରୋଧରେ ଦସ୍ତଖତ କରାଯାଇପାରିଲା ନାହିଁ</translation>
@@ -1092,6 +1094,7 @@
 <translation id="4953689047182316270">ଆକ୍ସେସିବିଲିଟୀ ଇଭେଣ୍ଟକୁ ପ୍ରତିକ୍ରିୟା ଦିଏ</translation>
 <translation id="4955242332710481440">A5-ଅତିରିକ୍ତ</translation>
 <translation id="4958444002117714549">ତାଲିକାକୁ ପ୍ରସାରିତ କରନ୍ତୁ</translation>
+<translation id="4968522289500246572">ଏହି ଆପକୁ ମୋବାଇଲ ପାଇଁ ଡିଜାଇନ୍ କରାଯାଇଛି ଏବଂ ଏହା ଭଲ ଭାବରେ ରିସାଇଜ୍ ହୋଇନପାରେ। ଆପରେ ସମସ୍ୟା ହୋଇପାରେ କିମ୍ୱା ଏହା ରିଷ୍ଟାର୍ଟ ହୋଇପାରେ।</translation>
 <translation id="4973922308112707173">ଉପର ପଟରେ ଦୁଇଟି ପଞ୍ଚ୍</translation>
 <translation id="4974590756084640048">ଚେତାବନୀ ପୁଣି ସକ୍ଷମ କରନ୍ତୁ</translation>
 <translation id="4984088539114770594">ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର କରିବେ?</translation>
@@ -1140,6 +1143,7 @@
 <translation id="5123063207673082822">ସପ୍ତାହର ଶେଷ ଦିନ</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">ଆପଣଙ୍କର କାର୍ଡ ଯାଞ୍ଚ କରନ୍ତୁ</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> ଭଲ ଭାବରେ ରିସାଇଜ୍ ହୋଇନପାରେ। ଆପରେ ହୋଇଥିବା ସମସ୍ୟାକୁ ପ୍ରତିରୋଧ କରିବା ପାଇଁ ୱିଣ୍ଡୋର ପ୍ରିସେଟ୍ ଆକାରଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।</translation>
 <translation id="5135404736266831032">ଠିକଣାଗୁଡ଼ିକ ପରିଚାଳିତ କରନ୍ତୁ...</translation>
 <translation id="5138014172396933048">ଭର୍ଚୁଆଲ୍ କାର୍ଡ ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ, ଦୟାକରି ଆପଣଙ୍କ ବ୍ୟାଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ</translation>
 <translation id="5138227688689900538">ଅଳ୍ପ ଦେଖାନ୍ତୁ</translation>
@@ -1505,6 +1509,7 @@
 <translation id="647261751007945333">ଡିଭାଇସ୍ ନୀତି</translation>
 <translation id="6476284679642588870">ପେମେଣ୍ଟ ପଦ୍ଧତିଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ</translation>
 <translation id="6489534406876378309">କ୍ରାସ୍‌ଗୁଡ଼ିକ ଅପ୍‌ଲୋଡ୍‌ କରିବା ଆରମ୍ଭ କରନ୍ତୁ</translation>
+<translation id="6493924760403974580">ଏହି ଆପ୍ କେବଳ ଏହି ଆକାରକୁ ସମର୍ଥନ କରେ।</translation>
 <translation id="6499038740797743453">ପାସ୍‍ୱର୍ଡ ରିସେଟ୍ କରିବେ?</translation>
 <translation id="6502991525169604759">ଆପଣଙ୍କ ପରିବର୍ତ୍ତନଗୁଡ଼ିକ ବିନା</translation>
 <translation id="6508722015517270189">Chrome ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ</translation>
@@ -2159,6 +2164,7 @@
 <translation id="8975263830901772334">ଆପଣ ପ୍ରିଣ୍ଟ୍ କରୁଥିବା ଫାଇଲ୍‌ଗୁଡ଼ିକର ନାମ</translation>
 <translation id="8978053250194585037">Google ସେଫ୍ ବ୍ରାଉଜିଂ, ସମ୍ପ୍ରତି <ph name="SITE" />ରେ <ph name="BEGIN_LINK" />ଫିସିଂ ଚିହ୍ନଟ କରିଛି<ph name="END_LINK" />। ଫିସିଂ ୱେବ୍‍ସାଇଟ୍‍ଗୁଡ଼ିକ ଆପଣଙ୍କୁ ପ୍ରତରଣା କରିବା ପାଇଁ ଅନ୍ୟ ୱେବ୍‍ସାଇଟ୍ ହେବାର ଛଳନା କରନ୍ତି।</translation>
 <translation id="8983003182662520383">Google Pay ବ୍ୟବହାର କରୁଥିବା ପେମେଣ୍ଟ ପଦ୍ଧତି ଓ ଠିକଣା</translation>
+<translation id="8983369100812962543">ଆପଣ ବର୍ତ୍ତମାନ ଆପକୁ ରିସାଇଜ୍ କରିପାରିବେ</translation>
 <translation id="8987927404178983737">ମାସ</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">ଆପଣ କେତେବେଳେ ଏହି ଡିଭାଇସକୁ ସକ୍ରିୟ ଭାବରେ ବ୍ୟବହାର କରୁଛନ୍ତି ତାହା <ph name="URL" /> ଜାଣିବାକୁ ଚାହୁଁଛି</translation>
diff --git a/components/strings/components_strings_pa.xtb b/components/strings/components_strings_pa.xtb
index 4067e80c..0e0bf7e 100644
--- a/components/strings/components_strings_pa.xtb
+++ b/components/strings/components_strings_pa.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">ਨਾਪਸੰਦ ਕੀਤੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ</translation>
 <translation id="131405271941274527">ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਕਿਸੇ NFC ਡੀਵਾਈਸ 'ਤੇ ਟੈਪ ਕਰਦੇ ਹੋ ਤਾਂ <ph name="URL" /> ਜਾਣਕਾਰੀ ਭੇਜਣਾ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦਾ ਹੈ</translation>
 <translation id="1314509827145471431">ਸੱਜੇ ਜਿਲਦਬੰਦ</translation>
+<translation id="1319245136674974084">ਇਸ ਐਪ ਲਈ ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ</translation>
 <translation id="1320233736580025032">Prc1 (ਲਿਫ਼ਾਫ਼ਾ)</translation>
 <translation id="132301787627749051">ਕਲਿੱਪਬੋਰਡ ਚਿੱਤਰ ਖੋਜੋ</translation>
 <translation id="1323433172918577554">ਹੋਰ ਦਿਖਾਓ</translation>
@@ -737,6 +738,7 @@
 <translation id="3655670868607891010">ਜੇਕਰ ਤੁਸੀਂ ਇਸਨੂੰ ਵਾਰ-ਵਾਰ ਦੇਖ ਰਹੇ ਹੋ, ਇਹਨਾਂ <ph name="HELP_LINK" /> ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।</translation>
 <translation id="3658742229777143148">ਸੁਧਾਈ</translation>
 <translation id="3664782872746246217">ਪ੍ਰਮੁੱਖ-ਸ਼ਬਦ:</translation>
+<translation id="3671540257457995106">ਕੀ ਆਕਾਰ ਬਦਲਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?</translation>
 <translation id="3676592649209844519">ਡੀਵਾਈਸ ਆਈ.ਡੀ.:</translation>
 <translation id="3677008721441257057">ਕੀ ਤੁਹਾਡਾ ਮਤਲਬ &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; ਤੋਂ ਹੈ?</translation>
 <translation id="3678029195006412963">ਬੇਨਤੀ ਹਸਤਾਖਰਿਤ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ</translation>
@@ -1092,6 +1094,7 @@
 <translation id="4953689047182316270">ਪਹੁੰਚਯੋਗਤਾ ਇਵੈਂਟਾਂ 'ਤੇ ਪ੍ਰਤਿਕਿਰਿਆ ਕਰੋ</translation>
 <translation id="4955242332710481440">A5-ਵਾਧੂ</translation>
 <translation id="4958444002117714549">ਸੂਚੀ ਦਾ ਵਿਸਤਾਰ ਕਰੋ</translation>
+<translation id="4968522289500246572">ਇਹ ਐਪ ਮੋਬਾਈਲ ਲਈ ਡਿਜ਼ਾਈਨ ਕੀਤੀ ਗਈ ਹੈ ਅਤੇ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਸਦਾ ਆਕਾਰ ਸਹੀ ਤਰੀਕੇ ਨਾਲ ਨਾ ਬਦਲੇ। ਐਪ ਵਿਚ ਸਮੱਸਿਆਵਾਂ ਆ ਸਕਦੀਆਂ ਹਨ ਜਾਂ ਮੁੜ-ਸ਼ੁਰੂ ਹੋ ਸਕਦੀ ਹੈ।</translation>
 <translation id="4973922308112707173">ਉੱਪਰ ਦੋ ਮੋਰੀਆਂ</translation>
 <translation id="4974590756084640048">ਚਿਤਾਵਨੀਆਂ ਨੂੰ ਮੁੜ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="4984088539114770594">ਕੀ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਵਰਤਣਾ ਹੈ?</translation>
@@ -1140,6 +1143,7 @@
 <translation id="5123063207673082822">ਵੀਕੈਂਡ</translation>
 <translation id="5125394840236832993">B-ਪਲੱਸ</translation>
 <translation id="5126510351761255129">ਆਪਣੇ ਕਾਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ</translation>
+<translation id="512670116361803001">ਹੋ ਸਕਦਾ ਹੈ ਕਿ <ph name="APP_NAME" /> ਦਾ ਆਕਾਰ ਸਹੀ ਤਰੀਕੇ ਨਾਲ ਨਾ ਬਦਲੇ। ਐਪਾਂ ਵਿਚ ਸਮੱਸਿਆਵਾਂ ਆਉਣ ਤੋਂ ਰੋਕਣ ਲਈ ਵਿੰਡੋ ਦੇ ਪ੍ਰੀਸੈੱਟ ਆਕਾਰਾਂ ਨੂੰ ਵਰਤੋ।</translation>
 <translation id="5135404736266831032">ਪਤਿਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ...</translation>
 <translation id="5138014172396933048">ਇਸ ਸਮੇਂ ਆਭਾਸੀ ਕਾਰਡ ਉਪਲਬਧ ਨਹੀਂ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਬੈਂਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ</translation>
 <translation id="5138227688689900538">ਘੱਟ ਦਿਖਾਓ</translation>
@@ -1505,6 +1509,7 @@
 <translation id="647261751007945333">ਡੀਵਾਈਸ ਨੀਤੀਆਂ</translation>
 <translation id="6476284679642588870">ਭੁਗਤਾਨ ਵਿਧੀਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ</translation>
 <translation id="6489534406876378309">ਕ੍ਰੈਸ਼ ਅਪਲੋਡ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰੋ</translation>
+<translation id="6493924760403974580">ਇਹ ਐਪ ਸਿਰਫ਼ ਇਸ ਆਕਾਰ ਦਾ ਸਮਰਥਨ ਕਰਦੀ ਹੈ।</translation>
 <translation id="6499038740797743453">ਕੀ ਪਾਸਵਰਡ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?</translation>
 <translation id="6502991525169604759">ਤੁਹਾਡੀਆਂ ਤਬਦੀਲੀਆਂ ਤੋਂ ਬਿਨਾਂ</translation>
 <translation id="6508722015517270189">Chrome ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ</translation>
@@ -2159,6 +2164,7 @@
 <translation id="8975263830901772334">ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਿੰਟ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ ਦੇ ਨਾਮ</translation>
 <translation id="8978053250194585037">Google ਸੁਰੱਖਿਅਤ ਖੋਜ ਨੂੰ ਹਾਲ ਹੀ ਵਿੱਚ <ph name="SITE" /> 'ਤੇ <ph name="BEGIN_LINK" />ਧੋਖਾਧੜੀ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ<ph name="END_LINK" />। ਧੋਖਾਧੜੀ ਵਾਲੀਆਂ ਸਾਈਟਾਂ ਤੁਹਾਡੇ ਨਾਲ ਚਾਲਬਾਜ਼ੀ ਕਰਨ ਲਈ ਹੋਰ ਵੈੱਬਸਾਈਟਾਂ ਹੋਣ ਦਾ ਦਿਖਾਵਾ ਕਰਦੀਆਂ ਹਨ।</translation>
 <translation id="8983003182662520383">Google Pay ਦੀ ਵਰਤੋਂ ਕਰਨ ਵਾਲੀਆਂ ਭੁਗਤਾਨ ਵਿਧੀਆਂ ਅਤੇ ਪਤੇ</translation>
+<translation id="8983369100812962543">ਹੁਣ ਤੁਸੀਂ ਐਪ ਦਾ ਆਕਾਰ ਬਦਲ ਸਕਦੇ ਹੋ</translation>
 <translation id="8987927404178983737">ਮਹੀਨਾ</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> ਜਾਣਨਾ ਚਾਹੁੰਦਾ ਹੈ ਕਿ ਤੁਸੀਂ ਕਿਰਿਆਸ਼ੀਲ ਤੌਰ 'ਤੇ ਇਸ ਡੀਵਾਈਸ ਦੀ ਵਰਤੋਂ ਕਦੋਂ ਕਰਦੇ ਹੋ</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb
index 85745aa..b0cc6c6 100644
--- a/components/strings/components_strings_ru.xtb
+++ b/components/strings/components_strings_ru.xtb
@@ -1145,7 +1145,7 @@
 <translation id="5123063207673082822">До выходных</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Подтвердите данные карты</translation>
-<translation id="512670116361803001">Если размер приложения "<ph name="APP_NAME" />" изменить, оно может работать некорректно. Чтобы избежать этого, используйте стандартные размеры.</translation>
+<translation id="512670116361803001">Если размер приложения "<ph name="APP_NAME" />" изменить, оно может работать некорректно. Чтобы избежать проблем, используйте стандартные размеры.</translation>
 <translation id="5135404736266831032">Управление адресами…</translation>
 <translation id="5138014172396933048">Сейчас виртуальная карта недоступна. Обратитесь в свой банк.</translation>
 <translation id="5138227688689900538">Свернуть</translation>
diff --git a/components/strings/components_strings_sq.xtb b/components/strings/components_strings_sq.xtb
index 73e6f19..d0c5d1a 100644
--- a/components/strings/components_strings_sq.xtb
+++ b/components/strings/components_strings_sq.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">Veçori të vjetruara</translation>
 <translation id="131405271941274527"><ph name="URL" /> dëshiron që të dërgojë dhe të marrë informacion kur troket te telefoni në një pajisje me NFC</translation>
 <translation id="1314509827145471431">Lidhje djathtas</translation>
+<translation id="1319245136674974084">Mos pyet përsëri për këtë aplikacion</translation>
 <translation id="1320233736580025032">Prc1 (Zarf)</translation>
 <translation id="132301787627749051">Kërko për imazhin e kujtesës së fragmenteve</translation>
 <translation id="1323433172918577554">Shfaq më shumë</translation>
@@ -743,6 +744,7 @@
 <translation id="3655670868607891010">Nëse e shikon këtë vazhdimisht, provo këto <ph name="HELP_LINK" />.</translation>
 <translation id="3658742229777143148">Rishikim</translation>
 <translation id="3664782872746246217">Fjalët kyçe:</translation>
+<translation id="3671540257457995106">Të lejohet ndryshimi i përmasave?</translation>
 <translation id="3676592649209844519">ID-ja e pajisjes:</translation>
 <translation id="3677008721441257057">Mos dëshiron të thuash &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
 <translation id="3678029195006412963">Kërkesa nuk mund të nënshkruhej</translation>
@@ -1101,6 +1103,7 @@
 <translation id="4953689047182316270">Reago ndaj ngjarjeve të qasshmërisë</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">Zgjero listën</translation>
+<translation id="4968522289500246572">Ky aplikacion është projektuar për celular dhe përmasat mund të mos ndryshohen si duhet. Aplikacioni mund të ketë probleme ose të riniset.</translation>
 <translation id="4973922308112707173">Dy shpime lart</translation>
 <translation id="4974590756084640048">Aktivizo përsëri paralajmërimet</translation>
 <translation id="4984088539114770594">Të përdoret mikrofoni?</translation>
@@ -1149,6 +1152,7 @@
 <translation id="5123063207673082822">Fundjavë</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">Verifiko kartën tënde</translation>
+<translation id="512670116361803001">Përmasat e <ph name="APP_NAME" /> mund të mos ndryshohen si duhet. Përdor madhësitë e paravendosura të dritares për të parandaluar problemet e aplikacionit.</translation>
 <translation id="5135404736266831032">Menaxho adresat...</translation>
 <translation id="5138014172396933048">Karta virtuale nuk ofrohet për momentin, kontakto me bankën tënde</translation>
 <translation id="5138227688689900538">Shfaq më pak</translation>
@@ -1514,6 +1518,7 @@
 <translation id="647261751007945333">Politikat e pajisjes</translation>
 <translation id="6476284679642588870">Menaxho mënyrat e pagesës</translation>
 <translation id="6489534406876378309">Nis ngarkimin e ndërprerjeve aksidentale</translation>
+<translation id="6493924760403974580">Ky aplikacion mbështet vetëm këtë madhësi.</translation>
 <translation id="6499038740797743453">Të rivendoset fjalëkalimi?</translation>
 <translation id="6502991525169604759">Pa ndryshimet e tua</translation>
 <translation id="6508722015517270189">Rinis Chrome</translation>
@@ -2168,6 +2173,7 @@
 <translation id="8975263830901772334">Emrat e skedarëve që printon</translation>
 <translation id="8978053250194585037">"Shfletimi i sigurt i Google" <ph name="BEGIN_LINK" />zbuloi së fundi mashtrime<ph name="END_LINK" /> në <ph name="SITE" />. Sajtet mashtruese pretendojnë se janë sajte të tjera uebi për të të mashtruar.</translation>
 <translation id="8983003182662520383">Mënyrat e pagesës dhe adresat që përdorin Google Pay</translation>
+<translation id="8983369100812962543">Tani mund t'i ndryshosh përmasat e aplikacionit</translation>
 <translation id="8987927404178983737">Muaji</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> dëshiron të dijë kur ti e përdor këtë pajisje në mënyrë aktive</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb
index b361cf89..22b8ec9d4 100644
--- a/components/strings/components_strings_ta.xtb
+++ b/components/strings/components_strings_ta.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">நிறுத்தப்பட்ட அம்சங்கள்</translation>
 <translation id="131405271941274527">NFC சாதனத்தில் உங்கள் மொபைலைத் தட்டும்போது தகவலை அனுப்புவதற்கும் பெறுவதற்குமான அனுமதி <ph name="URL" />க்குத் தேவை</translation>
 <translation id="1314509827145471431">பைண்டு ரைட்</translation>
+<translation id="1319245136674974084">இந்த ஆப்ஸில் மீண்டும் கேட்காதே</translation>
 <translation id="1320233736580025032">Prc1 (என்வலப்)</translation>
 <translation id="132301787627749051">கிளிப்-போர்டு படத்தைத் தேடும்</translation>
 <translation id="1323433172918577554">மேலும் காட்டு</translation>
@@ -736,6 +737,7 @@
 <translation id="3655670868607891010">இதை அடிக்கடி காண்கிறீர்கள் எனில், <ph name="HELP_LINK" /> ஐ முயற்சிக்கவும்.</translation>
 <translation id="3658742229777143148">மீள்திருத்தங்கள்</translation>
 <translation id="3664782872746246217">தேடல் குறிப்புகள்:</translation>
+<translation id="3671540257457995106">அளவை மாற்ற அனுமதிக்கவா?</translation>
 <translation id="3676592649209844519">சாதன ஐடி:</translation>
 <translation id="3677008721441257057">இதைக் குறிப்பிட்டீர்களா: &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt;?</translation>
 <translation id="3678029195006412963">கோரிக்கையில் கையொப்பமிட முடியவில்லை</translation>
@@ -1096,6 +1098,7 @@
 <translation id="4953689047182316270">அணுகல்தன்மை நிகழ்வுகளுக்குப் பதிலளித்தல்</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">பட்டியலை விரி</translation>
+<translation id="4968522289500246572">மொபைல் சாதனங்களுக்காக இந்த ஆப்ஸ் வடிவமைக்கப்பட்டுள்ளதால் இதன் அளவைச் சரியாக மாற்ற முடியாமல் போகலாம். அத்துடன் இதில் சிக்கல்கள் ஏற்படலாம் அல்லது இது மீண்டும் தொடங்கலாம்.</translation>
 <translation id="4973922308112707173">டூயல் பஞ்ச் டாப்</translation>
 <translation id="4974590756084640048">எச்சரிக்கைகளை மீண்டும் இயக்கு</translation>
 <translation id="4984088539114770594">மைக்ரோஃபோனைப் பயன்படுத்தவா?</translation>
@@ -1144,6 +1147,7 @@
 <translation id="5123063207673082822">வாரயிறுதி</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">உங்கள் கார்டு விவரங்களைச் சரிபார்த்தல்</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> அளவைச் சரியாக மாற்ற முடியாமல் போகலாம். ஆப்ஸில் சிக்கல்கள் ஏற்படுவதைத் தடுக்க, ஏற்கெனவே அமைத்த சாளர அளவுகளைப் பயன்படுத்தவும்.</translation>
 <translation id="5135404736266831032">முகவரிகளை நிர்வகி...</translation>
 <translation id="5138227688689900538">குறைவாகக் காட்டு</translation>
 <translation id="514010763713772514">அடுத்த முறை விரைவாகச் செக்-அவுட் செய்யுங்கள்</translation>
@@ -1507,6 +1511,7 @@
 <translation id="647261751007945333">சாதனக் கொள்கைகள்</translation>
 <translation id="6476284679642588870">கட்டண முறைகளை நிர்வகி</translation>
 <translation id="6489534406876378309">சிதைவுகளைப் பதிவேற்றுவதைத் தொடங்கு</translation>
+<translation id="6493924760403974580">இந்த அளவில் மட்டுமே இந்த ஆப்ஸை மாற்ற முடியும்.</translation>
 <translation id="6499038740797743453">கடவுச்சொல்லை மீட்டமைக்கவா?</translation>
 <translation id="6502991525169604759">அசல் ஆவணத்தைப் பதிவிறக்கு</translation>
 <translation id="6508722015517270189">Chromeஐ மீண்டும் தொடங்கவும்</translation>
@@ -2158,6 +2163,7 @@
 <translation id="8975263830901772334">நீங்கள் அச்சிடும் கோப்புகளின் பெயர்கள்</translation>
 <translation id="8978053250194585037">சமீபத்தில் Google பாதுகாப்பான உலாவலானது <ph name="SITE" /> தளத்தில் <ph name="BEGIN_LINK" />ஃபிஷிங்கைக் கண்டறிந்தது<ph name="END_LINK" />. ஃபிஷிங் தளங்கள் பிற இணையதளங்களைப் போல் காண்பித்து, உங்களை ஏமாற்ற முயற்சிக்கக்கூடும்.</translation>
 <translation id="8983003182662520383">Google Payவைப் பயன்படுத்தும் கட்டண முறைகளும் முகவரிகளும்</translation>
+<translation id="8983369100812962543">இனி நீங்கள் ஆப்ஸின் அளவை மாற்றலாம்</translation>
 <translation id="8987927404178983737">மாதம்</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">இந்தச் சாதனத்தில் நீங்கள் செயலில் இருப்பது குறித்து <ph name="URL" /> அறிந்துகொள்ள விரும்புகிறது</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb
index 19050a26..6130d19 100644
--- a/components/strings/components_strings_te.xtb
+++ b/components/strings/components_strings_te.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">విస్మరించబడిన ఫీచర్‌లు</translation>
 <translation id="131405271941274527">మీరు NFC పరికరంలో మీ ఫోన్‌పై నొక్కినప్పుడు సమాచారం పంపడానికి, అందుకోవడానికి <ph name="URL" /> అనుమతి కోరుతోంది</translation>
 <translation id="1314509827145471431">కుడివైపున బైండ్</translation>
+<translation id="1319245136674974084">ఈ యాప్‌ కోసం మళ్లీ అడగవద్దు</translation>
 <translation id="1320233736580025032">Prc1 (ఎన్వలప్)</translation>
 <translation id="132301787627749051">క్లిప్‌బోర్డ్ చిత్రం కోసం వెతకండి</translation>
 <translation id="1323433172918577554">మరింత చూపు</translation>
@@ -746,6 +747,7 @@
 <translation id="3655670868607891010">మీరు దీన్ని తరచుగా చూస్తుంటే, ఈ <ph name="HELP_LINK" />ని ప్రయత్నించండి.</translation>
 <translation id="3658742229777143148">పునర్విమర్శ</translation>
 <translation id="3664782872746246217">కీవర్డ్‌లు:</translation>
+<translation id="3671540257457995106">పరిమాణం మార్చడానికి అనుమతించాలా?</translation>
 <translation id="3676592649209844519">పరికర ID:</translation>
 <translation id="3677008721441257057">మీరు &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; గురించి అభ్యర్థిస్తున్నారా?</translation>
 <translation id="3678029195006412963">అభ్యర్థనకు సంతకం అందించడం సాధ్యపడలేదు</translation>
@@ -1106,6 +1108,7 @@
 <translation id="4953689047182316270">యాక్సెస్ సామర్థ్యం ఉన్న ఈవెంట్‌లకు ప్రతిస్పందించండి</translation>
 <translation id="4955242332710481440">A5-అదనం</translation>
 <translation id="4958444002117714549">జాబితాను విస్తరించు</translation>
+<translation id="4968522289500246572">ఈ యాప్ మొబైల్ కోసం డిజైన్ చేయబడింది, పరిమాణాన్ని మార్చడం సాధ్యం కాకపోవచ్చు. యాప్‌ను ఉపయోగించేటప్పుడు సమస్యలు ఎదురుకావచ్చు లేదా మీరు రీస్టార్ట్ చేయవలసి రావచ్చు.</translation>
 <translation id="4973922308112707173">ఎగువ భాగంలో రెండు రంధ్రాలు</translation>
 <translation id="4974590756084640048">హెచ్చరికలను మళ్లీ ప్రారంభించు</translation>
 <translation id="4984088539114770594">మైక్రోఫోన్‌ను ఉపయోగించాలా?</translation>
@@ -1154,6 +1157,7 @@
 <translation id="5123063207673082822">వారాంతం</translation>
 <translation id="5125394840236832993">B-ప్లస్</translation>
 <translation id="5126510351761255129">మీ కార్డ్‌ను ధృవీకరించండి</translation>
+<translation id="512670116361803001"><ph name="APP_NAME" /> పరిమాణాన్ని మార్చడం సాధ్యం కాకపోవచ్చు. యాప్‌లో సమస్యలు ఎదురుకాకుండా నివారించడానికి, ప్రీసెట్ చేసిన విండో పరిమాణాలను ఉపయోగించండి.</translation>
 <translation id="5135404736266831032">చిరునామాలను నిర్వహించండి...</translation>
 <translation id="5138014172396933048">ప్రస్తుతానికి వర్చువల్ కార్డ్ అందుబాటులో లేదు, దయచేసి మీ బ్యాంకును సంప్రదించండి</translation>
 <translation id="5138227688689900538">తక్కువ చూపు</translation>
@@ -1520,6 +1524,7 @@
 <translation id="647261751007945333">పరికర విధానాలు</translation>
 <translation id="6476284679642588870">చెల్లింపు పద్ధతులను నిర్వహించండి</translation>
 <translation id="6489534406876378309">క్రాష్‌లను అప్‌లోడ్ చేయడాన్ని ప్రారంభించండి</translation>
+<translation id="6493924760403974580">ఈ యాప్ ఈ పరిమాణాన్ని మాత్రమే సపోర్ట్ చేస్తుంది.</translation>
 <translation id="6499038740797743453">పాస్‌వర్డ్‌ను రీసెట్ చేయాలా?</translation>
 <translation id="6502991525169604759">మీరు చేసిన మార్పులు లేకుండా డౌన్‌లోడ్ చేసుకోండి</translation>
 <translation id="6508722015517270189">Chromeను పునఃప్రారంభించండి</translation>
@@ -2174,6 +2179,7 @@
 <translation id="8975263830901772334">మీరు ముద్రించే ఫైల్‌ల పేర్లు</translation>
 <translation id="8978053250194585037">Google సురక్షిత బ్రౌజింగ్ ఇటీవల <ph name="SITE" />లో <ph name="BEGIN_LINK" />ఫిషింగ్‌ని గుర్తించింది<ph name="END_LINK" />. ఫిషింగ్ సైట్‌లు వేరే వెబ్‌సైట్‌ల వలె ప్రవర్తించడం ద్వారా మిమ్మల్ని మాయ చేయవచ్చు.</translation>
 <translation id="8983003182662520383">Google Payని ఉపయోగిస్తున్న చెల్లింపు పద్ధతులు మరియు చిరునామాలు</translation>
+<translation id="8983369100812962543">మీరు ఇప్పుడు యాప్ పరిమాణం మార్చవచ్చు</translation>
 <translation id="8987927404178983737">నెల</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742">మీరు ఈ పరికరాన్ని యాక్టివ్‌గా ఉపయోగిస్తున్నప్పుడు <ph name="URL" /> ఆ విషయాన్ని తెలుసుకోవాలనుకుంటుంది</translation>
diff --git a/components/strings/components_strings_ur.xtb b/components/strings/components_strings_ur.xtb
index fc643b7..9849fb2 100644
--- a/components/strings/components_strings_ur.xtb
+++ b/components/strings/components_strings_ur.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">فرسودہ خصوصیات</translation>
 <translation id="131405271941274527">‏آپ کے NFC آلہ پر تھپتھپاتے وقت <ph name="URL" /> معلومات بھیجنا اور وصول کرنا چاہتا ہے</translation>
 <translation id="1314509827145471431">دائیں طرف باندھیں</translation>
+<translation id="1319245136674974084">اس ایپ کیلئے دوبارہ نہ پوچھیں</translation>
 <translation id="1320233736580025032">Prc1 ‎(Envelope‎)‎</translation>
 <translation id="132301787627749051">کلپ بورڈ کی تصویر تلاش کریں</translation>
 <translation id="1323433172918577554">مزید دکھائیں</translation>
@@ -746,6 +747,7 @@
 <translation id="3655670868607891010">اگر یہ آپ کو اکثر نظر آتا ہے تو یہ <ph name="HELP_LINK" /> آزمائیں۔</translation>
 <translation id="3658742229777143148">نظرثانی</translation>
 <translation id="3664782872746246217">کلیدی الفاظ:</translation>
+<translation id="3671540257457995106">سائز تبدیل کرنے کی اجازت دیں؟</translation>
 <translation id="3676592649209844519">‏آلہ کی ID:</translation>
 <translation id="3677008721441257057">‏کیا آپ کا مطلب &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; تھا؟</translation>
 <translation id="3678029195006412963">درخواست پر دستخط نہیں کیا جا سکا</translation>
@@ -1106,6 +1108,7 @@
 <translation id="4953689047182316270">ایکسیسبیلٹی ایونٹس کا جواب دیں</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">فہرست پھیلائیں</translation>
+<translation id="4968522289500246572">یہ ایپ موبائل کیلئے ڈیزائن کی گئی ہے اور ممکن ہے کہ اس کا سائز صحیح طریقے سے تبدیل نہ ہو۔ اس کو استعمال کرنے میں مسائل کا سامنا ہو سکتا ہے یا ری اسٹارٹ کرنا پڑ سکتی ہے۔</translation>
 <translation id="4973922308112707173">اوپر دُہرا سوراخ</translation>
 <translation id="4974590756084640048">وارننگز کو دوبارہ فعال کریں</translation>
 <translation id="4984088539114770594">مائیکروفون کا استعمال کریں؟</translation>
@@ -1154,6 +1157,7 @@
 <translation id="5123063207673082822">ویک اینڈ</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">اپنے کارڈ کی توثیق کریں</translation>
+<translation id="512670116361803001">ہو سکتا ہے کہ <ph name="APP_NAME" /> کا سائز صحیح طریقے سے تبدیل نہ ہو۔ ایپ کو مسائل کا سامنا کرنے سے روکنے کیلئے ونڈو کے پری سیٹ سائز کا استعمال کریں۔</translation>
 <translation id="5135404736266831032">پتوں کا نظم کریں...</translation>
 <translation id="5138014172396933048">ورچوئل کارڈ ابھی دستیاب نہیں ہے، براہ کرم اپنے بینک سے رابطہ کریں</translation>
 <translation id="5138227688689900538">کم دکھائیں</translation>
@@ -1521,6 +1525,7 @@
 <translation id="647261751007945333">آلے کی پالیسیاں</translation>
 <translation id="6476284679642588870">ادائیگی کے طریقوں کا نظم کریں</translation>
 <translation id="6489534406876378309">کریشز اپ لوڈ کرنا شروع کریں</translation>
+<translation id="6493924760403974580">یہ ایپ صرف اس سائز کو سپورٹ کرتی ہے۔</translation>
 <translation id="6499038740797743453">پاس ورڈ کو ری سیٹ کریں؟</translation>
 <translation id="6502991525169604759">آپ کی تبدیلیوں کے بغیر</translation>
 <translation id="6508722015517270189">‏Chrome کو دوبارہ شروع کریں</translation>
@@ -2175,6 +2180,7 @@
 <translation id="8975263830901772334">آپ کی پرنٹ کردہ فائلز کے نام</translation>
 <translation id="8978053250194585037">‏Google محفوظ براؤزنگ نے حال ہی میں <ph name="SITE" /> پر <ph name="BEGIN_LINK" />فریب دہی کا پتا لگایا ہے<ph name="END_LINK" />۔ فریب دہی والی سائٹس آپ کو پھنسانے کے لیے دوسری ویب سائٹس ہونے کا دکھاوا کرتی ہیں۔</translation>
 <translation id="8983003182662520383">‏Google Pay استعمال کرنے والے ادائیگی کے طریقے اور پتے</translation>
+<translation id="8983369100812962543">اب آپ ایپ کا سائز تبدیل کر سکتے ہیں</translation>
 <translation id="8987927404178983737">ماہ</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> جاننا چاہتا ہے کہ فعال طور پر آپ اس آلہ کا استعمال کب کر رہے ہیں</translation>
diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb
index 240a33c..22117588 100644
--- a/components/strings/components_strings_zh-CN.xtb
+++ b/components/strings/components_strings_zh-CN.xtb
@@ -103,6 +103,7 @@
 <translation id="1307966114820526988">已被弃用的功能</translation>
 <translation id="131405271941274527"><ph name="URL" /> 想在您的手机与 NFC 设备触碰时发送和接收信息</translation>
 <translation id="1314509827145471431">装订(右侧)</translation>
+<translation id="1319245136674974084">对于此应用不再询问</translation>
 <translation id="1320233736580025032">Prc1 (Envelope)</translation>
 <translation id="132301787627749051">搜索剪贴板上的图片</translation>
 <translation id="1323433172918577554">展开</translation>
@@ -736,6 +737,7 @@
 <translation id="3655670868607891010">如果您频繁遇到此问题,请尝试这些<ph name="HELP_LINK" />。</translation>
 <translation id="3658742229777143148">修订版本</translation>
 <translation id="3664782872746246217">关键字:</translation>
+<translation id="3671540257457995106">允许调整大小?</translation>
 <translation id="3676592649209844519">设备 ID:</translation>
 <translation id="3677008721441257057">您是想访问 &lt;a href="#" id="dont-proceed-link"&gt;<ph name="DOMAIN" />&lt;/a&gt; 吧?</translation>
 <translation id="3678029195006412963">无法签署该请求</translation>
@@ -1091,6 +1093,7 @@
 <translation id="4953689047182316270">对无障碍事件做出响应</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">展开列表</translation>
+<translation id="4968522289500246572">此应用是专为移动设备设计的,可能无法妥当地调整大小。此应用可能会出现问题或重启。</translation>
 <translation id="4973922308112707173">双孔(顶部)</translation>
 <translation id="4974590756084640048">重新启用警告功能</translation>
 <translation id="4984088539114770594">使用麦克风?</translation>
@@ -1139,6 +1142,7 @@
 <translation id="5123063207673082822">周末</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">验证您的银行卡</translation>
+<translation id="512670116361803001">“<ph name="APP_NAME" />”可能无法妥当地调整大小。请使用预设窗口大小,以防止该应用出现问题。</translation>
 <translation id="5135404736266831032">管理地址…</translation>
 <translation id="5138014172396933048">暂时无法使用虚拟卡,请联系您的发卡行</translation>
 <translation id="5138227688689900538">收起</translation>
@@ -1504,6 +1508,7 @@
 <translation id="647261751007945333">设备政策</translation>
 <translation id="6476284679642588870">管理付款方式</translation>
 <translation id="6489534406876378309">开始上传崩溃数据</translation>
+<translation id="6493924760403974580">此应用仅支持该尺寸。</translation>
 <translation id="6499038740797743453">重置密码?</translation>
 <translation id="6502991525169604759">不含您所做更改</translation>
 <translation id="6508722015517270189">重新启动 Chrome</translation>
@@ -2159,6 +2164,7 @@
 <translation id="8975263830901772334">已打印的文件的名称</translation>
 <translation id="8978053250194585037">Google 安全浏览功能最近在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />检测到网上诱骗行为<ph name="END_LINK" />。网上诱骗网站会假冒其他网站来欺骗您。</translation>
 <translation id="8983003182662520383">Google Pay 中存储的付款方式和地址信息</translation>
+<translation id="8983369100812962543">现在,您可以调整应用大小</translation>
 <translation id="8987927404178983737">月</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> 想了解您何时在主动使用此设备</translation>
diff --git a/components/strings/components_strings_zh-HK.xtb b/components/strings/components_strings_zh-HK.xtb
index 81d1b1b4..d00181a 100644
--- a/components/strings/components_strings_zh-HK.xtb
+++ b/components/strings/components_strings_zh-HK.xtb
@@ -103,7 +103,7 @@
 <translation id="1307966114820526988">這些功能已被淘汰</translation>
 <translation id="131405271941274527"><ph name="URL" /> 想在您以手機觸踫 NFC 裝置時傳送和接收資料</translation>
 <translation id="1314509827145471431">釘裝 (右側)</translation>
-<translation id="1319245136674974084">不要再詢問是否允許調整這個應用程式的大小</translation>
+<translation id="1319245136674974084">使用這個應用程式時不要再問我</translation>
 <translation id="1320233736580025032">Prc1 (信封)</translation>
 <translation id="132301787627749051">搵剪貼簿嘅圖</translation>
 <translation id="1323433172918577554">顯示更多</translation>
@@ -1096,7 +1096,7 @@
 <translation id="4953689047182316270">回應無障礙功能事件</translation>
 <translation id="4955242332710481440">A5-Extra</translation>
 <translation id="4958444002117714549">展開清單</translation>
-<translation id="4968522289500246572">這是專為行動裝置設計的應用程式,大小可能未妥善調整。此應用程式可能會發生問題,或是重新啟動。</translation>
+<translation id="4968522289500246572">此應用程式專為流動裝置而設,可能無法正常調整大小。應用程式可能會發生問題或重新啟動。</translation>
 <translation id="4973922308112707173">雙孔 (頂端)</translation>
 <translation id="4974590756084640048">重新啟用警告功能</translation>
 <translation id="4984088539114770594">要使用麥克風嗎?</translation>
@@ -1145,7 +1145,7 @@
 <translation id="5123063207673082822">週末</translation>
 <translation id="5125394840236832993">B-Plus</translation>
 <translation id="5126510351761255129">驗證信用卡</translation>
-<translation id="512670116361803001">「<ph name="APP_NAME" />」的大小可能未妥善調整。請採用預設的視窗大小,以免應用程式發生問題。</translation>
+<translation id="512670116361803001">「<ph name="APP_NAME" />」可能無法正常調整大小。請使用預設視窗大小,以免應用程式發生問題。</translation>
 <translation id="5135404736266831032">管理地址…</translation>
 <translation id="5138014172396933048">目前無法使用虛擬卡,請聯絡您的銀行</translation>
 <translation id="5138227688689900538">顯示較少</translation>
@@ -1512,7 +1512,7 @@
 <translation id="647261751007945333">裝置政策</translation>
 <translation id="6476284679642588870">管理付款方法</translation>
 <translation id="6489534406876378309">開始上載當機報告</translation>
-<translation id="6493924760403974580">這個應用程式僅支援此大小。</translation>
+<translation id="6493924760403974580">此應用程式只支援此大小。</translation>
 <translation id="6499038740797743453">要重設密碼嗎?</translation>
 <translation id="6502991525169604759">不包括您所作的變更</translation>
 <translation id="6508722015517270189">重新啟動 Chrome</translation>
@@ -2167,7 +2167,7 @@
 <translation id="8975263830901772334">您列印的檔案名稱</translation>
 <translation id="8978053250194585037">「Google 安全瀏覽」功能最近在 <ph name="SITE" /> 上<ph name="BEGIN_LINK" />偵測到網絡釣魚行為<ph name="END_LINK" />。網絡釣魚網站會偽裝成其他網站,藉此騙取您的資料。</translation>
 <translation id="8983003182662520383">使用 Google Pay 儲存的付款方法和地址</translation>
-<translation id="8983369100812962543">你現在可以調整應用程式大小</translation>
+<translation id="8983369100812962543">您現在可以調整應用程式大小</translation>
 <translation id="8987927404178983737">月</translation>
 <translation id="8989148748219918422"><ph name="ORGANIZATION" /> [<ph name="COUNTRY" />]</translation>
 <translation id="899688752321268742"><ph name="URL" /> 想知道您是否正在使用此裝置</translation>
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc
index 5f672453..160c1a8 100644
--- a/components/sync/driver/startup_controller.cc
+++ b/components/sync/driver/startup_controller.cc
@@ -10,7 +10,6 @@
 #include "base/command_line.h"
 #include "base/location.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/threading/sequenced_task_runner_handle.h"
@@ -46,17 +45,6 @@
       switches::kSyncDisableDeferredStartup);
 }
 
-// Enum for UMA defining different events that cause us to exit the "deferred"
-// state of initialization and invoke start_engine.
-enum DeferredInitTrigger {
-  // We have received a signal from a SyncableService requesting that sync
-  // starts as soon as possible.
-  TRIGGER_DATA_TYPE_REQUEST,
-  // No data type requested sync to start and our fallback timer expired.
-  TRIGGER_FALLBACK_TIMER,
-  MAX_TRIGGER_VALUE
-};
-
 }  // namespace
 
 StartupController::StartupController(
@@ -131,8 +119,9 @@
     }
     // If the Service had to start immediately, bypass the deferred startup when
     // we receive the policies.
-    if (force_immediate)
+    if (force_immediate) {
       bypass_deferred_startup_ = true;
+    }
     return;
   }
 
@@ -145,30 +134,28 @@
   // - a datatype has requested an immediate start of sync, or
   // - sync needs to start up the engine immediately to provide control state
   //   and encryption information to the UI.
-  // Do not start up the sync engine if setup has not completed and isn't
-  // in progress, unless told to otherwise.
   StartUp((force_immediate || bypass_deferred_startup_) ? STARTUP_IMMEDIATE
                                                         : STARTUP_DEFERRED);
 }
 
-void StartupController::RecordTimeDeferred() {
+void StartupController::RecordTimeDeferred(DeferredInitTrigger trigger) {
   DCHECK(!start_up_time_.is_null());
   base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
-  UMA_HISTOGRAM_CUSTOM_TIMES("Sync.Startup.TimeDeferred2", time_deferred,
-                             base::TimeDelta::FromSeconds(0),
-                             base::TimeDelta::FromMinutes(2), 60);
+  base::UmaHistogramCustomTimes("Sync.Startup.TimeDeferred2", time_deferred,
+                                base::TimeDelta::FromSeconds(0),
+                                base::TimeDelta::FromMinutes(2), 60);
+  base::UmaHistogramEnumeration("Sync.Startup.DeferredInitTrigger", trigger);
 }
 
 void StartupController::OnFallbackStartupTimerExpired() {
   DCHECK(IsDeferredStartupEnabled());
 
-  if (!start_engine_time_.is_null())
+  if (!start_engine_time_.is_null()) {
     return;
+  }
 
   DVLOG(2) << "Sync deferred init fallback timer expired, starting engine.";
-  RecordTimeDeferred();
-  UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
-                            TRIGGER_FALLBACK_TIMER, MAX_TRIGGER_VALUE);
+  RecordTimeDeferred(DeferredInitTrigger::kFallbackTimer);
   // Once the deferred init timer has expired, don't defer startup again (until
   // Reset() or browser restart), even if this startup attempt doesn't succeed.
   bypass_deferred_startup_ = true;
@@ -176,12 +163,15 @@
 }
 
 StartupController::State StartupController::GetState() const {
-  if (!start_engine_time_.is_null())
+  if (!start_engine_time_.is_null()) {
     return State::STARTED;
-  if (!ArePoliciesReady() && !waiting_for_policies_start_time_.is_null())
+  }
+  if (!ArePoliciesReady() && !waiting_for_policies_start_time_.is_null()) {
     return State::STARTING_DEFERRED;
-  if (!start_up_time_.is_null())
+  }
+  if (!start_up_time_.is_null()) {
     return State::STARTING_DEFERRED;
+  }
   return State::NOT_STARTED;
 }
 
@@ -219,8 +209,9 @@
 
   // Only try to start the engine if we explicitly tried to start but had to
   // wait for policies to be loaded.
-  if (!waiting_for_policies_start_time_.is_null())
+  if (!waiting_for_policies_start_time_.is_null()) {
     TryStart(/*force_immediate=*/false);
+  }
 }
 
 void StartupController::OnDataTypeRequestsSyncStartup(ModelType type) {
@@ -230,19 +221,13 @@
     return;
   }
 
-  if (!start_engine_time_.is_null())
+  if (!start_engine_time_.is_null()) {
     return;
+  }
 
   DVLOG(2) << "Data type requesting sync startup: " << ModelTypeToString(type);
-  // Measure the time spent waiting for init and the type that triggered it.
-  // We could measure the time spent deferred on a per-datatype basis, but
-  // for now this is probably sufficient.
-  UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit",
-                            ModelTypeHistogramValue(type));
   if (!start_up_time_.is_null()) {
-    RecordTimeDeferred();
-    UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
-                              TRIGGER_DATA_TYPE_REQUEST, MAX_TRIGGER_VALUE);
+    RecordTimeDeferred(DeferredInitTrigger::kDataTypeRequest);
   }
   bypass_deferred_startup_ = true;
   TryStart(/*force_immediate=*/false);
diff --git a/components/sync/driver/startup_controller.h b/components/sync/driver/startup_controller.h
index 1701cf686..0cd1739 100644
--- a/components/sync/driver/startup_controller.h
+++ b/components/sync/driver/startup_controller.h
@@ -73,6 +73,19 @@
  private:
   enum StartUpDeferredOption { STARTUP_DEFERRED, STARTUP_IMMEDIATE };
 
+  // Enum for UMA defining different events that cause us to exit the "deferred"
+  // state of initialization and invoke start_engine.
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class DeferredInitTrigger {
+    // We have received a signal from a data type requesting that sync starts as
+    // soon as possible.
+    kDataTypeRequest = 0,
+    // No data type requested sync to start and our fallback timer expired.
+    kFallbackTimer = 1,
+    kMaxValue = kFallbackTimer
+  };
+
   // Called when |policy_service_| is defined, but it took too long to receive
   // the first chrome policies.
   void OnFirstPoliciesLoadedTimeout();
@@ -86,7 +99,7 @@
   void OnFallbackStartupTimerExpired();
 
   // Records time spent in deferred state with UMA histograms.
-  void RecordTimeDeferred();
+  void RecordTimeDeferred(DeferredInitTrigger trigger);
 
   const base::RepeatingCallback<ModelTypeSet()>
       get_preferred_data_types_callback_;
diff --git a/components/sync/trusted_vault/standalone_trusted_vault_client.cc b/components/sync/trusted_vault/standalone_trusted_vault_client.cc
index 053d91b..ba1f631 100644
--- a/components/sync/trusted_vault/standalone_trusted_vault_client.cc
+++ b/components/sync/trusted_vault/standalone_trusted_vault_client.cc
@@ -93,8 +93,8 @@
 
   identity_manager_->AddObserver(this);
   UpdatePrimaryAccountIfNeeded();
-  // TODO(crbug.com/1148328): call UpdateAccountsInCookieJarInfoIfNotStale() if
-  // needed once tests are fixed.
+  UpdateAccountsInCookieJarInfoIfNotStale(
+      identity_manager_->GetAccountsInCookieJar());
 }
 
 IdentityManagerObserver::~IdentityManagerObserver() {
diff --git a/components/sync_device_info/device_info.cc b/components/sync_device_info/device_info.cc
index 8130b7d..b36be000 100644
--- a/components/sync_device_info/device_info.cc
+++ b/components/sync_device_info/device_info.cc
@@ -7,7 +7,7 @@
 // device_info.h's size can impact build time. Try not to raise this limit
 // unless absolutely necessary. See
 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
-#pragma clang max_tokens_here 505000
+#pragma clang max_tokens_here 506000
 
 #include <utility>
 
diff --git a/components/system_media_controls/mac/remote_command_center_delegate.h b/components/system_media_controls/mac/remote_command_center_delegate.h
index b91bf96..741f8423 100644
--- a/components/system_media_controls/mac/remote_command_center_delegate.h
+++ b/components/system_media_controls/mac/remote_command_center_delegate.h
@@ -11,6 +11,10 @@
 
 @class RemoteCommandCenterDelegateCocoa;
 
+namespace base {
+class TimeDelta;
+}
+
 namespace system_media_controls {
 
 class SystemMediaControlsObserver;
diff --git a/components/system_media_controls/mac/remote_command_center_delegate.mm b/components/system_media_controls/mac/remote_command_center_delegate.mm
index db05b09f..3366194 100644
--- a/components/system_media_controls/mac/remote_command_center_delegate.mm
+++ b/components/system_media_controls/mac/remote_command_center_delegate.mm
@@ -4,6 +4,7 @@
 
 #include "components/system_media_controls/mac/remote_command_center_delegate.h"
 
+#include "base/time/time.h"
 #include "components/system_media_controls/mac/remote_command_center_delegate_cocoa.h"
 #include "components/system_media_controls/system_media_controls_observer.h"
 
diff --git a/components/system_media_controls/mac/remote_command_center_delegate_cocoa.mm b/components/system_media_controls/mac/remote_command_center_delegate_cocoa.mm
index 2b05794..d05e043 100644
--- a/components/system_media_controls/mac/remote_command_center_delegate_cocoa.mm
+++ b/components/system_media_controls/mac/remote_command_center_delegate_cocoa.mm
@@ -6,6 +6,7 @@
 
 #import <MediaPlayer/MediaPlayer.h>
 
+#include "base/time/time.h"
 #include "components/system_media_controls/mac/remote_command_center_delegate.h"
 
 API_AVAILABLE(macos(10.12.2))
diff --git a/components/test/data/autofill_assistant/html_iframe/autofill_assistant_external_iframe.html b/components/test/data/autofill_assistant/html_iframe/autofill_assistant_external_iframe.html
index f5cc996..7caeda2 100644
--- a/components/test/data/autofill_assistant/html_iframe/autofill_assistant_external_iframe.html
+++ b/components/test/data/autofill_assistant/html_iframe/autofill_assistant_external_iframe.html
@@ -23,6 +23,12 @@
         input.value = select.options[select.selectedIndex].label;
       }
     </script>
+
+    <style>
+      #full_height_section {
+        height: 100vh;
+      }
+    </style>
   </head>
   <body>
     <button id="button" type="button" onclick="removeDiv()">Button</button>
@@ -37,5 +43,11 @@
       <option value="Fish">Fish</option>
     </select>
     <input type="text" id="myPet"/>
+
+    <!--
+    Intentionally make this section has the full height of the window
+    to force scroll when operating on the elements below this section.
+    -->
+    <div id="full_height_section"></div>
   </body>
 </html>
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc
index e94c3dae..a988ab3 100644
--- a/components/translate/content/renderer/translate_agent.cc
+++ b/components/translate/content/renderer/translate_agent.cc
@@ -576,7 +576,6 @@
   receiver_.reset();
   translate_callback_pending_.Reset();
   CancelPendingTranslation();
-  page_contents_length_ = 0;
 }
 
 void TranslateAgent::OnDestruct() {
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index 037ffc0d..7b545a4 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -756,20 +756,19 @@
 bool TranslatePrefs::CanTranslateLanguage(
     TranslateAcceptLanguages* accept_languages,
     base::StringPiece language) {
-  // Don't translate any user blocklisted languages.
+  // Languages not on the blocklist can always be translated.
   if (!IsBlockedLanguage(language))
     return true;
 
-  // Checking |is_accept_language| is necessary because if the user eliminates
-  // the language from the preference, it is natural to forget whether or not
-  // the language should be translated. Checking |cannot_be_accept_language| is
-  // also necessary because some minor languages can't be selected in the
-  // language preference even though the language is available in Translate
-  // server.
+  // Languages not on the Accept-Language list should not be blocked unless the
+  // detailed language settings are showing or the language can not be on the
+  // Accept-Language list (this is true for languages that do not have a ICU
+  // localization for the current UI locale.
   bool can_be_accept_language =
       TranslateAcceptLanguages::CanBeAcceptLanguage(language);
   bool is_accept_language = accept_languages->IsAcceptLanguage(language);
-  if (!is_accept_language && can_be_accept_language)
+  if (!is_accept_language && can_be_accept_language &&
+      !IsDetailedLanguageSettingsEnabled())
     return true;
 
   // Under this experiment, translate English page even though English may be
@@ -780,6 +779,17 @@
   return false;
 }
 
+// static
+bool TranslatePrefs::IsDetailedLanguageSettingsEnabled() {
+#if defined(OS_ANDROID)
+  return base::FeatureList::IsEnabled(language::kDetailedLanguageSettings);
+#elif defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+  return base::FeatureList::IsEnabled(
+      language::kDesktopDetailedLanguageSettings);
+#endif
+  return false;
+}
+
 bool TranslatePrefs::ShouldAutoTranslate(base::StringPiece source_language,
                                          std::string* target_language) {
   const base::DictionaryValue* dict =
diff --git a/components/translate/core/browser/translate_prefs.h b/components/translate/core/browser/translate_prefs.h
index 74ac483..96fd4529 100644
--- a/components/translate/core/browser/translate_prefs.h
+++ b/components/translate/core/browser/translate_prefs.h
@@ -300,6 +300,8 @@
                             base::StringPiece language);
   bool ShouldAutoTranslate(base::StringPiece source_language,
                            std::string* target_language);
+  // True if the detailed language settings are enabled for this user.
+  static bool IsDetailedLanguageSettingsEnabled();
 
   // Stores and retrieves the last-observed translate target language. Used to
   // determine which target language to offer in future. The translate target
diff --git a/components/translate/core/browser/translate_prefs_unittest.cc b/components/translate/core/browser/translate_prefs_unittest.cc
index 57bd7af..9af2e622 100644
--- a/components/translate/core/browser/translate_prefs_unittest.cc
+++ b/components/translate/core/browser/translate_prefs_unittest.cc
@@ -127,8 +127,6 @@
   // Shared time constants.
   base::Time now_;
   base::Time two_days_ago_;
-
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Test that GetLanguageInfoList() returns the correct list of languages based
@@ -1076,19 +1074,39 @@
   EXPECT_FALSE(translate_prefs_->CanTranslateLanguage(
       &translate_accept_languages, "en"));
 
-  // Blocked language that is not in accept languages.
+  // Blocked languages that are not in accept languages are not blocked.
   translate_prefs_->BlockLanguage("de");
   EXPECT_TRUE(translate_prefs_->CanTranslateLanguage(
       &translate_accept_languages, "de"));
 
-  // English in force translate experiment.
-  scoped_feature_list_.InitAndEnableFeatureWithParameters(
-      language::kOverrideTranslateTriggerInIndia,
-      {{"override_model", "heuristic"},
-       {"enforce_ranker", "false"},
-       {"backoff_threshold", "1"}});
-  EXPECT_TRUE(translate_prefs_->CanTranslateLanguage(
-      &translate_accept_languages, "en"));
+// When the detailed language settings are enabled blocked languages not in
+// accept languages can be translated.
+#if defined(OS_ANDROID)
+  {  // Android scoped feature.
+    base::test::ScopedFeatureList scoped_feature_list(
+        language::kDetailedLanguageSettings);
+    EXPECT_FALSE(translate_prefs_->CanTranslateLanguage(
+        &translate_accept_languages, "de"));
+  }
+#elif defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
+  {  // Desktop scoped feature.
+    base::test::ScopedFeatureList scoped_feature_list(
+        language::kDesktopDetailedLanguageSettings);
+    EXPECT_FALSE(translate_prefs_->CanTranslateLanguage(
+        &translate_accept_languages, "de"));
+  }
+#endif
+
+  {  // English in force translate experiment scoped feature.
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeatureWithParameters(
+        language::kOverrideTranslateTriggerInIndia,
+        {{"override_model", "heuristic"},
+         {"enforce_ranker", "false"},
+         {"backoff_threshold", "1"}});
+    EXPECT_TRUE(translate_prefs_->CanTranslateLanguage(
+        &translate_accept_languages, "en"));
+  }
 }
 
 TEST_F(TranslatePrefsTest, ForceTriggerOnEnglishPagesCount) {
diff --git a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
index c21f463..d2e6918 100644
--- a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
+++ b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
@@ -184,7 +184,6 @@
 
             SeedFetchInfo fetchInfo =
                     downloadContent(VariationsPlatform.ANDROID, restrictMode, milestone, channel);
-            recordFetchResultOrCode(fetchInfo.seedFetchResult);
             if (fetchInfo.seedInfo != null) {
                 SeedInfo info = fetchInfo.seedInfo;
                 VariationsSeedBridge.setVariationsFirstRunSeed(info.seedData, info.signature,
@@ -261,6 +260,7 @@
             if (connection != null) {
                 connection.disconnect();
             }
+            recordFetchResultOrCode(fetchInfo.seedFetchResult);
             return fetchInfo;
         }
     }
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
index 52cb1c1b..fd0cdaf 100644
--- a/components/variations/service/variations_field_trial_creator.cc
+++ b/components/variations/service/variations_field_trial_creator.cc
@@ -356,7 +356,7 @@
   std::string stored_country;
 
   // Determine if the saved pref value is present and valid.
-  const bool is_pref_empty = list_value->empty();
+  const bool is_pref_empty = list_value->GetList().empty();
   const bool is_pref_valid = list_value->GetSize() == 2 &&
                              list_value->GetString(0, &stored_version_string) &&
                              list_value->GetString(1, &stored_country) &&
diff --git a/components/vector_icons/cc_macros.h b/components/vector_icons/cc_macros.h
index 43ae8ed..2a587ee 100644
--- a/components/vector_icons/cc_macros.h
+++ b/components/vector_icons/cc_macros.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_VECTOR_ICONS_CC_MACROS_H_
 #define COMPONENTS_VECTOR_ICONS_CC_MACROS_H_
 
-#include "base/stl_util.h"  // For base::size().
+#include "base/cxx17_backports.h"  // For base::size().
 
 // This file holds macros that are common to each vector icon target's
 // vector_icons.cc.template file.
diff --git a/components/viz/common/delegated_ink_prediction_configuration.h b/components/viz/common/delegated_ink_prediction_configuration.h
index 4613e68e..2e9cb32 100644
--- a/components/viz/common/delegated_ink_prediction_configuration.h
+++ b/components/viz/common/delegated_ink_prediction_configuration.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_VIZ_COMMON_DELEGATED_INK_PREDICTION_CONFIGURATION_H_
 #define COMPONENTS_VIZ_COMMON_DELEGATED_INK_PREDICTION_CONFIGURATION_H_
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 
 namespace viz {
 
diff --git a/components/viz/common/surfaces/frame_sink_id.h b/components/viz/common/surfaces/frame_sink_id.h
index 8d651b24e..74c8712 100644
--- a/components/viz/common/surfaces/frame_sink_id.h
+++ b/components/viz/common/surfaces/frame_sink_id.h
@@ -37,8 +37,8 @@
  public:
   constexpr FrameSinkId() : client_id_(0), sink_id_(0) {}
 
-  constexpr FrameSinkId(const FrameSinkId& other)
-      : client_id_(other.client_id_), sink_id_(other.sink_id_) {}
+  constexpr FrameSinkId(const FrameSinkId& other) = default;
+  constexpr FrameSinkId& operator=(const FrameSinkId& other) = default;
 
   constexpr FrameSinkId(uint32_t client_id, uint32_t sink_id)
       : client_id_(client_id), sink_id_(sink_id) {}
diff --git a/components/viz/common/surfaces/local_surface_id.h b/components/viz/common/surfaces/local_surface_id.h
index 1642007..e717f82c 100644
--- a/components/viz/common/surfaces/local_surface_id.h
+++ b/components/viz/common/surfaces/local_surface_id.h
@@ -68,10 +68,8 @@
       : parent_sequence_number_(kInvalidParentSequenceNumber),
         child_sequence_number_(kInvalidChildSequenceNumber) {}
 
-  constexpr LocalSurfaceId(const LocalSurfaceId& other)
-      : parent_sequence_number_(other.parent_sequence_number_),
-        child_sequence_number_(other.child_sequence_number_),
-        embed_token_(other.embed_token_) {}
+  constexpr LocalSurfaceId(const LocalSurfaceId& other) = default;
+  constexpr LocalSurfaceId& operator=(const LocalSurfaceId& other) = default;
 
   constexpr LocalSurfaceId(uint32_t parent_sequence_number,
                            const base::UnguessableToken& embed_token)
diff --git a/components/viz/common/surfaces/surface_id.h b/components/viz/common/surfaces/surface_id.h
index eb0345d..7f8e7d9 100644
--- a/components/viz/common/surfaces/surface_id.h
+++ b/components/viz/common/surfaces/surface_id.h
@@ -28,6 +28,7 @@
   constexpr SurfaceId() = default;
 
   constexpr SurfaceId(const SurfaceId& other) = default;
+  constexpr SurfaceId& operator=(const SurfaceId& other) = default;
 
   // A SurfaceId consists of two components: FrameSinkId and LocalSurfaceId.
   // A |frame_sink_id| consists of two components; one is allocated by the
diff --git a/components/viz/common/surfaces/surface_range.cc b/components/viz/common/surfaces/surface_range.cc
index e8bdf9a5..d3b96347 100644
--- a/components/viz/common/surfaces/surface_range.cc
+++ b/components/viz/common/surfaces/surface_range.cc
@@ -4,6 +4,8 @@
 
 #include "components/viz/common/surfaces/surface_range.h"
 
+#include <string>
+
 #include "base/strings/stringprintf.h"
 
 namespace viz {
@@ -19,6 +21,8 @@
 
 SurfaceRange::SurfaceRange(const SurfaceRange& other) = default;
 
+SurfaceRange& SurfaceRange::operator=(const SurfaceRange& other) = default;
+
 bool SurfaceRange::operator==(const SurfaceRange& other) const {
   return start_ == other.start() && end_ == other.end();
 }
diff --git a/components/viz/common/surfaces/surface_range.h b/components/viz/common/surfaces/surface_range.h
index 83aa898..72510e34 100644
--- a/components/viz/common/surfaces/surface_range.h
+++ b/components/viz/common/surfaces/surface_range.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_RANGE_H_
 #define COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_RANGE_H_
 
+#include <string>
+
 #include "components/viz/common/surfaces/surface_id.h"
 #include "components/viz/common/viz_common_export.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
@@ -28,6 +30,7 @@
   explicit SurfaceRange(const SurfaceId& surface_id);
 
   SurfaceRange(const SurfaceRange& other);
+  SurfaceRange& operator=(const SurfaceRange& other);
 
   bool operator==(const SurfaceRange& other) const;
 
diff --git a/components/viz/service/display/output_surface.cc b/components/viz/service/display/output_surface.cc
index df3d9eab..5d000996 100644
--- a/components/viz/service/display/output_surface.cc
+++ b/components/viz/service/display/output_surface.cc
@@ -26,6 +26,8 @@
 OutputSurface::Capabilities::Capabilities() = default;
 OutputSurface::Capabilities::Capabilities(const Capabilities& capabilities) =
     default;
+OutputSurface::Capabilities& OutputSurface::Capabilities::operator=(
+    const Capabilities& capabilities) = default;
 
 OutputSurface::OutputSurface(Type type) : type_(type) {}
 
diff --git a/components/viz/service/display/output_surface.h b/components/viz/service/display/output_surface.h
index 34f9a6d7..59873e9 100644
--- a/components/viz/service/display/output_surface.h
+++ b/components/viz/service/display/output_surface.h
@@ -66,6 +66,7 @@
   struct Capabilities {
     Capabilities();
     Capabilities(const Capabilities& capabilities);
+    Capabilities& operator=(const Capabilities& capabilities);
 
     int max_frames_pending = 1;
     // If set, should be the max number of pending frames when running at or
diff --git a/components/viz/service/display/overlay_candidate.cc b/components/viz/service/display/overlay_candidate.cc
index c9f376d..c825d08 100644
--- a/components/viz/service/display/overlay_candidate.cc
+++ b/components/viz/service/display/overlay_candidate.cc
@@ -146,8 +146,12 @@
   const SharedQuadState* sqs = quad->shared_quad_state;
 
   // We don't support an opacity value different than one for an overlay plane.
-  if (sqs->opacity != 1.f)
+  // Render pass quads should have their |sqs| opacity integrated directly into
+  // their final output buffers.
+  if (!cc::MathUtil::IsWithinEpsilon(sqs->opacity, 1.0f) &&
+      quad->material != DrawQuad::Material::kAggregatedRenderPass) {
     return false;
+  }
 
   // We support only kSrc (no blending) and kSrcOver (blending with premul).
   if (!(sqs->blend_mode == SkBlendMode::kSrc ||
@@ -178,7 +182,13 @@
       return candidate->FromSolidColorQuad(
           resource_provider, surface_damage_rect_list,
           SolidColorDrawQuad::MaterialCast(quad), primary_rect, candidate);
-
+    case DrawQuad::Material::kAggregatedRenderPass:
+      if (!is_delegated_context)
+        return false;
+      return candidate->FromAggregateQuad(
+          resource_provider, surface_damage_rect_list,
+          AggregatedRenderPassDrawQuad::MaterialCast(quad), primary_rect,
+          candidate);
     case DrawQuad::Material::kTiledContent:
       if (!is_delegated_context)
         return false;
@@ -351,6 +361,21 @@
 }
 
 // static
+bool OverlayCandidate::FromAggregateQuad(
+    DisplayResourceProvider* resource_provider,
+    SurfaceDamageRectList* surface_damage_rect_list,
+    const AggregatedRenderPassDrawQuad* quad,
+    const gfx::RectF& primary_rect,
+    OverlayCandidate* candidate) {
+  if (!FromDrawQuadResource(resource_provider, surface_damage_rect_list, quad,
+                            kInvalidResourceId, false, candidate)) {
+    return false;
+  }
+  candidate->rpdq = quad;
+  return true;
+}
+
+// static
 bool OverlayCandidate::FromSolidColorQuad(
     DisplayResourceProvider* resource_provider,
     SurfaceDamageRectList* surface_damage_rect_list,
diff --git a/components/viz/service/display/overlay_candidate.h b/components/viz/service/display/overlay_candidate.h
index 7758b15..0c72df5 100644
--- a/components/viz/service/display/overlay_candidate.h
+++ b/components/viz/service/display/overlay_candidate.h
@@ -17,6 +17,7 @@
 #include "components/viz/service/viz_service_export.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/skia/include/core/SkDeferredDisplayList.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
@@ -29,6 +30,7 @@
 }
 
 namespace viz {
+class AggregatedRenderPassDrawQuad;
 class DisplayResourceProvider;
 class SolidColorDrawQuad;
 class StreamVideoDrawQuad;
@@ -153,6 +155,18 @@
   // for solid color quads only
   absl::optional<SkColor> solid_color;
 
+  // If |rpdq| is present, then the renderer must draw the filter effects and
+  // copy the result into the buffer backing of a render pass.
+  const AggregatedRenderPassDrawQuad* rpdq = nullptr;
+  // The DDL for generating render pass overlay buffer with SkiaRenderer. This
+  // is the recorded output of rendering the |rpdq|.
+  sk_sp<SkDeferredDisplayList> ddl;
+
+  // The bounds in pixels of the rendered |rpdq|.
+  // TODO(petermcneeley) : Refactor the usage of this member to be compatible
+  // with |uv_rect| member in this class.
+  gfx::RectF bounds_rect;
+
  private:
   static bool FromDrawQuadResource(
       DisplayResourceProvider* resource_provider,
@@ -172,6 +186,13 @@
                            const TileDrawQuad* quad,
                            const gfx::RectF& primary_rect,
                            OverlayCandidate* candidate);
+
+  static bool FromAggregateQuad(DisplayResourceProvider* resource_provider,
+                                SurfaceDamageRectList* surface_damage_rect_list,
+                                const AggregatedRenderPassDrawQuad* quad,
+                                const gfx::RectF& primary_rect,
+                                OverlayCandidate* candidate);
+
   static bool FromSolidColorQuad(
       DisplayResourceProvider* resource_provider,
       SurfaceDamageRectList* surface_damage_rect_list,
diff --git a/components/viz/service/display/overlay_processor_delegated.cc b/components/viz/service/display/overlay_processor_delegated.cc
index 5ef9d4a..31d134c 100644
--- a/components/viz/service/display/overlay_processor_delegated.cc
+++ b/components/viz/service/display/overlay_processor_delegated.cc
@@ -100,6 +100,13 @@
         continue;
       }
 
+      if (it->material == DrawQuad::Material::kAggregatedRenderPass) {
+        DBG_DRAW_RECT("delegated.overlay.aggregated", candidate.display_rect);
+        candidates->push_back(candidate);
+        candidate_quads.push_back(it);
+        continue;
+      }
+
       // Because of the device scale factor (2) we check against a rounded empty
       // rect.
       // TODO(https://crbug.com/1218678) : Move and generalize this fix in
@@ -133,14 +140,11 @@
   // Check for support.
   this->CheckOverlaySupport(primary_plane, candidates);
 
-  // Reverse iterate to avoid iterator invalidation of future elements.
-  auto quad_to_iter = candidate_quads.rbegin();
-  for (auto candidate = candidates->rbegin(); candidate != candidates->rend();
-       candidate++, quad_to_iter++) {
-    if (candidate->overlay_handled) {
-      quad_list->EraseAndInvalidateAllPointers(*quad_to_iter);
-    }
-  }
+  // We cannot erase the quads that were handled as overlays because raw
+  // pointers of the aggregate draw quads were placed in the |rpdq| member of
+  // the |OverlayCandidate|. As keeping with the pattern in
+  // overlay_processor_mac we will also set the damage to empty on the
+  // successful promotion of all quads.
 
   return true;
 }
diff --git a/components/viz/service/display/overlay_processor_interface.h b/components/viz/service/display/overlay_processor_interface.h
index cc87e27..065a9f4 100644
--- a/components/viz/service/display/overlay_processor_interface.h
+++ b/components/viz/service/display/overlay_processor_interface.h
@@ -44,6 +44,15 @@
 class VIZ_SERVICE_EXPORT OverlayProcessorInterface {
  public:
 #if defined(OS_APPLE)
+  using PlatformOverlayCandidate = CALayerOverlay;
+#elif defined(OS_WIN)
+  using PlatformOverlayCandidate = DCLayerOverlay;
+#else
+  // Default.
+  using PlatformOverlayCandidate = OverlayCandidate;
+#endif
+
+#if defined(OS_APPLE)
   using CandidateList = CALayerOverlayList;
 #elif defined(OS_WIN)
   using CandidateList = DCLayerOverlayList;
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h
index 541c9d0..bec2da2 100644
--- a/components/viz/service/display/skia_output_surface.h
+++ b/components/viz/service/display/skia_output_surface.h
@@ -179,7 +179,7 @@
   // the GPU main thread.
   virtual gpu::SyncToken Flush() = 0;
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   virtual SkCanvas* BeginPaintRenderPassOverlay(
       const gfx::Size& size,
       ResourceFormat format,
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index 1ac9a1c6..7b8b211 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -2276,6 +2276,11 @@
   // Only Wayland uses this code path.
   auto& locks = pending_overlay_locks_.back();
   for (auto& overlay : current_frame()->overlay_list) {
+    if (overlay.rpdq) {
+      PrepareRenderPassOverlay(&overlay);
+      // The output will be attached via mailbox when overlays are scheduled.
+      continue;
+    }
     // Solid Color quads do not have associated resource buffers.
     if (overlay.solid_color.has_value())
       continue;
@@ -2771,8 +2776,9 @@
   lock_set_for_external_use_->UnlockResources(sync_token);
 }
 
-#if defined(OS_APPLE)
-void SkiaRenderer::PrepareRenderPassOverlay(CALayerOverlay* overlay) {
+#if defined(OS_APPLE) || defined(USE_OZONE)
+void SkiaRenderer::PrepareRenderPassOverlay(
+    OverlayProcessorInterface::PlatformOverlayCandidate* overlay) {
   DCHECK(!current_canvas_);
   DCHECK(batched_quads_.empty());
   DCHECK(overlay->rpdq);
@@ -2872,6 +2878,7 @@
     bypass_mode = CalculateBypassParams(bypass->second, &rpdq_params, &params);
     if (bypass_mode == BypassMode::kSkip)
       return;
+
     // For bypassed render pass, we use the same format and color space for the
     // framebuffer.
     buffer_format = GetResourceFormat(reshape_buffer_format());
@@ -2889,7 +2896,13 @@
 
   // Adjust the overlay |buffer_size| to reduce memory fragmentation. It also
   // increases buffer reusing possibilities.
+#if defined(OS_APPLE)
   constexpr int kBufferMultiple = 64;
+#else  // defined(USE_OZONE)
+  // TODO(petermcneeley) : Support buffer rounding by dynamically changing
+  // texture uvs.
+  constexpr int kBufferMultiple = 1;
+#endif
   gfx::Size buffer_size(
       cc::MathUtil::CheckedRoundUp(filter_bounds.width(), kBufferMultiple),
       cc::MathUtil::CheckedRoundUp(filter_bounds.height(), kBufferMultiple));
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index acb51b7..939d787e 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -252,8 +252,9 @@
   // be sent to GPU scheduler.
   void FlushOutputSurface();
 
-#if defined(OS_APPLE)
-  void PrepareRenderPassOverlay(CALayerOverlay* overlay);
+#if defined(OS_APPLE) || defined(USE_OZONE)
+  void PrepareRenderPassOverlay(
+      OverlayProcessorInterface::PlatformOverlayCandidate* overlay);
 #endif
 
   DisplayResourceProviderSkia* resource_provider() {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index 055bc86..e6e9100 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -578,7 +578,7 @@
   return current_paint_->recorder()->getCanvas();
 }
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
 SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPassOverlay(
     const gfx::Size& size,
     ResourceFormat format,
@@ -607,7 +607,7 @@
   current_paint_.reset();
   return ddl;
 }
-#endif  // defined(OS_APPLE)
+#endif  // defined(OS_APPLE) || defined(USE_OZONE)
 
 void SkiaOutputSurfaceImpl::EndPaint(base::OnceClosure on_finished) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -748,14 +748,14 @@
     OverlayList overlays,
     std::vector<gpu::SyncToken> sync_tokens,
     base::OnceClosure on_finished) {
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   DCHECK_EQ(dependency_->gr_context_type(), gpu::GrContextType::kGL);
   // If there are render pass overlays, then a gl context is needed for drawing
   // the overlay render passes to a backing for being scanned out.
-  bool make_current = std::find_if(overlays.begin(), overlays.end(),
-                                   [](const CALayerOverlay& overlay) {
-                                     return !!overlay.ddl;
-                                   }) != overlays.end();
+  bool make_current =
+      std::find_if(overlays.begin(), overlays.end(), [](const auto& overlay) {
+        return !!overlay.ddl;
+      }) != overlays.end();
   // Append |resource_sync_tokens_| which are depended by drawing render passes
   // to overlay backings.
   std::move(resource_sync_tokens_.begin(), resource_sync_tokens_.end(),
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h
index 8ac31512..cca7b58 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -140,7 +140,7 @@
   void PreserveChildSurfaceControls() override;
   gpu::SyncToken Flush() override;
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   SkCanvas* BeginPaintRenderPassOverlay(
       const gfx::Size& size,
       ResourceFormat format,
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 86df379..8e9038ab 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
@@ -1178,7 +1178,7 @@
     SkiaOutputSurface::OverlayList overlays,
     std::vector<ImageContextImpl*> image_contexts,
     base::OnceClosure on_finished) {
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   if (context_is_lost_)
     return;
 
@@ -1559,7 +1559,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(output_device_);
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   // Release any backings which are not reused by the current frame, probably
   // because the properties of render passes are changed or render passes are
   // removed
@@ -1713,7 +1713,7 @@
     waiting_for_full_damage_ = true;
   }
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   // |available_render_pass_overlay_backings_| are used or released in
   // SwapBuffers() for every frames.
   DCHECK(available_render_pass_overlay_backings_.empty());
@@ -1792,7 +1792,7 @@
     gl_surface_->PreserveChildSurfaceControls();
 }
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
 std::unique_ptr<gpu::SharedImageRepresentationSkia>
 SkiaOutputSurfaceImplOnGpu::GetOrCreateRenderPassOverlayBacking(
     const SkSurfaceCharacterization& characterization) {
@@ -1859,7 +1859,7 @@
 
   return backing;
 }
-#endif
+#endif  // defined(OS_APPLE)  || defined(USE_OZONE)
 
 void SkiaOutputSurfaceImplOnGpu::InitDelegatedInkPointRendererReceiver(
     mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer>
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 77a9e16..64878ae 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -277,7 +277,7 @@
 
   void ReleaseAsyncReadResultHelpers();
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   std::unique_ptr<gpu::SharedImageRepresentationSkia>
   GetOrCreateRenderPassOverlayBacking(
       const SkSurfaceCharacterization& characterization);
@@ -376,7 +376,7 @@
   // Tracking for ongoing AsyncReadResults.
   base::flat_set<AsyncReadResultHelper*> async_read_result_helpers_;
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   using UniqueBackingPtr = std::unique_ptr<gpu::SharedImageRepresentationSkia>;
   class BackingComparator {
    public:
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc
index e1a4d103..813831a7 100644
--- a/components/viz/test/fake_skia_output_surface.cc
+++ b/components/viz/test/fake_skia_output_surface.cc
@@ -321,7 +321,7 @@
   return sync_token;
 }
 
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
 SkCanvas* FakeSkiaOutputSurface::BeginPaintRenderPassOverlay(
     const gfx::Size& size,
     ResourceFormat format,
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h
index 973ee86..18f6605d 100644
--- a/components/viz/test/fake_skia_output_surface.h
+++ b/components/viz/test/fake_skia_output_surface.h
@@ -103,7 +103,7 @@
   void AddContextLostObserver(ContextLostObserver* observer) override;
   void RemoveContextLostObserver(ContextLostObserver* observer) override;
   gpu::SyncToken Flush() override;
-#if defined(OS_APPLE)
+#if defined(OS_APPLE) || defined(USE_OZONE)
   SkCanvas* BeginPaintRenderPassOverlay(
       const gfx::Size& size,
       ResourceFormat format,
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArImmersiveOverlay.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArImmersiveOverlay.java
index 54aef12..24599dc9 100644
--- a/components/webxr/android/java/src/org/chromium/components/webxr/ArImmersiveOverlay.java
+++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArImmersiveOverlay.java
@@ -149,6 +149,11 @@
             mSurfaceView.getHolder().addCallback(ArImmersiveOverlay.this);
             mSurfaceView.setKeepScreenOn(true);
 
+            // Exactly one surface view needs to call setZOrderMediaOverlay(true) otherwise the
+            // resulting z-order is undefined. The DOM content's surface will set it to true if
+            // |mDomSurfaceNeedsConfiguring| is set so we need to do the opposite here.
+            mSurfaceView.setZOrderMediaOverlay(!mDomSurfaceNeedsConfiguring);
+
             // Process touch input events for XR input. This consumes them, they'll be resent to
             // the compositor view via forwardMotionEvent.
             mSurfaceView.setOnTouchListener(ArImmersiveOverlay.this);
diff --git a/components/wifi/network_properties.cc b/components/wifi/network_properties.cc
index a24899ea1..56a3858 100644
--- a/components/wifi/network_properties.cc
+++ b/components/wifi/network_properties.cc
@@ -52,7 +52,7 @@
          ++it) {
       frequency_list->AppendInteger(*it);
     }
-    if (!frequency_list->empty())
+    if (!frequency_list->GetList().empty())
       wifi->Set(onc::wifi::kFrequencyList, std::move(frequency_list));
     if (!bssid.empty())
       wifi->SetString(onc::wifi::kBSSID, bssid);
diff --git a/components/zucchini/disassembler_dex.cc b/components/zucchini/disassembler_dex.cc
index 256ccdeb..a835fb2 100644
--- a/components/zucchini/disassembler_dex.cc
+++ b/components/zucchini/disassembler_dex.cc
@@ -17,6 +17,7 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/logging.h"
+#include "base/numerics/checked_math.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "components/zucchini/buffer_source.h"
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 39520f11..58f03d3 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -353,6 +353,14 @@
     "accessibility/web_contents_accessibility.h",
     "after_startup_task_utils.cc",
     "after_startup_task_utils.h",
+    "aggregation_service/aggregatable_report_manager.h",
+    "aggregation_service/aggregation_service_key_storage.h",
+    "aggregation_service/aggregation_service_storage.cc",
+    "aggregation_service/aggregation_service_storage.h",
+    "aggregation_service/public_key.cc",
+    "aggregation_service/public_key.h",
+    "aggregation_service/public_key_parsing_utils.cc",
+    "aggregation_service/public_key_parsing_utils.h",
     "appcache/appcache.cc",
     "appcache/appcache.h",
     "appcache/appcache_backend_impl.cc",
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
index 3c92513..287ae0d 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
@@ -1229,8 +1229,7 @@
       break;
     }
     case base::Value::Type::DOUBLE: {
-      double double_value = 0.0;
-      value->GetAsDouble(&double_value);
+      const double double_value = value->GetIfDouble().value_or(0.0);
       WriteAttribute(false,
                      base::StringPrintf("%s=%.2f", name.c_str(), double_value),
                      &line);
diff --git a/content/browser/aggregation_service/DIR_METADATA b/content/browser/aggregation_service/DIR_METADATA
new file mode 100644
index 0000000..4f8aa58
--- /dev/null
+++ b/content/browser/aggregation_service/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+  component: "Internals>ConversionMeasurement"
+}
+team_email: "privacy-sandbox-dev@chromium.org"
diff --git a/content/browser/aggregation_service/OWNERS b/content/browser/aggregation_service/OWNERS
new file mode 100644
index 0000000..c35fd95
--- /dev/null
+++ b/content/browser/aggregation_service/OWNERS
@@ -0,0 +1,4 @@
+alexmt@chromium.org
+csharrison@chromium.org
+# No Chromium committer status:
+# linnan@chromium.org
diff --git a/content/browser/aggregation_service/aggregatable_report_manager.h b/content/browser/aggregation_service/aggregatable_report_manager.h
new file mode 100644
index 0000000..4597e18
--- /dev/null
+++ b/content/browser/aggregation_service/aggregatable_report_manager.h
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_MANAGER_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_MANAGER_H_
+
+#include "base/threading/sequence_bound.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class AggregationServiceKeyStorage;
+
+// Interface that provides access to the storage.
+class CONTENT_EXPORT AggregatableReportManager {
+ public:
+  virtual ~AggregatableReportManager() = default;
+
+  virtual const base::SequenceBound<AggregationServiceKeyStorage>&
+  GetKeyStorage() = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATABLE_REPORT_MANAGER_H_
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_key_storage.h b/content/browser/aggregation_service/aggregation_service_key_storage.h
new file mode 100644
index 0000000..797b3570
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_key_storage.h
@@ -0,0 +1,33 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_STORAGE_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_STORAGE_H_
+
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+
+// This class provides an interface for persisting helper server public keys
+// and performing queries on it.
+class CONTENT_EXPORT AggregationServiceKeyStorage {
+ public:
+  virtual ~AggregationServiceKeyStorage() = default;
+
+  // Returns the public keys for `origin`.
+  virtual PublicKeysForOrigin GetPublicKeys(
+      const url::Origin& origin) const = 0;
+
+  // Sets the public keys for `origin`.
+  virtual void SetPublicKeys(const PublicKeysForOrigin& keys) = 0;
+
+  // Clears the stored public keys for `origin`.
+  virtual void ClearPublicKeys(const url::Origin& origin) = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_STORAGE_H_
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_storage.cc b/content/browser/aggregation_service/aggregation_service_storage.cc
new file mode 100644
index 0000000..63dc038
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_storage.cc
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/aggregation_service_storage.h"
+
+#include <utility>
+
+#include "content/browser/aggregation_service/public_key.h"
+
+namespace content {
+
+AggregationServiceStorage::AggregationServiceStorage() = default;
+
+AggregationServiceStorage::~AggregationServiceStorage() = default;
+
+PublicKeysForOrigin AggregationServiceStorage::GetPublicKeys(
+    const url::Origin& origin) const {
+  auto it = public_keys_map_.find(origin);
+  if (it != public_keys_map_.end()) {
+    return PublicKeysForOrigin(origin, it->second);
+  } else {
+    return PublicKeysForOrigin(origin, {});
+  }
+}
+
+void AggregationServiceStorage::SetPublicKeys(const PublicKeysForOrigin& keys) {
+  public_keys_map_.insert_or_assign(keys.origin, keys.keys);
+}
+
+void AggregationServiceStorage::ClearPublicKeys(const url::Origin& origin) {
+  public_keys_map_.erase(origin);
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_storage.h b/content/browser/aggregation_service/aggregation_service_storage.h
new file mode 100644
index 0000000..49472fb0
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_storage.h
@@ -0,0 +1,37 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_STORAGE_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_STORAGE_H_
+
+#include "base/containers/flat_map.h"
+#include "content/browser/aggregation_service/aggregation_service_key_storage.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+
+// Implements the storage interface with an in-memory store.
+class CONTENT_EXPORT AggregationServiceStorage
+    : public AggregationServiceKeyStorage {
+ public:
+  AggregationServiceStorage();
+  AggregationServiceStorage(const AggregationServiceStorage& other) = delete;
+  AggregationServiceStorage& operator=(const AggregationServiceStorage& other) =
+      delete;
+  ~AggregationServiceStorage() override;
+
+  // AggregationServiceKeyStorage:
+  PublicKeysForOrigin GetPublicKeys(const url::Origin& origin) const override;
+  void SetPublicKeys(const PublicKeysForOrigin& keys) override;
+  void ClearPublicKeys(const url::Origin& origin) override;
+
+ private:
+  base::flat_map<url::Origin, std::vector<PublicKey>> public_keys_map_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_STORAGE_H
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_storage_unittest.cc b/content/browser/aggregation_service/aggregation_service_storage_unittest.cc
new file mode 100644
index 0000000..dff3ee7
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_storage_unittest.cc
@@ -0,0 +1,47 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/aggregation_service_storage.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+class AggregationServiceStorageTest : public testing::Test {
+ public:
+  AggregationServiceStorageTest()
+      : storage_(std::make_unique<AggregationServiceStorage>()) {}
+
+ protected:
+  std::unique_ptr<AggregationServiceStorage> storage_;
+};
+
+TEST_F(AggregationServiceStorageTest, GetSetPublicKeys) {
+  std::vector<PublicKey> expected_keys{
+      PublicKey("abcd", "defg", base::Time::FromJavaTime(1623000000000),
+                base::Time::FromJavaTime(1624000000000)),
+      PublicKey("bcde", "fghi", base::Time::FromJavaTime(1624000000000),
+                base::Time::FromJavaTime(1625000000000)),
+  };
+
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+
+  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, expected_keys));
+  PublicKeysForOrigin keys = storage_->GetPublicKeys(origin);
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(expected_keys, keys.keys));
+
+  storage_->ClearPublicKeys(origin);
+  keys = storage_->GetPublicKeys(origin);
+  EXPECT_TRUE(keys.keys.empty());
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_test_utils.cc b/content/browser/aggregation_service/aggregation_service_test_utils.cc
new file mode 100644
index 0000000..60de61d
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_test_utils.cc
@@ -0,0 +1,53 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+
+#include <tuple>
+
+#include "base/task/thread_pool.h"
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service_storage.h"
+
+namespace content {
+
+namespace aggregation_service {
+
+testing::AssertionResult PublicKeysEqual(const std::vector<PublicKey>& expected,
+                                         const std::vector<PublicKey>& actual) {
+  const auto tie = [](const PublicKey& key) {
+    return std::make_tuple(key.id(), key.key(), key.not_before_time(),
+                           key.not_after_time());
+  };
+
+  if (expected.size() != actual.size()) {
+    return testing::AssertionFailure() << "Expected length " << expected.size()
+                                       << ", actual: " << actual.size();
+  }
+
+  for (size_t i = 0; i < expected.size(); i++) {
+    if (tie(expected[i]) != tie(actual[i])) {
+      return testing::AssertionFailure()
+             << "Expected " << expected[i] << " at index " << i
+             << ", actual: " << actual[i];
+    }
+  }
+
+  return testing::AssertionSuccess();
+}
+
+}  // namespace aggregation_service
+
+TestAggregatableReportManager::TestAggregatableReportManager()
+    : storage_(base::SequenceBound<AggregationServiceStorage>(
+          base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))) {}
+
+TestAggregatableReportManager::~TestAggregatableReportManager() = default;
+
+const base::SequenceBound<content::AggregationServiceKeyStorage>&
+TestAggregatableReportManager::GetKeyStorage() {
+  return storage_;
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/aggregation_service/aggregation_service_test_utils.h b/content/browser/aggregation_service/aggregation_service_test_utils.h
new file mode 100644
index 0000000..47d12467
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_test_utils.h
@@ -0,0 +1,44 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_TEST_UTILS_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_TEST_UTILS_H_
+
+#include <vector>
+
+#include "base/threading/sequence_bound.h"
+#include "content/browser/aggregation_service/aggregatable_report_manager.h"
+#include "content/browser/aggregation_service/aggregation_service_key_storage.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace aggregation_service {
+
+testing::AssertionResult PublicKeysEqual(const std::vector<PublicKey>& expected,
+                                         const std::vector<PublicKey>& actual);
+
+}  // namespace aggregation_service
+
+class TestAggregatableReportManager : public AggregatableReportManager {
+ public:
+  TestAggregatableReportManager();
+  TestAggregatableReportManager(const TestAggregatableReportManager& other) =
+      delete;
+  TestAggregatableReportManager& operator=(
+      const TestAggregatableReportManager& other) = delete;
+  ~TestAggregatableReportManager() override;
+
+  // AggregatableReportManager:
+  const base::SequenceBound<content::AggregationServiceKeyStorage>&
+  GetKeyStorage() override;
+
+ private:
+  base::SequenceBound<content::AggregationServiceKeyStorage> storage_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_TEST_UTILS_H_
\ No newline at end of file
diff --git a/content/browser/aggregation_service/public_key.cc b/content/browser/aggregation_service/public_key.cc
new file mode 100644
index 0000000..3adfceb
--- /dev/null
+++ b/content/browser/aggregation_service/public_key.cc
@@ -0,0 +1,45 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/public_key.h"
+
+#include <utility>
+
+#include "base/check_op.h"
+
+namespace content {
+
+PublicKey::PublicKey(std::string id,
+                     std::string key,
+                     base::Time not_before_time,
+                     base::Time not_after_time)
+    : id_(std::move(id)),
+      key_(std::move(key)),
+      not_before_time_(not_before_time),
+      not_after_time_(not_after_time) {
+  DCHECK_LE(not_before_time_, not_after_time_);
+}
+
+PublicKeysForOrigin::PublicKeysForOrigin() = default;
+
+PublicKeysForOrigin::PublicKeysForOrigin(url::Origin origin,
+                                         std::vector<PublicKey> keys)
+    : origin(std::move(origin)), keys(std::move(keys)) {}
+
+PublicKeysForOrigin::PublicKeysForOrigin(const PublicKeysForOrigin& other) =
+    default;
+
+PublicKeysForOrigin& PublicKeysForOrigin::operator=(
+    const PublicKeysForOrigin& other) = default;
+
+PublicKeysForOrigin::~PublicKeysForOrigin() = default;
+
+std::ostream& operator<<(std::ostream& out, const PublicKey& public_key) {
+  out << "id: " << public_key.id() << ", key: " << public_key.key()
+      << ", not_before_time: " << public_key.not_before_time()
+      << ", not_after_time: " << public_key.not_after_time();
+  return out;
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/aggregation_service/public_key.h b/content/browser/aggregation_service/public_key.h
new file mode 100644
index 0000000..fcdba9bf
--- /dev/null
+++ b/content/browser/aggregation_service/public_key.h
@@ -0,0 +1,69 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_H_
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+
+// Class that contains all the data of a public key.
+class CONTENT_EXPORT PublicKey {
+ public:
+  PublicKey() = default;
+  PublicKey(std::string id,
+            std::string key,
+            base::Time not_before_time,
+            base::Time not_after_time);
+  PublicKey(const PublicKey& other) = default;
+  PublicKey& operator=(const PublicKey& other) = default;
+  ~PublicKey() = default;
+
+  std::string id() const { return id_; }
+
+  std::string key() const { return key_; }
+
+  base::Time not_before_time() const { return not_before_time_; }
+
+  base::Time not_after_time() const { return not_after_time_; }
+
+ private:
+  // String identifying the key, controlled by the helper server.
+  std::string id_;
+
+  // Base64-encoded public key.
+  std::string key_;
+
+  // The first time the key is valid.
+  base::Time not_before_time_;
+
+  // The time the key expires.
+  base::Time not_after_time_;
+};
+
+struct CONTENT_EXPORT PublicKeysForOrigin {
+  PublicKeysForOrigin();
+  PublicKeysForOrigin(url::Origin origin, std::vector<PublicKey> keys);
+  PublicKeysForOrigin(const PublicKeysForOrigin& other);
+  PublicKeysForOrigin& operator=(const PublicKeysForOrigin& other);
+  ~PublicKeysForOrigin();
+
+  url::Origin origin;
+  std::vector<PublicKey> keys;
+};
+
+// Only used for logging.
+CONTENT_EXPORT std::ostream& operator<<(std::ostream& out,
+                                        const PublicKey& public_key);
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_H_
diff --git a/content/browser/aggregation_service/public_key_parsing_utils.cc b/content/browser/aggregation_service/public_key_parsing_utils.cc
new file mode 100644
index 0000000..ac2d309d
--- /dev/null
+++ b/content/browser/aggregation_service/public_key_parsing_utils.cc
@@ -0,0 +1,128 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/public_key_parsing_utils.h"
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace content {
+
+namespace {
+
+const char kKeyId[] = "id";
+const char kKeyKey[] = "key";
+const char kKeyNotBefore[] = "not_before";
+const char kKeyNotAfter[] = "not_after";
+
+// Returns the latest version id from multiple JSON arrays tagged with version
+// ids, currently based on the lexicographical comparison of version ids. In
+// case of an error or invalid JSON, returns an empty string.
+std::string GetLatestVersion(base::Value& value) {
+  if (!value.is_dict())
+    return "";
+
+  // TODO(crbug.com/1218920): Implement the logic to get latest supported
+  // version.
+
+  std::string latest_version;
+
+  for (const auto& kv : value.DictItems()) {
+    const std::string& version = kv.first;
+    if (version < latest_version)
+      continue;
+
+    if (!kv.second.is_list())
+      continue;
+
+    latest_version = version;
+  }
+
+  return latest_version;
+}
+
+// This attempts to extract the 64-bit integer value associated with `key`. In
+// case of failure, e.g. the key does not exist or doesn't have 64-bit integer
+// type, nullopt is returned.
+absl::optional<int64_t> ExtractKeyInt64(base::Value& value,
+                                        const std::string& key) {
+  absl::optional<base::Value> str = value.ExtractKey(key);
+  if (!str || !str.value().is_string())
+    return absl::nullopt;
+
+  int64_t number = 0;
+  if (!base::StringToInt64(str.value().GetString(), &number))
+    return absl::nullopt;
+
+  return absl::make_optional(number);
+}
+
+// Constructs a public key from a single JSON key definition. Returns
+// `absl::nullopt`in case of an error or invalid JSON.
+absl::optional<PublicKey> GetPublicKey(base::Value& value) {
+  if (!value.is_dict())
+    return absl::nullopt;
+
+  absl::optional<base::Value> id = value.ExtractKey(kKeyId);
+  if (!id || !id.value().is_string())
+    return absl::nullopt;
+
+  absl::optional<base::Value> key = value.ExtractKey(kKeyKey);
+  if (!key || !key.value().is_string())
+    return absl::nullopt;
+
+  absl::optional<int64_t> not_before = ExtractKeyInt64(value, kKeyNotBefore);
+  if (!not_before)
+    return absl::nullopt;
+
+  absl::optional<int64_t> not_after = ExtractKeyInt64(value, kKeyNotAfter);
+  if (!not_after)
+    return absl::nullopt;
+
+  return PublicKey(id.value().GetString(), key.value().GetString(),
+                   base::Time::UnixEpoch() +
+                       base::TimeDelta::FromMilliseconds(not_before.value()),
+                   base::Time::UnixEpoch() +
+                       base::TimeDelta::FromMilliseconds(not_after.value()));
+}
+
+}  // namespace
+
+namespace aggregation_service {
+
+std::vector<PublicKey> GetPublicKeys(base::Value& value) {
+  if (!value.is_dict())
+    return {};
+
+  std::string latest_version = GetLatestVersion(value);
+  if (latest_version.empty())
+    return {};
+
+  absl::optional<base::Value> latest_json_object =
+      value.ExtractKey(latest_version);
+
+  if (!latest_json_object.value().is_list())
+    return {};
+
+  std::vector<PublicKey> keys_vec;
+  for (auto& key_json : latest_json_object.value().GetList()) {
+    absl::optional<PublicKey> key = GetPublicKey(key_json);
+    if (key)
+      keys_vec.push_back(key.value());
+  }
+
+  return keys_vec;
+}
+
+}  // namespace aggregation_service
+
+}  // namespace content
diff --git a/content/browser/aggregation_service/public_key_parsing_utils.h b/content/browser/aggregation_service/public_key_parsing_utils.h
new file mode 100644
index 0000000..36f700471
--- /dev/null
+++ b/content/browser/aggregation_service/public_key_parsing_utils.h
@@ -0,0 +1,44 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_PARSING_UTILS_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_PARSING_UTILS_H_
+
+#include <vector>
+
+#include "base/values.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+namespace aggregation_service {
+
+// Constructs a public key vector from multiple JSON arrays of key definition
+// tagged with version ids. In case of an error or invalid JSON, returns an
+// empty vector.
+//
+// The expected JSON schema is as follows.
+//
+// {
+//   <Version ID> : [
+//     {
+//        "id" : <arbitrary string identifying the key, e.g. a UUID>,
+//        "key" : <base64-encoded public key>,
+//        "not_before" : <when key become valid, encoded as a string
+//                      representation of an integer timestamp in milliseconds
+//                      since the Unix epoch>,
+//        "not_after" : <key expiry, encoded similarly to not_before>,
+//     },
+//     {  "id" : <different ID string>, ... },
+//     ...
+//   ]
+// }
+CONTENT_EXPORT std::vector<PublicKey> GetPublicKeys(base::Value& value);
+
+}  // namespace aggregation_service
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_PUBLIC_KEY_PARSING_UTILS_H_
\ No newline at end of file
diff --git a/content/browser/aggregation_service/public_key_parsing_utils_unittest.cc b/content/browser/aggregation_service/public_key_parsing_utils_unittest.cc
new file mode 100644
index 0000000..5d1dbaa2
--- /dev/null
+++ b/content/browser/aggregation_service/public_key_parsing_utils_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/aggregation_service/public_key_parsing_utils.h"
+
+#include <string>
+
+#include "base/json/json_reader.h"
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+TEST(PublicKeyParsingUtilsTest, WellFormedSingleKey_ParsedCorrectly) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "key" : "ABCD1234",
+                    "not_before": "1623000000000",
+                    "not_after" : "1633000000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(
+      {PublicKey("abcd", "ABCD1234", base::Time::FromJavaTime(1623000000000),
+                 base::Time::FromJavaTime(1633000000000))},
+      keys));
+}
+
+TEST(PublicKeyParsingUtilsTest, WellFormedMultipleKeys_ParsedCorrectly) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "key" : "ABCD1234",
+                    "not_before": "1623000000000",
+                    "not_after" : "1633000000000"
+                },
+                {
+                    "id" : "efgh",
+                    "key": "EFGH5678",
+                    "not_before": "1622500000000",
+                    "not_after" : "1632500000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(
+      {PublicKey("abcd", "ABCD1234", base::Time::FromJavaTime(1623000000000),
+                 base::Time::FromJavaTime(1633000000000)),
+       PublicKey("efgh", "EFGH5678", base::Time::FromJavaTime(1622500000000),
+                 base::Time::FromJavaTime(1632500000000))},
+      keys));
+}
+
+TEST(PublicKeyParsingUtilsTest, MalformedMissingId_EmptyResult) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "key" : "ABCD1234",
+                    "not_before": "1623000000000",
+                    "not_after" : "1633000000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(keys.empty());
+}
+
+TEST(PublicKeyParsingUtilsTest, MalformedMissingKey_EmptyResult) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "not_before": "1623000000000",
+                    "not_after" : "1633000000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(keys.empty());
+}
+
+TEST(PublicKeyParsingUtilsTest, MalformedMissingNotBefore_EmptyResult) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "key" : "ABCD1234",
+                    "not_after" : "1633000000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(keys.empty());
+}
+
+TEST(PublicKeyParsingUtilsTest, MalformedMissingNotAfter_EmptyResult) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "key" : "ABCD1234",
+                    "not_before": "1623000000000"
+                }
+            ]
+        }
+    )";
+
+  absl::optional<base::Value> json_object = base::JSONReader::Read(json_string);
+  ASSERT_TRUE(json_object) << "Incorrectly formatted JSON string.";
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(json_object.value());
+  EXPECT_TRUE(keys.empty());
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index 608f13f..8a741779 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -381,7 +381,7 @@
   *error_code = result->GetInvocationError();
   if (result->HoldsPrimitiveResult()) {
     std::unique_ptr<base::ListValue> result_copy(
-        result->GetPrimitiveResult().DeepCopy());
+        result->GetPrimitiveResult().CreateDeepCopy());
     wrapped_result->Swap(result_copy.get());
   } else if (!result->GetObjectResult().is_null()) {
     GinJavaBoundObject::ObjectID returned_object_id;
diff --git a/content/browser/android/java/gin_java_method_invocation_helper.cc b/content/browser/android/java/gin_java_method_invocation_helper.cc
index 8f99328..c6d673b8 100644
--- a/content/browser/android/java/gin_java_method_invocation_helper.cc
+++ b/content/browser/android/java/gin_java_method_invocation_helper.cc
@@ -35,7 +35,7 @@
     const base::ListValue& arguments)
     : object_(std::move(object)),
       method_name_(method_name),
-      arguments_(arguments.DeepCopy()),
+      arguments_(arguments.CreateDeepCopy()),
       invocation_error_(kGinJavaBridgeNoError) {}
 
 GinJavaMethodInvocationHelper::~GinJavaMethodInvocationHelper() {}
@@ -178,7 +178,7 @@
 void GinJavaMethodInvocationHelper::SetPrimitiveResult(
     const base::ListValue& result_wrapper) {
   holds_primitive_result_ = true;
-  primitive_result_.reset(result_wrapper.DeepCopy());
+  primitive_result_ = result_wrapper.CreateDeepCopy();
 }
 
 void GinJavaMethodInvocationHelper::SetObjectResult(
diff --git a/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc b/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
index d632dc4..399c54b 100644
--- a/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
+++ b/content/browser/android/java/gin_java_method_invocation_helper_unittest.cc
@@ -221,7 +221,7 @@
   helper->Invoke();
   EXPECT_TRUE(object_delegate->get_local_ref_called());
   EXPECT_TRUE(helper->HoldsPrimitiveResult());
-  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
+  EXPECT_TRUE(helper->GetPrimitiveResult().GetList().empty());
   EXPECT_EQ(kGinJavaBridgeObjectIsGone, helper->GetInvocationError());
 }
 
@@ -271,7 +271,7 @@
   helper->Invoke();
   EXPECT_TRUE(object_delegate->find_method_called());
   EXPECT_TRUE(helper->HoldsPrimitiveResult());
-  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
+  EXPECT_TRUE(helper->GetPrimitiveResult().GetList().empty());
   EXPECT_EQ(kGinJavaBridgeMethodNotFound, helper->GetInvocationError());
 }
 
@@ -329,7 +329,7 @@
   EXPECT_TRUE(object_delegate->find_method_called());
   EXPECT_TRUE(object_delegate->get_class_called());
   EXPECT_TRUE(helper->HoldsPrimitiveResult());
-  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
+  EXPECT_TRUE(helper->GetPrimitiveResult().GetList().empty());
   EXPECT_EQ(kGinJavaBridgeAccessToObjectGetClassIsBlocked,
             helper->GetInvocationError());
 }
diff --git a/content/browser/android/overscroll_controller_android.cc b/content/browser/android/overscroll_controller_android.cc
index e452b41..774c669 100644
--- a/content/browser/android/overscroll_controller_android.cc
+++ b/content/browser/android/overscroll_controller_android.cc
@@ -19,7 +19,8 @@
 #include "ui/android/window_android.h"
 #include "ui/android/window_android_compositor.h"
 #include "ui/base/l10n/l10n_util_android.h"
-#include "ui/base/ui_base_features.h"
+#include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/events/blink/did_overscroll_params.h"
 
 using ui::DidOverscrollParams;
@@ -53,7 +54,7 @@
   // The elastic overscroll feature indicates when the user is scrolling beyond
   // the range of the scrollable area. Showing a glow in addition would be
   // redundant.
-  if (base::FeatureList::IsEnabled(features::kElasticOverscroll))
+  if (switches::IsElasticOverscrollEnabled())
     return nullptr;
 
   return std::make_unique<OverscrollGlow>(client);
diff --git a/content/browser/android/selection/selection_popup_controller.cc b/content/browser/android/selection/selection_popup_controller.cc
index 24ce0e34..3910aee5 100644
--- a/content/browser/android/selection/selection_popup_controller.cc
+++ b/content/browser/android/selection/selection_popup_controller.cc
@@ -155,6 +155,7 @@
 }
 
 bool SelectionPopupController::ShowSelectionMenu(
+    RenderFrameHost* render_frame_host,
     const ContextMenuParams& params,
     int handle_height) {
   JNIEnv* env = AttachCurrentThread();
@@ -197,7 +198,8 @@
       params.selection_rect.right(), params.selection_rect.bottom(),
       handle_height, params.is_editable, is_password_type, jselected_text,
       params.selection_start_offset, can_select_all, can_edit_richly,
-      should_suggest, params.source_type);
+      should_suggest, params.source_type,
+      render_frame_host->GetJavaRenderFrameHost());
   return true;
 }
 
diff --git a/content/browser/android/selection/selection_popup_controller.h b/content/browser/android/selection/selection_popup_controller.h
index 2eff17e0..f83c682 100644
--- a/content/browser/android/selection/selection_popup_controller.h
+++ b/content/browser/android/selection/selection_popup_controller.h
@@ -43,7 +43,9 @@
   void OnDragUpdate(const ui::TouchSelectionDraggable::Type type,
                     const gfx::PointF& position);
   void OnSelectionChanged(const std::string& text);
-  bool ShowSelectionMenu(const ContextMenuParams& params, int handle_height);
+  bool ShowSelectionMenu(RenderFrameHost* render_frame_host,
+                         const ContextMenuParams& params,
+                         int handle_height);
   void OnSelectWordAroundCaretAck(bool did_select,
                                   int start_adjust,
                                   int end_adjust);
diff --git a/content/browser/conversions/PRESUBMIT.py b/content/browser/conversions/PRESUBMIT.py
index 7c45aa46..768e7f0 100644
--- a/content/browser/conversions/PRESUBMIT.py
+++ b/content/browser/conversions/PRESUBMIT.py
@@ -16,6 +16,7 @@
   Whenever any of the following files is changed:
     - conversion_storage_sql.cc
     - conversion_storage_sql_migrations.cc
+    - rate_limit_table.cc
   and kCurrentVersionNumber stays intact, this check returns a
   presubmit warning to make sure the value is updated if necessary.
   """
@@ -27,7 +28,8 @@
     basename = input_api.basename(affected_file.LocalPath())
 
     if (basename == 'conversion_storage_sql_migrations.cc' or
-        basename == 'conversion_storage_sql.cc'):
+        basename == 'conversion_storage_sql.cc' or
+        basename == 'rate_limit_table.cc'):
       database_files_changed = True
 
     if basename == 'conversion_storage_sql.cc':
diff --git a/content/browser/conversions/conversion_host.cc b/content/browser/conversions/conversion_host.cc
index 06f9241..b863674 100644
--- a/content/browser/conversions/conversion_host.cc
+++ b/content/browser/conversions/conversion_host.cc
@@ -258,7 +258,8 @@
       policy.GetSanitizedImpressionData(impression.impression_data),
       impression_origin, impression.conversion_destination, reporting_origin,
       impression_time,
-      policy.GetExpiryTimeForImpression(impression.expiry, impression_time),
+      policy.GetExpiryTimeForImpression(impression.expiry, impression_time,
+                                        source_type),
       source_type, impression.priority,
       /*impression_id=*/absl::nullopt);
 
diff --git a/content/browser/conversions/conversion_policy.cc b/content/browser/conversions/conversion_policy.cc
index 4558e02..457d44b 100644
--- a/content/browser/conversions/conversion_policy.cc
+++ b/content/browser/conversions/conversion_policy.cc
@@ -4,8 +4,8 @@
 
 #include "content/browser/conversions/conversion_policy.h"
 
-#include "base/format_macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/numerics/ranges.h"
 #include "base/rand_util.h"
 #include "base/time/time.h"
 
@@ -109,15 +109,23 @@
 
 base::Time ConversionPolicy::GetExpiryTimeForImpression(
     const absl::optional<base::TimeDelta>& declared_expiry,
-    base::Time impression_time) const {
-  static constexpr base::TimeDelta kDefaultImpressionExpiry =
+    base::Time impression_time,
+    StorableImpression::SourceType source_type) const {
+  constexpr base::TimeDelta kMinImpressionExpiry = base::TimeDelta::FromDays(1);
+  constexpr base::TimeDelta kDefaultImpressionExpiry =
       base::TimeDelta::FromDays(30);
 
   // Default to the maximum expiry time.
   base::TimeDelta expiry = declared_expiry.value_or(kDefaultImpressionExpiry);
 
-  // If the impression specified its own expiry, clamp it to the maximum.
-  return impression_time + std::min(expiry, kDefaultImpressionExpiry);
+  // Expiry time for event sources must be a whole number of days.
+  if (source_type == StorableImpression::SourceType::kEvent)
+    expiry = expiry.RoundToMultiple(base::TimeDelta::FromDays(1));
+
+  // If the impression specified its own expiry, clamp it to the minimum and
+  // maximum.
+  return impression_time + base::ClampToRange(expiry, kMinImpressionExpiry,
+                                              kDefaultImpressionExpiry);
 }
 
 base::Time ConversionPolicy::GetReportTimeForExpiredReportAtStartup(
diff --git a/content/browser/conversions/conversion_policy.h b/content/browser/conversions/conversion_policy.h
index d073a58..250d8a6 100644
--- a/content/browser/conversions/conversion_policy.h
+++ b/content/browser/conversions/conversion_policy.h
@@ -7,10 +7,9 @@
 
 #include <stdint.h>
 #include <memory>
-#include <string>
-#include <vector>
 
 #include "base/time/time.h"
+#include "content/browser/conversions/storable_impression.h"
 #include "content/common/content_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -75,7 +74,8 @@
   // value of 30 days from |impression_time|.
   virtual base::Time GetExpiryTimeForImpression(
       const absl::optional<base::TimeDelta>& declared_expiry,
-      base::Time impression_time) const;
+      base::Time impression_time,
+      StorableImpression::SourceType source_type) const;
 
   // Delays reports that should have been sent while the browser was not open by
   // given them a noisy report time to help disassociate them from other
diff --git a/content/browser/conversions/conversion_policy_unittest.cc b/content/browser/conversions/conversion_policy_unittest.cc
index d320124c..43a0aa65 100644
--- a/content/browser/conversions/conversion_policy_unittest.cc
+++ b/content/browser/conversions/conversion_policy_unittest.cc
@@ -9,12 +9,18 @@
 
 #include "base/time/time.h"
 #include "content/browser/conversions/conversion_test_utils.h"
+#include "content/browser/conversions/storable_impression.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
 namespace {
 
+const StorableImpression::SourceType kSourceTypes[] = {
+    StorableImpression::SourceType::kNavigation,
+    StorableImpression::SourceType::kEvent,
+};
+
 // Fake ConversionNoiseProvider that return un-noised conversion data.
 class EmptyNoiseProvider : public ConversionPolicy::NoiseProvider {
  public:
@@ -133,26 +139,87 @@
 }
 
 TEST_F(ConversionPolicyTest, NoExpiryForImpression_DefaultUsed) {
-  base::Time impression_time = base::Time::Now();
-  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(30),
-            ConversionPolicy().GetExpiryTimeForImpression(
-                /*declared_expiry=*/absl::nullopt, impression_time));
+  const base::Time impression_time = base::Time::Now();
+
+  for (auto source_type : kSourceTypes) {
+    EXPECT_EQ(
+        impression_time + base::TimeDelta::FromDays(30),
+        ConversionPolicy().GetExpiryTimeForImpression(
+            /*declared_expiry=*/absl::nullopt, impression_time, source_type));
+  }
 }
 
 TEST_F(ConversionPolicyTest, LargeImpressionExpirySpecified_ClampedTo30Days) {
   constexpr base::TimeDelta declared_expiry = base::TimeDelta::FromDays(60);
-  base::Time impression_time = base::Time::Now();
-  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(30),
-            ConversionPolicy().GetExpiryTimeForImpression(declared_expiry,
-                                                          impression_time));
+  const base::Time impression_time = base::Time::Now();
+
+  for (auto source_type : kSourceTypes) {
+    EXPECT_EQ(impression_time + base::TimeDelta::FromDays(30),
+              ConversionPolicy().GetExpiryTimeForImpression(
+                  declared_expiry, impression_time, source_type));
+  }
+}
+
+TEST_F(ConversionPolicyTest, SmallImpressionExpirySpecified_ClampedTo1Day) {
+  const struct {
+    base::TimeDelta declared_expiry;
+    base::TimeDelta want_expiry;
+  } kTestCases[] = {
+      {base::TimeDelta::FromDays(-1), base::TimeDelta::FromDays(1)},
+      {base::TimeDelta::FromDays(0), base::TimeDelta::FromDays(1)},
+      {base::TimeDelta::FromDays(1) - base::TimeDelta::FromMilliseconds(1),
+       base::TimeDelta::FromDays(1)},
+  };
+
+  const base::Time impression_time = base::Time::Now();
+
+  for (auto source_type : kSourceTypes) {
+    for (const auto& test_case : kTestCases) {
+      EXPECT_EQ(impression_time + test_case.want_expiry,
+                ConversionPolicy().GetExpiryTimeForImpression(
+                    test_case.declared_expiry, impression_time, source_type));
+    }
+  }
+}
+
+TEST_F(ConversionPolicyTest, NonWholeDayImpressionExpirySpecified_Rounded) {
+  const struct {
+    StorableImpression::SourceType source_type;
+    base::TimeDelta declared_expiry;
+    base::TimeDelta want_expiry;
+  } kTestCases[] = {
+      {StorableImpression::SourceType::kNavigation,
+       base::TimeDelta::FromHours(36), base::TimeDelta::FromHours(36)},
+      {StorableImpression::SourceType::kEvent, base::TimeDelta::FromHours(36),
+       base::TimeDelta::FromDays(2)},
+
+      {StorableImpression::SourceType::kNavigation,
+       base::TimeDelta::FromDays(1) + base::TimeDelta::FromMilliseconds(1),
+       base::TimeDelta::FromDays(1) + base::TimeDelta::FromMilliseconds(1)},
+      {StorableImpression::SourceType::kEvent,
+       base::TimeDelta::FromDays(1) + base::TimeDelta::FromMilliseconds(1),
+       base::TimeDelta::FromDays(1)},
+  };
+
+  const base::Time impression_time = base::Time::Now();
+
+  for (const auto& test_case : kTestCases) {
+    EXPECT_EQ(
+        impression_time + test_case.want_expiry,
+        ConversionPolicy().GetExpiryTimeForImpression(
+            test_case.declared_expiry, impression_time, test_case.source_type));
+  }
 }
 
 TEST_F(ConversionPolicyTest, ImpressionExpirySpecified_ExpiryOverrideDefault) {
   constexpr base::TimeDelta declared_expiry = base::TimeDelta::FromDays(10);
-  base::Time impression_time = base::Time::Now();
-  EXPECT_EQ(impression_time + base::TimeDelta::FromDays(10),
-            ConversionPolicy().GetExpiryTimeForImpression(declared_expiry,
-                                                          impression_time));
+  const base::Time impression_time = base::Time::Now();
+
+  for (auto source_type : kSourceTypes) {
+    EXPECT_EQ(impression_time + base::TimeDelta::FromDays(10),
+              ConversionPolicy().GetExpiryTimeForImpression(
+                  declared_expiry, impression_time, source_type));
+  }
 }
 
 }  // namespace content
diff --git a/content/browser/conversions/storable_impression.cc b/content/browser/conversions/storable_impression.cc
index 27b68ca00..678ae4ac 100644
--- a/content/browser/conversions/storable_impression.cc
+++ b/content/browser/conversions/storable_impression.cc
@@ -28,6 +28,8 @@
       impression_id_(impression_id) {
   // 30 days is the max allowed expiry for an impression.
   DCHECK_GE(base::TimeDelta::FromDays(30), expiry_time - impression_time);
+  // The impression must expire strictly after it occurred.
+  DCHECK_GT(expiry_time, impression_time);
   DCHECK(!impression_origin.opaque());
   DCHECK(!reporting_origin.opaque());
   DCHECK(!conversion_origin.opaque());
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 4a32236..b1ff30b 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -1030,16 +1030,14 @@
 namespace {
 
 void AddIssueToIssueStorage(
-    RenderFrameHost* frame,
+    RenderFrameHost* rfh,
     std::unique_ptr<protocol::Audits::InspectorIssue> issue) {
-  // We only utilize a central storage on the main frame. Each issue is
-  // still associated with the originating |RenderFrameHost| though.
+  // We only utilize a central storage on the page. Each issue is still
+  // associated with the originating |RenderFrameHost| though.
   DevToolsIssueStorage* issue_storage =
-      DevToolsIssueStorage::GetOrCreateForCurrentDocument(
-          frame->GetMainFrame());
+      DevToolsIssueStorage::GetOrCreateForPage(rfh->GetPage());
 
-  issue_storage->AddInspectorIssue(frame->GetFrameTreeNodeId(),
-                                   std::move(issue));
+  issue_storage->AddInspectorIssue(rfh, std::move(issue));
 }
 
 }  // namespace
diff --git a/content/browser/devtools/devtools_issue_storage.cc b/content/browser/devtools/devtools_issue_storage.cc
index 28f10867..b392f08 100644
--- a/content/browser/devtools/devtools_issue_storage.cc
+++ b/content/browser/devtools/devtools_issue_storage.cc
@@ -5,7 +5,8 @@
 #include "content/browser/devtools/devtools_issue_storage.h"
 
 #include "content/browser/devtools/protocol/audits.h"
-#include "content/browser/renderer_host/frame_tree_node.h"
+#include "content/browser/devtools/render_frame_devtools_agent_host.h"
+#include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/page_transition_types.h"
@@ -14,51 +15,56 @@
 
 static const unsigned kMaxIssueCount = 1000;
 
-RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(DevToolsIssueStorage)
+PAGE_USER_DATA_KEY_IMPL(DevToolsIssueStorage)
 
-DevToolsIssueStorage::DevToolsIssueStorage(RenderFrameHost* rfh)
-    : WebContentsObserver(content::WebContents::FromRenderFrameHost(rfh)) {}
+DevToolsIssueStorage::DevToolsIssueStorage(Page& page)
+    : PageUserData<DevToolsIssueStorage>(page) {}
 DevToolsIssueStorage::~DevToolsIssueStorage() = default;
 
 void DevToolsIssueStorage::AddInspectorIssue(
-    int frame_tree_node_id,
+    RenderFrameHost* rfh,
     std::unique_ptr<protocol::Audits::InspectorIssue> issue) {
   DCHECK_LE(issues_.size(), kMaxIssueCount);
   if (issues_.size() == kMaxIssueCount) {
     issues_.pop_front();
   }
-  issues_.emplace_back(frame_tree_node_id, std::move(issue));
+  issues_.emplace_back(rfh->GetGlobalId(), std::move(issue));
 }
 
 std::vector<const protocol::Audits::InspectorIssue*>
-DevToolsIssueStorage::FilterIssuesBy(
-    const base::flat_set<int>& frame_tree_node_ids) const {
+DevToolsIssueStorage::FindIssuesForAgentOf(
+    RenderFrameHost* render_frame_host) const {
+  RenderFrameHostImpl* render_frame_host_impl =
+      static_cast<RenderFrameHostImpl*>(render_frame_host);
+  RenderFrameHostImpl* main_rfh =
+      static_cast<RenderFrameHostImpl*>(&page().GetMainDocument());
+  DevToolsAgentHostImpl* agent_host =
+      RenderFrameDevToolsAgentHost::GetFor(render_frame_host_impl);
+  DCHECK_EQ(&render_frame_host->GetPage(), &page());
+  DCHECK(RenderFrameDevToolsAgentHost::ShouldCreateDevToolsForHost(
+      render_frame_host_impl));
+  DCHECK(agent_host);
+  bool is_main_agent = render_frame_host_impl == main_rfh;
+
   std::vector<const protocol::Audits::InspectorIssue*> issues;
   for (const auto& entry : issues_) {
-    if (frame_tree_node_ids.contains(entry.first)) {
-      issues.push_back(entry.second.get());
+    bool should_add;
+    RenderFrameHostImpl* issue_rfh = RenderFrameHostImpl::FromID(entry.first);
+    if (!issue_rfh) {
+      // Issues that fall in this category are either associated with |main_rfh|
+      // or with deleted subframe RFHs of |main_rfh|. In both cases, we only
+      // want to retrieve them for |main_rfh|'s agent.
+      // Note: This means that issues for deleted subframe RFHs get reparented
+      // to |main_rfh| after deletion.
+      should_add = is_main_agent;
+    } else {
+      should_add =
+          RenderFrameDevToolsAgentHost::GetFor(issue_rfh) == agent_host;
     }
+    if (should_add)
+      issues.push_back(entry.second.get());
   }
   return issues;
 }
 
-void DevToolsIssueStorage::FrameDeleted(int frame_tree_node_id) {
-  const int main_frame_id = FrameTreeNode::GloballyFindByID(frame_tree_node_id)
-                                ->frame_tree()
-                                ->root()
-                                ->frame_tree_node_id();
-  // Deletion of the main frame causes the DevToolsIssueStorage to be cleaned
-  // up. Also there would no longer be a root frame we could re-parent issues
-  // on.
-  if (frame_tree_node_id == main_frame_id)
-    return;
-
-  // Reassign issues from the deleted frame to the root frame.
-  for (auto& entry : issues_) {
-    if (entry.first == frame_tree_node_id) {
-      entry.first = main_frame_id;
-    }
-  }
-}
-
 }  // namespace content
diff --git a/content/browser/devtools/devtools_issue_storage.h b/content/browser/devtools/devtools_issue_storage.h
index 9076151..7fe923e 100644
--- a/content/browser/devtools/devtools_issue_storage.h
+++ b/content/browser/devtools/devtools_issue_storage.h
@@ -7,7 +7,8 @@
 
 #include "base/containers/circular_deque.h"
 #include "base/unguessable_token.h"
-#include "content/public/browser/render_document_host_user_data.h"
+#include "content/public/browser/global_routing_id.h"
+#include "content/public/browser/page_user_data.h"
 #include "content/public/browser/web_contents_observer.h"
 
 namespace content {
@@ -19,31 +20,26 @@
 }  // namespace protocol
 
 // TODO(crbug.com/1063007): Attribute issues to ongoing navigations correctly.
-// TODO(crbug.com/1090679): Replace RenderDocumentHostUserData with
-//                          PageUserData.
 class DevToolsIssueStorage
-    : public content::RenderDocumentHostUserData<DevToolsIssueStorage>,
-      public WebContentsObserver {
+    : public content::PageUserData<DevToolsIssueStorage> {
  public:
   ~DevToolsIssueStorage() override;
 
   void AddInspectorIssue(
-      int frame_tree_node_id,
+      RenderFrameHost* render_frame_host,
       std::unique_ptr<protocol::Audits::InspectorIssue> issue);
-  std::vector<const protocol::Audits::InspectorIssue*> FilterIssuesBy(
-      const base::flat_set<int>& frame_tree_node_ids) const;
+  std::vector<const protocol::Audits::InspectorIssue*> FindIssuesForAgentOf(
+      RenderFrameHost* render_frame_host) const;
 
  private:
-  explicit DevToolsIssueStorage(RenderFrameHost* rfh);
-  friend class content::RenderDocumentHostUserData<DevToolsIssueStorage>;
-  RENDER_DOCUMENT_HOST_USER_DATA_KEY_DECL();
+  explicit DevToolsIssueStorage(Page& page);
+  friend class content::PageUserData<DevToolsIssueStorage>;
+  PAGE_USER_DATA_KEY_DECL();
 
-  // WebContentsObserver overrides.
-  void FrameDeleted(int frame_tree_node_id) override;
-
-  using FrameAssociatedIssue =
-      std::pair<int, std::unique_ptr<protocol::Audits::InspectorIssue>>;
-  base::circular_deque<FrameAssociatedIssue> issues_;
+  using RenderFrameHostAssociatedIssue =
+      std::pair<GlobalRenderFrameHostId,
+                std::unique_ptr<protocol::Audits::InspectorIssue>>;
+  base::circular_deque<RenderFrameHostAssociatedIssue> issues_;
 };
 
 }  // namespace content
diff --git a/content/browser/devtools/devtools_issue_storage_browsertest.cc b/content/browser/devtools/devtools_issue_storage_browsertest.cc
index b3525bdf..877e78f 100644
--- a/content/browser/devtools/devtools_issue_storage_browsertest.cc
+++ b/content/browser/devtools/devtools_issue_storage_browsertest.cc
@@ -22,6 +22,7 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/prerender_test_util.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
 #include "net/dns/mock_host_resolver.h"
@@ -43,6 +44,13 @@
   RenderFrameHostImpl* main_frame_host() {
     return web_contents()->GetFrameTree()->GetMainFrame();
   }
+
+  void WaitForDummyIssueNotification() {
+    std::unique_ptr<base::DictionaryValue> notification =
+        WaitForNotification("Audits.issueAdded", true);
+    EXPECT_EQ(*(notification->FindDictPath("issue")->FindStringPath("code")),
+              protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue);
+  }
 };
 
 namespace {
@@ -79,7 +87,7 @@
   SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
 
   // 6) Verify we have received the SameSite issue.
-  WaitForNotification("Audits.issueAdded", true);
+  WaitForDummyIssueNotification();
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsIssueStorageBrowserTest,
@@ -98,7 +106,7 @@
   ReportDummyIssue(main_frame_host());
 
   // 5) Verify we have received the SameSite issue.
-  WaitForNotification("Audits.issueAdded", true);
+  WaitForDummyIssueNotification();
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsIssueStorageBrowserTest,
@@ -127,7 +135,7 @@
   SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
 
   // 5) Verify we have received the SameSite issue on the main target.
-  WaitForNotification("Audits.issueAdded", true);
+  WaitForDummyIssueNotification();
 }
 
 IN_PROC_BROWSER_TEST_F(DevToolsIssueStorageBrowserTest,
@@ -203,7 +211,56 @@
   SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
 
   // 6) Verify we have received the SameSite issue on the main target.
-  WaitForNotification("Audits.issueAdded", true);
+  WaitForDummyIssueNotification();
 }
 
+class DevToolsIssueStorageWithPrerenderBrowserTest
+    : public DevToolsIssueStorageBrowserTest {
+ public:
+  DevToolsIssueStorageWithPrerenderBrowserTest()
+      : prerender_test_helper_(base::BindRepeating(
+            &DevToolsIssueStorageWithPrerenderBrowserTest::GetWebContents,
+            base::Unretained(this))) {}
+
+  void SetUpOnMainThread() override {
+    DevToolsIssueStorageBrowserTest::SetUpOnMainThread();
+    prerender_test_helper().SetUpOnMainThread(embedded_test_server());
+  }
+
+  test::PrerenderTestHelper& prerender_test_helper() {
+    return prerender_test_helper_;
+  }
+
+ private:
+  WebContents* GetWebContents() { return web_contents(); }
+  test::PrerenderTestHelper prerender_test_helper_;
+};
+
+IN_PROC_BROWSER_TEST_F(DevToolsIssueStorageWithPrerenderBrowserTest,
+                       IssueWhilePrerendering) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL main_url(embedded_test_server()->GetURL("/empty.html"));
+  GURL prerender_url(embedded_test_server()->GetURL("/title1.html"));
+
+  // 1) Navigate to |main_url|.
+  EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+  // 2) Prerender |prerender_url|.
+  int host_id = prerender_test_helper().AddPrerender(prerender_url);
+  RenderFrameHostImpl* prerender_rfh = static_cast<RenderFrameHostImpl*>(
+      prerender_test_helper().GetPrerenderedMainFrameHost(host_id));
+
+  // 3) Report an empty SameSite cookie issue in prerendering page.
+  ReportDummyIssue(prerender_rfh);
+
+  // 4) Activate prerendering page.
+  prerender_test_helper().NavigatePrimaryPage(prerender_url);
+
+  // 5) Open DevTools and enable Audits domain.
+  Attach();
+  SendCommand("Audits.enable", std::make_unique<base::DictionaryValue>());
+
+  // 6) Verify we have received the SameSite issue on the main target.
+  WaitForDummyIssueNotification();
+}
 }  // namespace content
diff --git a/content/browser/devtools/protocol/audits_handler.cc b/content/browser/devtools/protocol/audits_handler.cc
index b772fe0..561e3a3 100644
--- a/content/browser/devtools/protocol/audits_handler.cc
+++ b/content/browser/devtools/protocol/audits_handler.cc
@@ -44,24 +44,10 @@
                                      protocol::AuditsHandler* handler) {
   // Check the storage first. No need to do any work in case its empty.
   DevToolsIssueStorage* issue_storage =
-      DevToolsIssueStorage::GetForCurrentDocument(rfh->GetMainFrame());
+      DevToolsIssueStorage::GetForPage(rfh->GetPage());
   if (!issue_storage)
     return;
-
-  FrameTreeNode* local_root = rfh->frame_tree_node();
-
-  std::vector<int> frame_tree_node_ids;
-  for (FrameTreeNode* node : rfh->frame_tree()->SubtreeNodes(local_root)) {
-    // For each child we find the child's local root. Should the child's local
-    // root match |local_root|, the provided |AuditsHandler| is responsible and
-    // we collect the devtools_frame_token.
-    if (local_root == GetFrameTreeNodeAncestor(node)) {
-      frame_tree_node_ids.push_back(node->frame_tree_node_id());
-    }
-  }
-
-  base::flat_set<int> frame_ids_set(frame_tree_node_ids);
-  auto issues = issue_storage->FilterIssuesBy(std::move(frame_ids_set));
+  auto issues = issue_storage->FindIssuesForAgentOf(rfh);
   for (auto* const issue : issues) {
     handler->OnIssueAdded(issue);
   }
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index bc00d04a..7a5b648 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -42,6 +42,7 @@
 #include "content/browser/download/save_package_serialization_handler.h"
 #include "content/browser/renderer_host/frame_tree.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
+#include "content/browser/renderer_host/page_impl.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -149,15 +150,31 @@
   NOTREACHED();
 }
 
+WebContents* GetWebContents(Page* page) {
+  return static_cast<RenderFrameHostImpl*>(&page->GetMainDocument())
+      ->delegate()
+      ->GetAsWebContents();
+}
+
+const std::u16string& GetTitle(Page& page) {
+  RenderFrameHostImpl* rfh =
+      static_cast<RenderFrameHostImpl*>(&page.GetMainDocument());
+  NavigationEntry* visible_entry =
+      rfh->frame_tree()->controller().GetVisibleEntry();
+  if (visible_entry)
+    return visible_entry->GetTitleForDisplay();
+  return base::EmptyString16();
+}
+
 }  // namespace
 
 const base::FilePath::CharType SavePackage::kDefaultHtmlExtension[] =
     FILE_PATH_LITERAL("html");
 
-SavePackage::SavePackage(WebContents* web_contents)
-    : WebContentsObserver(web_contents),
-      page_url_(GetUrlToBeSaved(web_contents)),
-      title_(web_contents->GetTitle()),
+SavePackage::SavePackage(Page& page)
+    : page_(&page),
+      page_url_(GetUrlToBeSaved(&page.GetMainDocument())),
+      title_(GetTitle(page)),
       start_tick_(base::TimeTicks::Now()),
       file_name_set_(&base::FilePath::CompareLessIgnoreCase),
       unique_id_(GetNextSavePackageId()) {
@@ -166,15 +183,15 @@
 }
 
 // Used for tests.
-SavePackage::SavePackage(WebContents* web_contents,
+SavePackage::SavePackage(Page& page,
                          SavePageType save_type,
                          const base::FilePath& file_full_path,
                          const base::FilePath& directory_full_path)
-    : WebContentsObserver(web_contents),
-      page_url_(GetUrlToBeSaved(web_contents)),
+    : page_(&page),
+      page_url_(GetUrlToBeSaved(&page.GetMainDocument())),
       saved_main_file_path_(file_full_path),
       saved_main_directory_path_(directory_full_path),
-      title_(web_contents->GetTitle()),
+      title_(GetTitle(page)),
       start_tick_(base::TimeTicks::Now()),
       save_type_(save_type),
       file_name_set_(&base::FilePath::CompareLessIgnoreCase),
@@ -224,15 +241,19 @@
   file_manager_ = nullptr;
 }
 
+void SavePackage::ClearPage() {
+  page_ = nullptr;
+}
+
 // static
-GURL SavePackage::GetUrlToBeSaved(WebContents* web_contents) {
+GURL SavePackage::GetUrlToBeSaved(RenderFrameHost* main_frame) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // Instead of using web_contents->GetURL here, we call GetURL() (which is the
-  // "real" url of the page) from the NavigationEntry because it reflects its
+  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(main_frame);
+  // Retrieve the url from the NavigationEntry because it reflects its
   // origin rather than the displayed one (returned by GetVirtualURL) which may
   // be different (like having "view-source:" on the front).
   NavigationEntry* visible_entry =
-      web_contents->GetController().GetVisibleEntry();
+      rfh->frame_tree()->controller().GetVisibleEntry();
   return visible_entry ? visible_entry->GetURL() : GURL::EmptyGURL();
 }
 
@@ -257,23 +278,19 @@
   DCHECK(file_manager_);
 
   download_manager_ = static_cast<DownloadManagerImpl*>(
-      web_contents()->GetBrowserContext()->GetDownloadManager());
+      page_->GetMainDocument().GetBrowserContext()->GetDownloadManager());
   DCHECK(download_manager_);
 
   download::RecordSavePackageEvent(download::SAVE_PACKAGE_STARTED);
 
-  // TODO(crbug.com/1061899): The code here should take an explicit reference
-  // to the corresponding frame instead of using the current main frame.
-  ukm_source_id_ = static_cast<WebContentsImpl*>(web_contents())
-                       ->GetMainFrame()
-                       ->GetPageUkmSourceId();
+  ukm_source_id_ = page_->GetMainDocument().GetPageUkmSourceId();
   ukm_download_id_ = download::GetUniqueDownloadId();
   download::DownloadUkmHelper::RecordDownloadStarted(
       ukm_download_id_, ukm_source_id_, download::DownloadContent::TEXT,
       download::DownloadSource::UNKNOWN,
       download::CheckDownloadConnectionSecurity(
-          web_contents()->GetLastCommittedURL(),
-          std::vector<GURL>{web_contents()->GetLastCommittedURL()}),
+          page_->GetMainDocument().GetLastCommittedURL(),
+          std::vector<GURL>{page_->GetMainDocument().GetLastCommittedURL()}),
       true /* is_same_host_download */);
 }
 
@@ -288,16 +305,17 @@
   wait_state_ = START_PROCESS;
 
   // Initialize the request context and resource dispatcher.
-  BrowserContext* browser_context = web_contents()->GetBrowserContext();
+  BrowserContext* browser_context =
+      page_->GetMainDocument().GetBrowserContext();
   if (!browser_context) {
     NOTREACHED();
     return false;
   }
 
-  RenderFrameHost* frame_host = web_contents()->GetMainFrame();
+  RenderFrameHost& frame_host = page_->GetMainDocument();
   download_manager_->CreateSavePackageDownloadItem(
       saved_main_file_path_, page_url_, GetMimeTypeForSaveType(save_type_),
-      frame_host->GetProcess()->GetID(), frame_host->GetRoutingID(),
+      frame_host.GetProcess()->GetID(), frame_host.GetRoutingID(),
       base::BindOnce(&CancelSavePackage, AsWeakPtr()),
       base::BindOnce(&SavePackage::InitWithDownloadItem, AsWeakPtr(),
                      std::move(download_created_callback)));
@@ -321,11 +339,11 @@
     GetSavableResourceLinks();
   } else if (save_type_ == SAVE_PAGE_TYPE_AS_MHTML) {
     MHTMLGenerationParams mhtml_generation_params(saved_main_file_path_);
-    web_contents()->GenerateMHTML(
+    GetWebContents(page_)->GenerateMHTML(
         mhtml_generation_params,
         base::BindOnce(&SavePackage::OnMHTMLOrWebBundleGenerated, this));
   } else if (save_type_ == SAVE_PAGE_TYPE_AS_WEB_BUNDLE) {
-    web_contents()->GenerateWebBundle(
+    GetWebContents(page_)->GenerateWebBundle(
         saved_main_file_path_,
         base::BindOnce(&SavePackage::OnWebBundleGenerated, this));
   } else {
@@ -335,7 +353,7 @@
     waiting_item_queue_.push_back(base::WrapUnique(new SaveItem(
         page_url_, Referrer(), this, SaveFileCreateInfo::SAVE_FILE_FROM_NET,
         FrameTreeNode::kFrameTreeNodeInvalidId,
-        web_contents()->GetMainFrame()->GetFrameTreeNodeId())));
+        page_->GetMainDocument().GetFrameTreeNodeId())));
     all_save_items_count_ = 1;
     download_->SetTotalBytes(1);
 
@@ -696,11 +714,10 @@
     final_names.insert(std::make_pair(it.first, it.second->full_path()));
 
   download::GetDownloadTaskRunner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&SaveFileManager::RenameAllFiles, file_manager_,
-                     final_names, dir,
-                     web_contents()->GetMainFrame()->GetProcess()->GetID(),
-                     web_contents()->GetMainFrame()->GetRoutingID(), id()));
+      FROM_HERE, base::BindOnce(&SaveFileManager::RenameAllFiles, file_manager_,
+                                final_names, dir,
+                                page_->GetMainDocument().GetProcess()->GetID(),
+                                page_->GetMainDocument().GetRoutingID(), id()));
 }
 
 // Successfully finished all items of this SavePackage.
@@ -810,7 +827,7 @@
 
 void SavePackage::SaveNextFile(bool process_all_remaining_items) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK(web_contents());
+  DCHECK(page_);
   DCHECK(!waiting_item_queue_.empty());
 
   do {
@@ -847,10 +864,10 @@
         requester_frame->GetProcess()->GetID(),
         requester_frame->render_view_host()->GetRoutingID(),
         requester_frame->routing_id(), save_item_ptr->save_source(),
-        save_item_ptr->full_path(), web_contents()->GetBrowserContext(),
-        web_contents()
-            ->GetMainFrame()
-            ->GetRenderViewHost()
+        save_item_ptr->full_path(),
+        page_->GetMainDocument().GetBrowserContext(),
+        page_->GetMainDocument()
+            .GetRenderViewHost()
             ->GetProcess()
             ->GetStoragePartition(),
         this);
@@ -942,7 +959,7 @@
   // Try to serialize all the frames gathered during GetSavableResourceLinks.
   DCHECK_EQ(0, number_of_frames_pending_response_);
   FrameTree* frame_tree =
-      static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
+      static_cast<RenderFrameHostImpl*>(&page_->GetMainDocument())
           ->frame_tree();
   for (const auto& item : frame_tree_node_id_to_save_item_) {
     int frame_tree_node_id = item.first;
@@ -1045,7 +1062,7 @@
   // Ask target frame to serialize itself.
   target->GetSerializedHtmlWithLocalLinks(
       url_to_local_path, frame_token_to_local_path,
-      web_contents()->GetBrowserContext()->IsOffTheRecord(),
+      page_->GetMainDocument().GetBrowserContext()->IsOffTheRecord(),
       std::move(serializer_handler));
 }
 
@@ -1122,6 +1139,14 @@
   return save_item;
 }
 
+void SavePackage::GetSavableResourceLinksForRenderFrameHost(
+    RenderFrameHost* rfh) {
+  if (!rfh->IsRenderFrameLive())
+    return;
+  ++number_of_frames_pending_response_;
+  static_cast<RenderFrameHostImpl*>(rfh)->GetSavableResourceLinksFromRenderer();
+}
+
 // Ask for all savable resource links from backend, include main frame and
 // sub-frame.
 void SavePackage::GetSavableResourceLinks() {
@@ -1132,19 +1157,14 @@
   wait_state_ = RESOURCES_LIST;
 
   DCHECK_EQ(0, number_of_frames_pending_response_);
-  for (RenderFrameHost* rfh : web_contents()->GetAllFrames()) {
-    if (!rfh->IsRenderFrameLive())
-      continue;
-    ++number_of_frames_pending_response_;
-    static_cast<RenderFrameHostImpl*>(rfh)
-        ->GetSavableResourceLinksFromRenderer();
-  }
+  page_->GetMainDocument().ForEachRenderFrameHost(base::BindRepeating(
+      &SavePackage::GetSavableResourceLinksForRenderFrameHost, this));
   DCHECK_LT(0, number_of_frames_pending_response_);
 
   // Enqueue the main frame separately (because this frame won't show up in any
   // of GetsSavableResourceLinks callbacks).
   FrameTreeNode* main_frame_tree_node =
-      static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
+      static_cast<RenderFrameHostImpl*>(&page_->GetMainDocument())
           ->frame_tree_node();
   EnqueueFrame(FrameTreeNode::kFrameTreeNodeInvalidId,  // No container.
                main_frame_tree_node->frame_tree_node_id(),
@@ -1295,16 +1315,16 @@
 
 void SavePackage::GetSaveInfo() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // Can't use |web_contents_| in the download sequence, so get the data that we
+  // Can't use |page_| in the download sequence, so get the data that we
   // need before calling to it.
   base::FilePath website_save_dir;
   base::FilePath download_save_dir;
   auto* delegate = download_manager_->GetDelegate();
   if (delegate) {
-    delegate->GetSaveDir(web_contents()->GetBrowserContext(), &website_save_dir,
-                         &download_save_dir);
+    delegate->GetSaveDir(page_->GetMainDocument().GetBrowserContext(),
+                         &website_save_dir, &download_save_dir);
   }
-  std::string mime_type = web_contents()->GetContentsMimeType();
+  std::string mime_type = static_cast<PageImpl*>(page_)->contents_mime_type();
   bool can_save_as_complete = CanSaveAsComplete(mime_type);
   base::PostTaskAndReplyWithResult(
       download::GetDownloadTaskRunner().get(), FROM_HERE,
@@ -1367,7 +1387,7 @@
   // The WebContents which owns this SavePackage may have disappeared during
   // the UI->download sequence->UI thread hop of
   // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo.
-  if (!web_contents() || !download_manager_->GetDelegate())
+  if (!page_ || !download_manager_->GetDelegate())
     return;
 
   base::FilePath::StringType default_extension;
@@ -1375,7 +1395,8 @@
     default_extension = kDefaultHtmlExtension;
 
   download_manager_->GetDelegate()->ChooseSavePath(
-      web_contents(), suggested_path, default_extension, can_save_as_complete,
+      GetWebContents(page_), suggested_path, default_extension,
+      can_save_as_complete,
       base::BindOnce(&SavePackage::OnPathPicked, AsWeakPtr()));
 }
 
@@ -1393,8 +1414,8 @@
   saved_main_file_path_ = final_name;
   // TODO(asanka): This call may block on IO and shouldn't be made
   // from the UI thread.  See http://crbug.com/61827.
-  net::GenerateSafeFileName(web_contents()->GetContentsMimeType(), false,
-                            &saved_main_file_path_);
+  std::string mime_type = static_cast<PageImpl*>(page_)->contents_mime_type();
+  net::GenerateSafeFileName(mime_type, false, &saved_main_file_path_);
 
   saved_main_directory_path_ = saved_main_file_path_.DirName();
   save_type_ = type;
diff --git a/content/browser/download/save_package.h b/content/browser/download/save_package.h
index 77a092f..434d982c 100644
--- a/content/browser/download/save_package.h
+++ b/content/browser/download/save_package.h
@@ -27,7 +27,6 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/download_manager_delegate.h"
 #include "content/public/browser/save_page_type.h"
-#include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/referrer.h"
 #include "net/base/net_errors.h"
 #include "services/data_decoder/public/mojom/web_bundler.mojom.h"
@@ -43,12 +42,12 @@
 
 namespace content {
 class DownloadManagerImpl;
+class Page;
 class FrameTreeNode;
 class RenderFrameHostImpl;
 class SaveFileManager;
 class SaveItem;
 class SavePackage;
-class WebContents;
 
 // SavePackage manages the process of saving a page as only-HTML, complete-HTML
 // or MHTML and provides status information about the job.
@@ -66,7 +65,6 @@
 // saving job, and exist for the duration of one contents's life time.
 class CONTENT_EXPORT SavePackage
     : public base::RefCountedThreadSafe<SavePackage>,
-      public WebContentsObserver,
       public base::SupportsWeakPtr<SavePackage> {
  public:
   enum WaitState {
@@ -91,7 +89,7 @@
   // Constructor for user initiated page saving. This constructor results in a
   // SavePackage that will generate and sanitize a suggested name for the user
   // in the "Save As" dialog box.
-  explicit SavePackage(WebContents* web_contents);
+  explicit SavePackage(Page& page);
 
   // Initialize the SavePackage. Returns true if it initializes properly.  Need
   // to make sure that this method must be called in the UI thread because using
@@ -163,12 +161,12 @@
 
   // Used only for testing. Bypasses the file and directory name generation /
   // sanitization by providing well known paths better suited for tests.
-  SavePackage(WebContents* web_contents,
+  SavePackage(Page& page,
               SavePageType save_type,
               const base::FilePath& file_full_path,
               const base::FilePath& directory_full_path);
 
-  ~SavePackage() override;
+  ~SavePackage();
 
   void InitWithDownloadItem(
       SavePackageDownloadCreatedCallback download_created_callback,
@@ -188,6 +186,9 @@
   void Stop(bool cancel_download_item);
   void CheckFinish();
 
+  // Clears the associated page.
+  void ClearPage();
+
   // Initiate a saving job of a specific URL. We send the request to
   // SaveFileManager, which will dispatch it to different approach according to
   // the save source. |process_all_remaining_items| indicates whether we need to
@@ -245,6 +246,7 @@
   // with the help of CreatePendingSaveItem, EnqueueSavableResource,
   // EnqueueFrame.
   void GetSavableResourceLinks();
+  void GetSavableResourceLinksForRenderFrameHost(RenderFrameHost* rfh);
 
   // Helper for finding or creating a SaveItem with the given parameters.
   SaveItem* CreatePendingSaveItem(
@@ -309,8 +311,8 @@
   // Remove SaveItem from in progress map and put it to saved map.
   void PutInProgressItemToSavedMap(SaveItem* save_item);
 
-  // Retrieves the URL to be saved from the WebContents.
-  static GURL GetUrlToBeSaved(WebContents* web_contents);
+  // Retrieves the URL to be saved from the main frame.
+  static GURL GetUrlToBeSaved(RenderFrameHost* main_frame);
 
   static base::FilePath CreateDirectoryOnFileThread(
       const std::u16string& title,
@@ -344,6 +346,10 @@
   // files is presented as the total and received bytes.
   int64_t CurrentSpeed() const;
 
+  // The current page, may be null if the primary page has been navigated away
+  // or destroyed.
+  Page* page_;
+
   // A queue for items we are about to start saving.
   base::circular_deque<std::unique_ptr<SaveItem>> waiting_item_queue_;
 
diff --git a/content/browser/download/save_package_browsertest.cc b/content/browser/download/save_package_browsertest.cc
index 84294ba..499955d 100644
--- a/content/browser/download/save_package_browsertest.cc
+++ b/content/browser/download/save_package_browsertest.cc
@@ -186,7 +186,7 @@
       download_manager->AddObserver(&download_item_killer);
 
       scoped_refptr<SavePackage> save_package(
-          new SavePackage(shell()->web_contents()));
+          new SavePackage(shell()->web_contents()->GetPrimaryPage()));
       save_package->GetSaveInfo();
       run_loop.Run();
       download_manager->RemoveObserver(&download_item_killer);
@@ -219,9 +219,9 @@
   EXPECT_TRUE(NavigateToURL(shell(), url));
   base::FilePath full_file_name, dir;
   GetDestinationPaths("a", &full_file_name, &dir);
-  scoped_refptr<SavePackage> save_package(new SavePackage(
-      shell()->web_contents(), SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name,
-      dir));
+  scoped_refptr<SavePackage> save_package(
+      new SavePackage(shell()->web_contents()->GetPrimaryPage(),
+                      SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name, dir));
 }
 
 // Create a SavePackage, call Cancel, then delete it.
@@ -232,9 +232,9 @@
   EXPECT_TRUE(NavigateToURL(shell(), url));
   base::FilePath full_file_name, dir;
   GetDestinationPaths("a", &full_file_name, &dir);
-  scoped_refptr<SavePackage> save_package(new SavePackage(
-      shell()->web_contents(), SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name,
-      dir));
+  scoped_refptr<SavePackage> save_package(
+      new SavePackage(shell()->web_contents()->GetPrimaryPage(),
+                      SAVE_PAGE_TYPE_AS_ONLY_HTML, full_file_name, dir));
   save_package->Cancel(true);
 }
 
@@ -281,7 +281,7 @@
     DownloadCompleteObserver observer(run_loop.QuitClosure());
     download_manager->AddObserver(&observer);
     scoped_refptr<SavePackage> save_package(
-        new SavePackage(shell()->web_contents()));
+        new SavePackage(shell()->web_contents()->GetPrimaryPage()));
     save_package->GetSaveInfo();
     run_loop.Run();
     download_manager->RemoveObserver(&observer);
diff --git a/content/browser/download/save_package_unittest.cc b/content/browser/download/save_package_unittest.cc
index b91539f3..9c347d0 100644
--- a/content/browser/download/save_package_unittest.cc
+++ b/content/browser/download/save_package_unittest.cc
@@ -81,7 +81,7 @@
   }
 
   GURL GetUrlToBeSaved() {
-    return SavePackage::GetUrlToBeSaved(save_package_success_->web_contents());
+    return SavePackage::GetUrlToBeSaved(contents()->GetMainFrame());
   }
 
  protected:
@@ -93,13 +93,13 @@
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
     save_package_success_ = new SavePackage(
-        contents(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
+        contents()->GetPrimaryPage(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
         temp_dir_.GetPath().AppendASCII("testfile" HTML_EXTENSION),
         temp_dir_.GetPath().AppendASCII("testfile_files"));
 
     base::FilePath::StringType long_file_name = GetLongFileName();
     save_package_fail_ = new SavePackage(
-        contents(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
+        contents()->GetPrimaryPage(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
         temp_dir_.GetPath().Append(long_file_name + FPL_HTML_EXTENSION),
         temp_dir_.GetPath().Append(long_file_name + FPL("_files")));
   }
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index 5b83ced..b6d6aa68 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -891,10 +891,10 @@
   void StartStandardAuction() {
     std::vector<auction_worklet::mojom::BiddingInterestGroupPtr> bidders;
     bidders.push_back(MakeInterestGroup(kBidder1, kBidder1Name, kBidder1Url,
-                                        kTrustedSignalsUrl, {"k1", "k2"},
+                                        kBidder1TrustedSignalsUrl, {"k1", "k2"},
                                         GURL("https://ad1.com")));
     bidders.push_back(MakeInterestGroup(kBidder2, kBidder2Name, kBidder2Url,
-                                        kTrustedSignalsUrl, {"l1", "l2"},
+                                        kBidder2TrustedSignalsUrl, {"l1", "l2"},
                                         GURL("https://ad2.com")));
 
     StartAuction(kSellerUrl, std::move(bidders),
@@ -960,14 +960,16 @@
   const url::Origin frame_origin_ =
       url::Origin::Create(GURL("https://frame.origin.test"));
   const GURL kSellerUrl{"https://adstuff.publisher1.com/auction.js"};
+
   const GURL kBidder1Url{"https://adplatform.com/offers.js"};
   const url::Origin kBidder1 = url::Origin::Create(kBidder1Url);
   const std::string kBidder1Name{"Ad Platform"};
+  const GURL kBidder1TrustedSignalsUrl{"https://adplatform.com/signals1"};
+
   const GURL kBidder2Url{"https://anotheradthing.com/bids.js"};
   const url::Origin kBidder2 = url::Origin::Create(kBidder2Url);
   const std::string kBidder2Name{"Another Ad Thing"};
-
-  const GURL kTrustedSignalsUrl{"https://trustedsignaller.org/signals"};
+  const GURL kBidder2TrustedSignalsUrl{"https://anotheradthing.com/signals2"};
 
   base::test::TaskEnvironment task_environment_;
 
@@ -1034,14 +1036,14 @@
                     true /* has_signals */, "k1", "a"));
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
 
   std::vector<auction_worklet::mojom::BiddingInterestGroupPtr> bidders;
   bidders.push_back(MakeInterestGroup(kBidder1, kBidder1Name, kBidder1Url,
-                                      kTrustedSignalsUrl, {"k1", "k2"},
+                                      kBidder1TrustedSignalsUrl, {"k1", "k2"},
                                       GURL("https://ad1.com")));
 
   RunAuctionAndWait(kSellerUrl, std::move(bidders),
@@ -1077,14 +1079,14 @@
                     true /* has_signals */, "l2", "b"));
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
@@ -1111,14 +1113,14 @@
   url_loader_factory_.AddResponse(kBidder2Url.spec(), "", net::HTTP_NOT_FOUND);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad1.com/"), res.ad_url);
@@ -1152,14 +1154,14 @@
                                          MakeAuctionScript());
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad1.com/"), res.ad_url);
@@ -1185,14 +1187,14 @@
   url_loader_factory_.AddResponse(kBidder2Url.spec(), "", net::HTTP_NOT_FOUND);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2":"b", "extra":"c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2":"b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra":"c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_FALSE(res.ad_url);
@@ -1221,14 +1223,14 @@
                                          MakeAuctionScript());
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2":"b", "extra":"c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2":"b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra":"c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_FALSE(res.ad_url);
@@ -1263,14 +1265,14 @@
   // No seller scoring function in a bid script.
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          bid_script1);
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2":"b", "extra":"c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2":"b", "extra":"c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra":"c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_FALSE(res.ad_url);
@@ -1301,14 +1303,14 @@
                     true /* has_signals */, "l2", "b"));
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScriptReject2());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad1.com/"), res.ad_url);
@@ -1403,11 +1405,11 @@
       MakeBidScript("2", "https://ad2.com/", kBidder2, kBidder2Name,
                     false /* has_signals */, "l2", "b"));
   url_loader_factory_.AddResponse(
-      kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2", "",
-      net::HTTP_NOT_FOUND);
+      kBidder1TrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2",
+      "", net::HTTP_NOT_FOUND);
   url_loader_factory_.AddResponse(
-      kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2", "",
-      net::HTTP_NOT_FOUND);
+      kBidder2TrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2",
+      "", net::HTTP_NOT_FOUND);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
 
@@ -1424,12 +1426,12 @@
             res.bidder2_prev_wins[3]->ad_json);
   EXPECT_THAT(res.errors, testing::UnorderedElementsAre(
                               "Failed to load "
-                              "https://trustedsignaller.org/"
-                              "signals?hostname=publisher1.com&keys=k1,k2 "
+                              "https://adplatform.com/"
+                              "signals1?hostname=publisher1.com&keys=k1,k2 "
                               "HTTP status = 404 Not Found.",
                               "Failed to load "
-                              "https://trustedsignaller.org/"
-                              "signals?hostname=publisher1.com&keys=l1,l2 "
+                              "https://anotheradthing.com/"
+                              "signals2?hostname=publisher1.com&keys=l1,l2 "
                               "HTTP status = 404 Not Found."));
   CheckHistograms(AuctionRunner::AuctionResult::kSuccess,
                   2 /* expected_interest_groups */, 2 /* expected_owners */);
@@ -1447,14 +1449,14 @@
                     true /* has_signals */, "l2", "b"));
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScriptNoReportUrl());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
@@ -1486,14 +1488,14 @@
           kReportWinNoUrl);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
@@ -1524,14 +1526,14 @@
           kReportWinNoUrl);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScriptNoReportUrl());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
@@ -1564,14 +1566,14 @@
           kReportWinExpectNullAuctionSignals);
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          kCheckingAuctionScript);
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   const Result& res = RunStandardAuction();
   EXPECT_EQ(GURL("https://ad2.com/"), res.ad_url);
@@ -1603,14 +1605,14 @@
                     true /* has_signals */, "l2", "b"));
   auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
                                          MakeAuctionScript());
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=k1,k2"),
-      R"({"k1":"a", "k2": "b", "extra": "c"})");
-  auction_worklet::AddJsonResponse(
-      &url_loader_factory_,
-      GURL(kTrustedSignalsUrl.spec() + "?hostname=publisher1.com&keys=l1,l2"),
-      R"({"l1":"a", "l2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder1TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=k1,k2"),
+                                   R"({"k1":"a", "k2": "b", "extra": "c"})");
+  auction_worklet::AddJsonResponse(&url_loader_factory_,
+                                   GURL(kBidder2TrustedSignalsUrl.spec() +
+                                        "?hostname=publisher1.com&keys=l1,l2"),
+                                   R"({"l1":"a", "l2": "b", "extra": "c"})");
 
   // Create AuctionProcessManager in advance of starting the auction so can
   // create seller worklets before the auction starts.
diff --git a/content/browser/interest_group/interest_group_storage.cc b/content/browser/interest_group/interest_group_storage.cc
index 515061b..24d6352e 100644
--- a/content/browser/interest_group/interest_group_storage.cc
+++ b/content/browser/interest_group/interest_group_storage.cc
@@ -68,23 +68,16 @@
 std::string Serialize(const base::Value& value) {
   std::string json_output;
   JSONStringValueSerializer serializer(&json_output);
-  if (!serializer.Serialize(value))
-    LOG(ERROR) << "Could not serialize value:   " << value.DebugString();
-
+  serializer.Serialize(value);
   return json_output;
 }
-std::unique_ptr<base::Value> DeserializeValue(std::string serialized_value) {
+std::unique_ptr<base::Value> DeserializeValue(
+    const std::string& serialized_value) {
   if (serialized_value.empty())
     return {};
-  JSONStringValueDeserializer deserializer{base::StringPiece(serialized_value)};
-  std::string error_message;
-  std::unique_ptr<base::Value> result =
-      deserializer.Deserialize(nullptr, &error_message);
-  if (!result) {
-    LOG(ERROR) << "Could not deserialize value `" << serialized_value
-               << "`:   " << error_message;
-  }
-  return result;
+  JSONStringValueDeserializer deserializer(serialized_value);
+  return deserializer.Deserialize(/*error_code=*/nullptr,
+                                  /*error_message=*/nullptr);
 }
 
 std::string Serialize(const url::Origin& origin) {
@@ -96,7 +89,7 @@
 
 std::string Serialize(const absl::optional<GURL>& url) {
   if (!url)
-    return "";
+    return std::string();
   return url->spec();
 }
 absl::optional<GURL> DeserializeURL(const std::string& serialized_url) {
@@ -113,17 +106,12 @@
     dict.SetStringKey("metadata", ad.metadata.value());
   return dict;
 }
-InterestGroupAdPtr FromInterestGroupAdPtrValue(const base::Value* value) {
+InterestGroupAdPtr FromInterestGroupAdPtrValue(const base::Value& value) {
   InterestGroupAdPtr result = blink::mojom::InterestGroupAd::New();
-  if (!value) {
-    LOG(ERROR) << "converting InterestGroupAd from value";
-    return result;
-  }
-  const std::string* maybe_url = value->FindStringKey("url");
-  if (!maybe_url)
-    LOG(ERROR) << "url field not found in serialized InterestGroupAdPtrValue";
-  result->render_url = GURL(*maybe_url);
-  const std::string* maybe_metadata = value->FindStringKey("metadata");
+  const std::string* maybe_url = value.FindStringKey("url");
+  if (maybe_url)
+    result->render_url = GURL(*maybe_url);
+  const std::string* maybe_metadata = value.FindStringKey("metadata");
   if (maybe_metadata)
     result->metadata = *maybe_metadata;
   return result;
@@ -132,7 +120,7 @@
 std::string Serialize(
     const absl::optional<std::vector<InterestGroupAdPtr>>& ads) {
   if (!ads)
-    return "";
+    return std::string();
   base::Value list(base::Value::Type::LIST);
   for (const auto& ad : ads.value()) {
     list.Append(ToValue(*ad));
@@ -140,29 +128,29 @@
   return Serialize(list);
 }
 absl::optional<std::vector<InterestGroupAdPtr>>
-DeserializeInterestGroupAdPtrVector(std::string serialized_ads) {
+DeserializeInterestGroupAdPtrVector(const std::string& serialized_ads) {
   std::vector<InterestGroupAdPtr> result;
   std::unique_ptr<base::Value> ads_value = DeserializeValue(serialized_ads);
-  if (!ads_value) {
+  if (!ads_value || !ads_value->is_list())
     return absl::nullopt;
+  for (const auto& ad_value : ads_value->GetList()) {
+    result.push_back(FromInterestGroupAdPtrValue(ad_value));
   }
-  for (const auto& ad_value : ads_value->GetList())
-    result.push_back(FromInterestGroupAdPtrValue(&ad_value));
   return result;
 }
 
-std::string Serialize(const absl::optional<std::vector<std::string>> strings) {
+std::string Serialize(const absl::optional<std::vector<std::string>>& strings) {
   if (!strings)
-    return "";
+    return std::string();
   base::Value list(base::Value::Type::LIST);
   for (const auto& s : strings.value())
     list.Append(s);
   return Serialize(list);
 }
 absl::optional<std::vector<std::string>> DeserializeStringVector(
-    std::string serialized_vector) {
+    const std::string& serialized_vector) {
   std::unique_ptr<base::Value> list = DeserializeValue(serialized_vector);
-  if (!list)
+  if (!list || !list->is_list())
     return absl::nullopt;
   std::vector<std::string> result;
   for (const auto& value : list->GetList())
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 447e2386..4e53d8d1 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -755,8 +755,14 @@
   // Early Hints should not come after actual response.
   DCHECK(on_receive_response_time_.is_null());
   DCHECK(!received_response_);
+  DCHECK_NE(early_hints->ip_address_space,
+            network::mojom::IPAddressSpace::kUnknown);
 
   if (!early_hints_manager_) {
+    // TODO(crbug.com/1225556): Create URLLoaderFactory via
+    // URLLoaderFactoryParams of which values are calculated from `early_hints`
+    // and `this`. Then add browsertests which check whether the resulting
+    // factory cannot fetch subresources from the private network.
     early_hints_manager_ = std::make_unique<NavigationEarlyHintsManager>(
         *browser_context_,
         storage_partition_->GetURLLoaderFactoryForBrowserProcess(),
diff --git a/content/browser/payments/payment_app_provider_impl.cc b/content/browser/payments/payment_app_provider_impl.cc
index f7953de..ce55995 100644
--- a/content/browser/payments/payment_app_provider_impl.cc
+++ b/content/browser/payments/payment_app_provider_impl.cc
@@ -432,15 +432,11 @@
     WebContents* payment_request_web_contents)
     : payment_request_web_contents_(payment_request_web_contents),
       event_dispatcher_(
-          std::make_unique<ServiceWorkerCoreThreadEventDispatcher>(
-              payment_request_web_contents_)) {
+          std::make_unique<ServiceWorkerCoreThreadEventDispatcher>()) {
   event_dispatcher_->set_payment_app_provider(weak_ptr_factory_.GetWeakPtr());
 }
 
-PaymentAppProviderImpl::~PaymentAppProviderImpl() {
-  BrowserThread::DeleteSoon(ServiceWorkerContext::GetCoreThreadId(), FROM_HERE,
-                            std::move(event_dispatcher_));
-}
+PaymentAppProviderImpl::~PaymentAppProviderImpl() = default;
 
 PaymentAppProviderImpl::PaymentHandlerWindowObserver::
     PaymentHandlerWindowObserver(WebContents* payment_handler_web_contents)
diff --git a/content/browser/payments/respond_with_callback.cc b/content/browser/payments/respond_with_callback.cc
index eff548d..b46d0f0 100644
--- a/content/browser/payments/respond_with_callback.cc
+++ b/content/browser/payments/respond_with_callback.cc
@@ -33,12 +33,10 @@
 }
 
 RespondWithCallback::RespondWithCallback(
-    WebContents* web_contents,
     ServiceWorkerMetrics::EventType event_type,
     scoped_refptr<ServiceWorkerVersion> service_worker_version,
     base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher)
-    : WebContentsObserver(web_contents),
-      service_worker_version_(service_worker_version),
+    : service_worker_version_(service_worker_version),
       event_dispatcher_(event_dispatcher) {
   request_id_ = service_worker_version->StartRequest(
       event_type, base::BindOnce(&RespondWithCallback::OnServiceWorkerError,
@@ -61,9 +59,6 @@
 
 void RespondWithCallback::ClearRespondWithCallbackAndCloseWindow() {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
-  if (!web_contents())
-    return;
-
   if (!event_dispatcher_)
     return;
 
@@ -76,12 +71,10 @@
 }
 
 CanMakePaymentRespondWithCallback::CanMakePaymentRespondWithCallback(
-    WebContents* web_contents,
     scoped_refptr<ServiceWorkerVersion> service_worker_version,
     base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
     PaymentAppProvider::CanMakePaymentCallback callback)
-    : RespondWithCallback(web_contents,
-                          ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
+    : RespondWithCallback(ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
                           service_worker_version,
                           event_dispatcher),
       callback_(std::move(callback)) {}
@@ -125,12 +118,10 @@
 }
 
 InvokeRespondWithCallback::InvokeRespondWithCallback(
-    WebContents* web_contents,
     scoped_refptr<ServiceWorkerVersion> service_worker_version,
     base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
     PaymentAppProvider::InvokePaymentAppCallback callback)
-    : RespondWithCallback(web_contents,
-                          ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
+    : RespondWithCallback(ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
                           service_worker_version,
                           event_dispatcher),
       callback_(std::move(callback)) {}
@@ -187,12 +178,10 @@
 }
 
 AbortRespondWithCallback::AbortRespondWithCallback(
-    WebContents* web_contents,
     scoped_refptr<ServiceWorkerVersion> service_worker_version,
     base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
     PaymentAppProvider::AbortCallback callback)
-    : RespondWithCallback(web_contents,
-                          ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
+    : RespondWithCallback(ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
                           service_worker_version,
                           event_dispatcher),
       callback_(std::move(callback)) {}
diff --git a/content/browser/payments/respond_with_callback.h b/content/browser/payments/respond_with_callback.h
index 826c7e9..95b8abb 100644
--- a/content/browser/payments/respond_with_callback.h
+++ b/content/browser/payments/respond_with_callback.h
@@ -25,8 +25,7 @@
 // Abstract base class for event callbacks that are invoked when the payment
 // handler resolves the promise passed in to TheEvent.respondWith() method.
 class RespondWithCallback
-    : public payments::mojom::PaymentHandlerResponseCallback,
-      public WebContentsObserver {
+    : public payments::mojom::PaymentHandlerResponseCallback {
  public:
   // Disallow copy and assign.
   RespondWithCallback(const RespondWithCallback& other) = delete;
@@ -37,7 +36,6 @@
 
  protected:
   RespondWithCallback(
-      WebContents* web_contents,
       ServiceWorkerMetrics::EventType event_type,
       scoped_refptr<ServiceWorkerVersion> service_worker_version,
       base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher);
@@ -78,7 +76,6 @@
 class CanMakePaymentRespondWithCallback : public RespondWithCallback {
  public:
   CanMakePaymentRespondWithCallback(
-      WebContents* web_contents,
       scoped_refptr<ServiceWorkerVersion> service_worker_version,
       base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
       PaymentAppProvider::CanMakePaymentCallback callback);
@@ -108,7 +105,6 @@
 class InvokeRespondWithCallback : public RespondWithCallback {
  public:
   InvokeRespondWithCallback(
-      WebContents* web_contents,
       scoped_refptr<ServiceWorkerVersion> service_worker_version,
       base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
       PaymentAppProvider::InvokePaymentAppCallback callback);
@@ -143,7 +139,6 @@
 class AbortRespondWithCallback : public RespondWithCallback {
  public:
   AbortRespondWithCallback(
-      WebContents* web_contents,
       scoped_refptr<ServiceWorkerVersion> service_worker_version,
       base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
       PaymentAppProvider::AbortCallback callback);
diff --git a/content/browser/payments/service_worker_core_thread_event_dispatcher.cc b/content/browser/payments/service_worker_core_thread_event_dispatcher.cc
index 434760be..953ecdc 100644
--- a/content/browser/payments/service_worker_core_thread_event_dispatcher.cc
+++ b/content/browser/payments/service_worker_core_thread_event_dispatcher.cc
@@ -11,7 +11,6 @@
 #include "components/payments/core/payments_validators.h"
 #include "content/browser/payments/payment_app_provider_impl.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 
 namespace content {
@@ -129,10 +128,8 @@
 
 }  // namespace
 
-ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerCoreThreadEventDispatcher(
-    WebContents* web_contents)
-    : WebContentsObserver(web_contents) {}
-
+ServiceWorkerCoreThreadEventDispatcher::
+    ServiceWorkerCoreThreadEventDispatcher() = default;
 ServiceWorkerCoreThreadEventDispatcher::
     ~ServiceWorkerCoreThreadEventDispatcher() {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -143,9 +140,6 @@
     scoped_refptr<ServiceWorkerVersion> active_version,
     blink::ServiceWorkerStatusCode service_worker_status) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
-  if (!web_contents())
-    return;
-
   if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
     GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback), false));
@@ -160,8 +154,7 @@
   // This object self-deletes after either success or error callback is
   // invoked.
   RespondWithCallback* respond_with_callback = new AbortRespondWithCallback(
-      web_contents(), active_version, weak_ptr_factory_.GetWeakPtr(),
-      std::move(callback));
+      active_version, weak_ptr_factory_.GetWeakPtr(), std::move(callback));
 
   active_version->endpoint()->DispatchAbortPaymentEvent(
       respond_with_callback->BindNewPipeAndPassRemote(),
@@ -196,9 +189,6 @@
     scoped_refptr<ServiceWorkerVersion> active_version,
     blink::ServiceWorkerStatusCode service_worker_status) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
-  if (!web_contents())
-    return;
-
   if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
     GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
@@ -217,9 +207,8 @@
   // This object self-deletes after either success or error callback is
   // invoked.
   RespondWithCallback* respond_with_callback =
-      new CanMakePaymentRespondWithCallback(web_contents(), active_version,
-                                            weak_ptr_factory_.GetWeakPtr(),
-                                            std::move(callback));
+      new CanMakePaymentRespondWithCallback(
+          active_version, weak_ptr_factory_.GetWeakPtr(), std::move(callback));
 
   active_version->endpoint()->DispatchCanMakePaymentEvent(
       std::move(event_data), respond_with_callback->BindNewPipeAndPassRemote(),
@@ -255,9 +244,6 @@
     scoped_refptr<ServiceWorkerVersion> active_version,
     blink::ServiceWorkerStatusCode service_worker_status) {
   DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
-  if (!web_contents())
-    return;
-
   if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
     GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
@@ -274,8 +260,7 @@
       ServiceWorkerMetrics::EventType::PAYMENT_REQUEST, base::DoNothing());
 
   invoke_respond_with_callback_ = std::make_unique<InvokeRespondWithCallback>(
-      web_contents(), active_version, weak_ptr_factory_.GetWeakPtr(),
-      std::move(callback));
+      active_version, weak_ptr_factory_.GetWeakPtr(), std::move(callback));
 
   active_version->endpoint()->DispatchPaymentRequestEvent(
       std::move(event_data),
diff --git a/content/browser/payments/service_worker_core_thread_event_dispatcher.h b/content/browser/payments/service_worker_core_thread_event_dispatcher.h
index 9564960..ec3acf8 100644
--- a/content/browser/payments/service_worker_core_thread_event_dispatcher.h
+++ b/content/browser/payments/service_worker_core_thread_event_dispatcher.h
@@ -16,16 +16,14 @@
 
 namespace content {
 
-class WebContents;
 class PaymentAppProviderImpl;
 
 // All of the methods and the destructor should be running on the
 // service worker core thread.
-class ServiceWorkerCoreThreadEventDispatcher : public WebContentsObserver {
+class ServiceWorkerCoreThreadEventDispatcher {
  public:
-  explicit ServiceWorkerCoreThreadEventDispatcher(WebContents* web_contents);
-
-  ~ServiceWorkerCoreThreadEventDispatcher() override;
+  ServiceWorkerCoreThreadEventDispatcher();
+  ~ServiceWorkerCoreThreadEventDispatcher();
 
   using ServiceWorkerStartCallback =
       base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>,
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc
index a6a954e..21303a87 100644
--- a/content/browser/prerender/prerender_browsertest.cc
+++ b/content/browser/prerender/prerender_browsertest.cc
@@ -1499,6 +1499,27 @@
                                             rfh_sub_1, rfh_sub_2, rfh_sub_1_1));
 }
 
+// Tests that a prerendering page cannot change the visible URL of the
+// corresponding WebContentsImpl instance before activation.
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, TabVisibleURL) {
+  const GURL kInitialUrl = GetUrl("/empty.html");
+  const GURL kPrerenderingUrl = GetUrl("/title1.html");
+  ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
+
+  ASSERT_EQ(shell()->web_contents()->GetVisibleURL(), kInitialUrl);
+  const int host_id = AddPrerender(kPrerenderingUrl);
+  ASSERT_NE(host_id, RenderFrameHost::kNoFrameTreeNodeId);
+
+  // The visible URL should not be modified by the prerendering page.
+  EXPECT_EQ(shell()->web_contents()->GetVisibleURL(), kInitialUrl);
+
+  // Activate the prerendered page.
+  NavigatePrimaryPage(kPrerenderingUrl);
+
+  // The visible URL should be updated after activation.
+  EXPECT_EQ(shell()->web_contents()->GetVisibleURL(), kPrerenderingUrl);
+}
+
 class MojoCapabilityControlTestContentBrowserClient
     : public TestContentBrowserClient,
       mojom::TestInterfaceForDefer,
@@ -2496,6 +2517,19 @@
                 ->CalculatePageLifecycleState()
                 ->visibility,
             PageVisibilityState::kHidden);
+  EXPECT_EQ(prerendered_render_frame_host->GetVisibilityState(),
+            PageVisibilityState::kHidden);
+
+  // Activate prerendering page.
+  NavigatePrimaryPage(kPrerenderingUrl);
+
+  // The visibility state should be "visible" after activation.
+  EXPECT_EQ(rvh->GetPageLifecycleStateManager()
+                ->CalculatePageLifecycleState()
+                ->visibility,
+            PageVisibilityState::kVisible);
+  EXPECT_EQ(prerendered_render_frame_host->GetVisibilityState(),
+            PageVisibilityState::kVisible);
 }
 
 // Tests that prerendering doesn't affect WebContents::GetTitle().
diff --git a/content/browser/prerender/prerender_host.h b/content/browser/prerender/prerender_host.h
index ac98402..efc7cfb 100644
--- a/content/browser/prerender/prerender_host.h
+++ b/content/browser/prerender/prerender_host.h
@@ -71,7 +71,8 @@
     kNavigationBadHttpStatus = 18,
     kClientCertRequested = 19,
     kNavigationRequestNetworkError = 20,
-    kMaxValue = kNavigationRequestNetworkError,
+    kMaxNumOfRunningPrerendersExceeded = 21,
+    kMaxValue = kMaxNumOfRunningPrerendersExceeded
   };
 
   PrerenderHost(blink::mojom::PrerenderAttributesPtr attributes,
diff --git a/content/browser/prerender/prerender_host_registry.cc b/content/browser/prerender/prerender_host_registry.cc
index bdaf5b7..434a2f1 100644
--- a/content/browser/prerender/prerender_host_registry.cc
+++ b/content/browser/prerender/prerender_host_registry.cc
@@ -74,6 +74,16 @@
       return iter.first;
   }
 
+  // TODO(crbug.com/1197133): Cancel the started prerender and start a new
+  // one if the score of the new candidate is higher than the started one's.
+  if (prerender_host_by_frame_tree_node_id_.size() ==
+      kMaxNumOfRunningPrerenders) {
+    base::UmaHistogramEnumeration(
+        "Prerender.Experimental.PrerenderHostFinalStatus",
+        PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded);
+    return RenderFrameHost::kNoFrameTreeNodeId;
+  }
+
   auto prerender_host = std::make_unique<PrerenderHost>(
       std::move(attributes), initiator_render_frame_host);
   const int frame_tree_node_id = prerender_host->frame_tree_node_id();
diff --git a/content/browser/prerender/prerender_host_registry.h b/content/browser/prerender/prerender_host_registry.h
index b8da2dc..72e8606 100644
--- a/content/browser/prerender/prerender_host_registry.h
+++ b/content/browser/prerender/prerender_host_registry.h
@@ -24,8 +24,8 @@
 class RenderFrameHostImpl;
 
 // PrerenderHostRegistry creates and retains a prerender host, and reserves it
-// for NavigationRequest to activate the prerendered page. This is created and
-// owned by WebContentsImpl.
+// for NavigationRequest to activate the prerendered page. This is created per
+// WebContentsImpl and owned by it.
 //
 // The APIs of this class are categorized into two: APIs for triggers and APIs
 // for activators.
@@ -135,6 +135,10 @@
 
   void NotifyTrigger(const GURL& url);
 
+  // Currently the number of speculationrules-triggered prerenders is limited to
+  // one per WebContentsImpl.
+  const size_t kMaxNumOfRunningPrerenders = 1;
+
   // Hosts that are not reserved for activation yet.
   // TODO(https://crbug.com/1132746): Expire prerendered contents if they are
   // not used for a while.
diff --git a/content/browser/prerender/prerender_host_registry_unittest.cc b/content/browser/prerender/prerender_host_registry_unittest.cc
index aac122c..d8276e88 100644
--- a/content/browser/prerender/prerender_host_registry_unittest.cc
+++ b/content/browser/prerender/prerender_host_registry_unittest.cc
@@ -9,6 +9,7 @@
 #include "content/browser/prerender/prerender_host.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
 #include "content/browser/site_instance_impl.h"
+#include "content/browser/speculation_rules/speculation_host_impl.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/test/test_browser_context.h"
@@ -18,14 +19,39 @@
 #include "net/base/load_flags.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/mojom/loader/mixed_content.mojom.h"
+#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom.h"
 
 namespace content {
 namespace {
 
+blink::mojom::SpeculationCandidatePtr CreatePrerenderCandidate(
+    const GURL& url) {
+  auto candidate = blink::mojom::SpeculationCandidate::New();
+  candidate->action = blink::mojom::SpeculationAction::kPrerender;
+  candidate->url = url;
+  candidate->referrer = blink::mojom::Referrer::New();
+  return candidate;
+}
+
+void SendCandidate(const GURL& url,
+                   mojo::Remote<blink::mojom::SpeculationHost>& remote) {
+  std::vector<blink::mojom::SpeculationCandidatePtr> candidates;
+  candidates.push_back(CreatePrerenderCandidate(url));
+  remote->UpdateSpeculationCandidates(std::move(candidates));
+  remote.FlushForTesting();
+}
+
 // This definition is needed because this constant is odr-used in gtest macros.
 // https://en.cppreference.com/w/cpp/language/static#Constant_static_members
 const int kNoFrameTreeNodeId = RenderFrameHost::kNoFrameTreeNodeId;
 
+class PrerenderWebContentsDelegate : public WebContentsDelegate {
+ public:
+  PrerenderWebContentsDelegate() = default;
+
+  bool IsPrerender2Supported() override { return true; }
+};
+
 class PrerenderHostRegistryTest : public RenderViewHostImplTestHarness {
  public:
   PrerenderHostRegistryTest() = default;
@@ -46,14 +72,28 @@
     std::unique_ptr<TestWebContents> web_contents(TestWebContents::Create(
         browser_context_.get(),
         SiteInstanceImpl::Create(browser_context_.get())));
+    web_contents->SetDelegate(&web_contents_delegate_);
     web_contents->NavigateAndCommit(url);
     return web_contents;
   }
 
+  RenderFrameHostImpl* NavigatePrimaryPage(TestWebContents* web_contents,
+                                           const GURL& dest_url) {
+    std::unique_ptr<NavigationSimulatorImpl> navigation =
+        NavigationSimulatorImpl::CreateRendererInitiated(
+            dest_url, web_contents->GetMainFrame());
+    navigation->SetTransition(ui::PAGE_TRANSITION_LINK);
+    navigation->Start();
+    navigation->Commit();
+    RenderFrameHostImpl* render_frame_host = web_contents->GetMainFrame();
+    EXPECT_EQ(render_frame_host->GetLastCommittedURL(), dest_url);
+    return render_frame_host;
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
-
   std::unique_ptr<TestBrowserContext> browser_context_;
+  PrerenderWebContentsDelegate web_contents_delegate_;
 };
 
 // Finish a prerendering navigation that was already started with
@@ -183,13 +223,18 @@
   registry->OnActivationFinished(frame_tree_node_id1);
 }
 
-TEST_F(PrerenderHostRegistryTest, CreateAndStartHostForDifferentURLs) {
+// Tests that PrerenderHostRegistry limits the number of started prerenders
+// to 1.
+TEST_F(PrerenderHostRegistryTest, NumberLimit_Activation) {
+  base::HistogramTester histogram_tester;
   const GURL kOriginalUrl("https://example.com/");
   std::unique_ptr<TestWebContents> web_contents =
       CreateWebContents(kOriginalUrl);
   RenderFrameHostImpl* render_frame_host = web_contents->GetMainFrame();
   ASSERT_TRUE(render_frame_host);
 
+  // After the first prerender page was activated, PrerenderHostRegistry can
+  // start prerendering a new one.
   const GURL kPrerenderingUrl1("https://example.com/next1");
   auto attributes1 = blink::mojom::PrerenderAttributes::New();
   attributes1->url = kPrerenderingUrl1;
@@ -199,45 +244,135 @@
   attributes2->url = kPrerenderingUrl2;
 
   PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
-  const int frame_tree_node_id1 =
+  int frame_tree_node_id1 =
       registry->CreateAndStartHost(std::move(attributes1), *render_frame_host);
-  const int frame_tree_node_id2 =
+  int frame_tree_node_id2 =
       registry->CreateAndStartHost(std::move(attributes2), *render_frame_host);
-  EXPECT_NE(frame_tree_node_id1, frame_tree_node_id2);
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
+
+  // PrerenderHostRegistry should only start prerendering for kPrerenderingUrl1.
+  EXPECT_NE(frame_tree_node_id1, kNoFrameTreeNodeId);
+  EXPECT_EQ(frame_tree_node_id2, kNoFrameTreeNodeId);
+
+  // Activate the first prerender.
   PrerenderHost* prerender_host1 =
       registry->FindHostByUrlForTesting(kPrerenderingUrl1);
-  PrerenderHost* prerender_host2 =
-      registry->FindHostByUrlForTesting(kPrerenderingUrl2);
   CommitPrerenderNavigation(*prerender_host1);
-  CommitPrerenderNavigation(*prerender_host2);
-
-  // Select the first host.
   std::unique_ptr<NavigationSimulatorImpl> navigation =
       NavigationSimulatorImpl::CreateRendererInitiated(kPrerenderingUrl1,
                                                        render_frame_host);
   navigation->Start();
   NavigationRequest* navigation_request = navigation->GetNavigationHandle();
-
   EXPECT_EQ(navigation_request->prerender_frame_tree_node_id(),
             frame_tree_node_id1);
   EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
-  // The second host should still be findable.
-  EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl2),
-            prerender_host2);
-
-  // Select the second host.
-  std::unique_ptr<NavigationSimulatorImpl> navigation2 =
-      NavigationSimulatorImpl::CreateRendererInitiated(kPrerenderingUrl2,
-                                                       render_frame_host);
-  navigation2->Start();
-  NavigationRequest* navigation_request2 = navigation2->GetNavigationHandle();
-
-  EXPECT_EQ(navigation_request2->prerender_frame_tree_node_id(),
-            frame_tree_node_id2);
-  EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
-
   registry->OnActivationFinished(frame_tree_node_id1);
-  registry->OnActivationFinished(frame_tree_node_id2);
+
+  // After the first prerender page was activated, PrerenderHostRegistry can
+  // start prerendering a new one.
+  attributes2 = blink::mojom::PrerenderAttributes::New();
+  attributes2->url = kPrerenderingUrl2;
+  frame_tree_node_id2 =
+      registry->CreateAndStartHost(std::move(attributes2), *render_frame_host);
+  EXPECT_NE(frame_tree_node_id2, kNoFrameTreeNodeId);
+  histogram_tester.ExpectBucketCount(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
+}
+
+// Tests that PrerenderHostRegistry limits the number of started prerenders
+// to 1, and new candidates can be processed after the initiator page navigates
+// to a new same-origin page.
+TEST_F(PrerenderHostRegistryTest, NumberLimit_SameOriginNavigateAway) {
+  base::HistogramTester histogram_tester;
+  const GURL kOriginalUrl("https://example.com/");
+  std::unique_ptr<TestWebContents> web_contents =
+      CreateWebContents(kOriginalUrl);
+  RenderFrameHostImpl* render_frame_host = web_contents->GetMainFrame();
+  ASSERT_TRUE(render_frame_host);
+
+  mojo::Remote<blink::mojom::SpeculationHost> remote1;
+  SpeculationHostImpl::Bind(render_frame_host,
+                            remote1.BindNewPipeAndPassReceiver());
+  ASSERT_TRUE(remote1.is_connected());
+  const GURL kPrerenderingUrl1("https://example.com/next1");
+  const GURL kPrerenderingUrl2("https://example.com/next2");
+  SendCandidate(kPrerenderingUrl1, remote1);
+  SendCandidate(kPrerenderingUrl2, remote1);
+  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
+
+  // PrerenderHostRegistry should only start prerendering for kPrerenderingUrl1.
+  ASSERT_NE(registry->FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
+  ASSERT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
+
+  // The initiator document navigates away.
+  render_frame_host = NavigatePrimaryPage(
+      web_contents.get(), GURL("https://example.com/elsewhere"));
+  EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
+
+  // After the initiator page navigates away, the started prerendering should be
+  // cancelled, and PrerenderHostRegistry can start prerendering a new one.
+  mojo::Remote<blink::mojom::SpeculationHost> remote2;
+  SpeculationHostImpl::Bind(render_frame_host,
+                            remote2.BindNewPipeAndPassReceiver());
+  SendCandidate(kPrerenderingUrl2, remote2);
+
+  EXPECT_NE(registry->FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
+  histogram_tester.ExpectBucketCount(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
+}
+
+// Tests that PrerenderHostRegistry limits the number of started prerenders
+// to 1, and new candidates can be processed after the initiator page navigates
+// to a new cross-origin page.
+TEST_F(PrerenderHostRegistryTest, NumberLimit_CrossOriginNavigateAway) {
+  base::HistogramTester histogram_tester;
+  const GURL kOriginalUrl("https://example.com/");
+
+  std::unique_ptr<TestWebContents> web_contents =
+      CreateWebContents(kOriginalUrl);
+  RenderFrameHostImpl* render_frame_host = web_contents->GetMainFrame();
+  ASSERT_TRUE(render_frame_host);
+
+  mojo::Remote<blink::mojom::SpeculationHost> remote1;
+  SpeculationHostImpl::Bind(render_frame_host,
+                            remote1.BindNewPipeAndPassReceiver());
+  ASSERT_TRUE(remote1.is_connected());
+  const GURL kPrerenderingUrl1("https://example.com/next1");
+  const GURL kPrerenderingUrl2("https://example.com/next2");
+  SendCandidate(kPrerenderingUrl1, remote1);
+  SendCandidate(kPrerenderingUrl2, remote1);
+  PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry();
+
+  // PrerenderHostRegistry should only start prerendering for kPrerenderingUrl1.
+  ASSERT_NE(registry->FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
+  ASSERT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl2), nullptr);
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
+
+  // The initiator document navigates away to a cross-origin page.
+  render_frame_host =
+      NavigatePrimaryPage(web_contents.get(), GURL("https://example.org/"));
+  EXPECT_EQ(registry->FindHostByUrlForTesting(kPrerenderingUrl1), nullptr);
+
+  // After the initiator page navigates away, the started prerendering should be
+  // cancelled, and PrerenderHostRegistry can start prerendering a new one.
+  mojo::Remote<blink::mojom::SpeculationHost> remote2;
+  SpeculationHostImpl::Bind(render_frame_host,
+                            remote2.BindNewPipeAndPassReceiver());
+  const GURL kPrerenderingUrl3("https://example.org/next1");
+  SendCandidate(kPrerenderingUrl3, remote2);
+  EXPECT_NE(registry->FindHostByUrlForTesting(kPrerenderingUrl3), nullptr);
+  histogram_tester.ExpectBucketCount(
+      "Prerender.Experimental.PrerenderHostFinalStatus",
+      PrerenderHost::FinalStatus::kMaxNumOfRunningPrerendersExceeded, 1);
 }
 
 TEST_F(PrerenderHostRegistryTest,
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS
index cd90edb..3219bc4 100644
--- a/content/browser/renderer_host/DEPS
+++ b/content/browser/renderer_host/DEPS
@@ -32,6 +32,7 @@
     "+components/viz/service",
   ],
   "render_process_host_impl\.cc": [
+    "+google_apis/gaia/gaia_config.h",
     "+google_apis/gaia/gaia_switches.h",
     # TODO(crbug.com/734668): Dependencies on ozone should be removed, as content
     # embedded in mus won't be able to talk to the native ozone.
diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc
index cc54ad8d..91a6039 100644
--- a/content/browser/renderer_host/clipboard_host_impl.cc
+++ b/content/browser/renderer_host/clipboard_host_impl.cc
@@ -363,8 +363,7 @@
 void ClipboardHostImpl::OnReadImage(ui::ClipboardBuffer clipboard_buffer,
                                     ReadImageCallback callback,
                                     const SkBitmap& bitmap) {
-  std::string data =
-      std::string(reinterpret_cast<const char*>(bitmap.getPixels()),
+  std::string data(reinterpret_cast<const char*>(bitmap.getPixels()),
                   bitmap.computeByteSize());
   PasteIfPolicyAllowed(clipboard_buffer,
                        ui::ClipboardFormatType::GetBitmapType(),
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
index 54573ec..8cc34d1 100644
--- a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
+++ b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
@@ -8,8 +8,8 @@
 #import <Cocoa/Cocoa.h>
 #include <stddef.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/mac_util.h"
-#include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "ui/events/cocoa/cocoa_event_utils.h"
 #include "ui/events/event.h"
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
index c5663e48..d18f1b1 100644
--- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -10394,8 +10394,10 @@
 
 // Ensure that we do not corrupt a NavigationEntry's PageState if two forward
 // navigations compete in different frames.  See https://crbug.com/623319.
-// Currently flaking on Android, Linux and Mac, see https://crubug.com/1101292.
-#if defined(OS_ANDROID) || defined(OS_MAC) || defined(OS_LINUX)
+// Currently flaking on Android, Linux and Mac, see https://crbug.com/1101292.
+// Currently flaking on ChromeOS, see https://crbug.com/1227088.
+#if defined(OS_ANDROID) || defined(OS_MAC) || defined(OS_LINUX) || \
+    defined(OS_CHROMEOS)
 #define MAYBE_PageStateAfterForwardInCompetingFrames \
   DISABLED_PageStateAfterForwardInCompetingFrames
 #else
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 5464440..3206b28 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -5245,6 +5245,18 @@
     return;
   }
 
+  if (base::FeatureList::IsEnabled(
+          features::kBlockInsecurePrivateNetworkRequestsDeprecationTrial) &&
+      blink::TrialTokenValidator().RequestEnablesFeature(
+          common_params_->url, response_head_->headers.get(),
+          "PrivateNetworkAccessNonSecureContextsAllowed", base::Time::Now())) {
+    // TODO(https://crbug.com/1225977): Record that we need to increment a
+    // usecounter after commit.
+    private_network_request_policy_ =
+        network::mojom::PrivateNetworkRequestPolicy::kAllow;
+    return;
+  }
+
   // Requests from non-secure contexts are only blocked if the feature is
   // enabled, otherwise we simply show a warning in DevTools.
   private_network_request_policy_ =
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 2490470..2ee680f6 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -772,11 +772,10 @@
   // calculations. Do not use it to make actual decisions.
   bool IsLoadDataWithBaseURLAndHasUnreachableURL();
 
-  // Will calculate an *approximation* of the origin that this NavigationRequest
-  // will commit.  (An "approximation", because sandboxing is not taken into
-  // account - see https://crbug.com/1041376.  The approximation is still good
-  // enough for |request_initiator_origin_lock| in
-  // network::mojom::URLLoaderFactoryParams.)
+  // Will calculate the origin that this NavigationRequest will commit. (This
+  // should be reasonably accurate, but some browser-vs-renderer inconsistencies
+  // might still exist - they are currently tracked in
+  // https://crbug.com/1220238).
   //
   // This method depends on GetRenderFrameHost() and therefore can only be
   // called after a response has been delivered for processing, or after the
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm b/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
index 91fd4ca3..f753ed2 100644
--- a/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
+++ b/content/browser/renderer_host/pepper/pepper_truetype_font_list_mac.mm
@@ -6,7 +6,7 @@
 
 #import <Cocoa/Cocoa.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #include "ppapi/c/dev/ppb_truetype_font_dev.h"
 #include "ppapi/proxy/serialized_structs.h"
diff --git a/content/browser/renderer_host/private_network_access_browsertest.cc b/content/browser/renderer_host/private_network_access_browsertest.cc
index 86e6ea8db..edd00bae 100644
--- a/content/browser/renderer_host/private_network_access_browsertest.cc
+++ b/content/browser/renderer_host/private_network_access_browsertest.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "base/test/scoped_feature_list.h"
@@ -19,6 +20,7 @@
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/url_loader_interceptor.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/content_browser_test_utils_internal.h"
 #include "content/test/resource_load_observer.h"
@@ -2252,6 +2254,148 @@
             network::mojom::PrivateNetworkRequestPolicy::kBlock);
 }
 
+// ==================================================
+// SECURE CONTEXT RESTRICTION DEPRECATION TRIAL TESTS
+// ==================================================
+//
+// These tests verify the correct behavior of `private_network_request_policy`
+// in the face of the `PrivateNetworkAccessNonSecureContextsAllowed` deprecation
+// trial.
+
+// Origin Trial tokens are tied to a single origin, which precludes the use of
+// `net::EmbeddedTestServer` and its random port assignment. Instead, we resort
+// to the use of an interceptor that can serve resources from a fixed origin.
+class OriginTrialURLLoaderInterceptor {
+ public:
+  OriginTrialURLLoaderInterceptor()
+      : interceptor_(
+            base::BindRepeating(&OriginTrialURLLoaderInterceptor::HandleRequest,
+                                base::Unretained(this))) {}
+
+  // Instances of this type are neither copyable nor movable.
+  OriginTrialURLLoaderInterceptor(const OriginTrialURLLoaderInterceptor&) =
+      delete;
+  OriginTrialURLLoaderInterceptor& operator=(
+      const OriginTrialURLLoaderInterceptor&) = delete;
+
+  GURL EnabledUrl() const { return enabled_url_; }
+  GURL DisabledUrl() const { return disabled_url_; }
+
+ private:
+  using RequestParams = URLLoaderInterceptor::RequestParams;
+
+  bool HandleRequest(RequestParams* request_params) const {
+    const GURL& url = request_params->url_request.url;
+    if (url == EnabledUrl()) {
+      HandleEnabledUrlRequest(*request_params);
+      return true;
+    }
+
+    if (url == DisabledUrl()) {
+      HandleDisabledUrlRequest(*request_params);
+      return true;
+    }
+
+    return false;
+  }
+
+  void HandleEnabledUrlRequest(RequestParams& request_params) const {
+    constexpr char kHeaders[] =      //
+        "HTTP/1.1 200 OK\n"          //
+        "Content-Type: text/html\n"  //
+        // Use CSP to make the page `public`, even though it is served with no
+        // IP address information. Without this it is treated as `unknown`, and
+        // that interferes with its private network request policy.
+        "Content-Security-Policy: treat-as-public-address\n"  //
+        // This token was generated using:
+        //
+        //   $ tools/origin_trials/generate_token.py \
+        //     --expire-days 5000 \
+        //     --version 3 \
+        //     http://enabled.test PrivateNetworkAccessNonSecureContextsAllowed
+        //
+        "Origin-Trial: "
+        "A4dgNIB2F3P8qkQQes/oiaobjPNRbfZcaPd5TqdcIHUlpX3/al3rvk5b4f+dnke3WcsXeX"
+        "4aMNENL3mg1FM8+wYAAAB1eyJvcmlnaW4iOiAiaHR0cDovL2VuYWJsZWQudGVzdDo4MCIs"
+        "ICJmZWF0dXJlIjogIlByaXZhdGVOZXR3b3JrQWNjZXNzTm9uU2VjdXJlQ29udGV4dHNBbG"
+        "xvd2VkIiwgImV4cGlyeSI6IDIwNTcxNDYwMzB9"  //
+        "\n\n";
+    URLLoaderInterceptor::WriteResponse(kHeaders, "",
+                                        request_params.client.get());
+  }
+
+  void HandleDisabledUrlRequest(RequestParams& request_params) const {
+    constexpr char kHeaders[] =      //
+        "HTTP/1.1 200 OK\n"          //
+        "Content-Type: text/html\n"  //
+        // See above.
+        "Content-Security-Policy: treat-as-public-address\n\n";
+    URLLoaderInterceptor::WriteResponse(kHeaders, "",
+                                        request_params.client.get());
+  }
+
+  const GURL enabled_url_{"http://enabled.test/"};
+  const GURL disabled_url_{"http://disabled.test/"};
+  URLLoaderInterceptor interceptor_;
+};
+
+// Test with insecure private network requests blocked, excluding navigations.
+class PrivateNetworkAccessDeprecationTrialBrowserTest
+    : public PrivateNetworkAccessBrowserTestBase {
+ public:
+  PrivateNetworkAccessDeprecationTrialBrowserTest()
+      : PrivateNetworkAccessBrowserTestBase(
+            {
+                features::kBlockInsecurePrivateNetworkRequests,
+                features::kBlockInsecurePrivateNetworkRequestsDeprecationTrial,
+            },
+            {}) {}
+};
+
+IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessBrowserTest,
+                       DeprecationTrialDisabled) {
+  OriginTrialURLLoaderInterceptor interceptor;
+
+  EXPECT_TRUE(NavigateToURL(shell(), interceptor.EnabledUrl()));
+
+  const network::mojom::ClientSecurityStatePtr security_state =
+      root_frame_host()->BuildClientSecurityState();
+  ASSERT_FALSE(security_state.is_null());
+
+  EXPECT_EQ(security_state->private_network_request_policy,
+            network::mojom::PrivateNetworkRequestPolicy::kBlock);
+}
+
+IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessDeprecationTrialBrowserTest,
+                       OriginEnabled) {
+  OriginTrialURLLoaderInterceptor interceptor;
+
+  EXPECT_TRUE(NavigateToURL(shell(), interceptor.EnabledUrl()));
+
+  const network::mojom::ClientSecurityStatePtr security_state =
+      root_frame_host()->BuildClientSecurityState();
+  ASSERT_FALSE(security_state.is_null());
+
+  // TODO(https://crbug.com/1225977): Expect `kAllow` once support for trials
+  // on insecure origins is fixed in `blink::TrialTokenValidator`.
+  EXPECT_EQ(security_state->private_network_request_policy,
+            network::mojom::PrivateNetworkRequestPolicy::kBlock);
+}
+
+IN_PROC_BROWSER_TEST_F(PrivateNetworkAccessDeprecationTrialBrowserTest,
+                       OriginDisabled) {
+  OriginTrialURLLoaderInterceptor interceptor;
+
+  EXPECT_TRUE(NavigateToURL(shell(), interceptor.DisabledUrl()));
+
+  const network::mojom::ClientSecurityStatePtr security_state =
+      root_frame_host()->BuildClientSecurityState();
+  ASSERT_FALSE(security_state.is_null());
+
+  EXPECT_EQ(security_state->private_network_request_policy,
+            network::mojom::PrivateNetworkRequestPolicy::kBlock);
+}
+
 // =======================
 // SUBRESOURCE FETCH TESTS
 // =======================
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 445f0e3..ccfb5ad 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -4994,7 +4994,7 @@
 void SetupRemoteObjectInvocation(Shell* shell, const GURL& url) {
   WebContents* web_contents = shell->web_contents();
 
-  // The first load triggers RenderFrameCreated on a RenderFrameHostObserver
+  // The first load triggers RenderFrameCreated on a WebContentsObserver
   // instance, where the object injection happens.
   shell->LoadURL(url);
   EXPECT_TRUE(WaitForLoadStop(web_contents));
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 43c270f8..d68e24f5 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -168,6 +168,7 @@
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/zygote/zygote_buildflags.h"
+#include "google_apis/gaia/gaia_config.h"
 #include "google_apis/gaia/gaia_switches.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gpu_switches.h"
@@ -3561,6 +3562,17 @@
   renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
                                  base::size(kSwitchNames));
 
+  // |switches::kGaiaConfig| can be set via browser command-line arguments,
+  // usually by developers working on signin code. The switch, however, cannot
+  // be passed as is, because the renderer cannot read the file anyway. In those
+  // cases (and only in those cases) GaiaConfig::GetInstance() returns non-null,
+  // and it can be used to serialize its content (usually <2 KB) into a
+  // command-line switch.
+  if (GaiaConfig::GetInstance()) {
+    GaiaConfig::GetInstance()->SerializeContentsToCommandLineSwitch(
+        renderer_cmd);
+  }
+
   BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(renderer_cmd);
   BrowserChildProcessHostImpl::CopyTraceStartupFlags(renderer_cmd);
 
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 169279f..b6602d1 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -71,6 +71,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_iterator.h"
 #include "content/public/common/content_client.h"
@@ -1969,12 +1970,13 @@
 }
 
 bool RenderWidgetHostViewAndroid::ShowSelectionMenu(
+    RenderFrameHost* render_frame_host,
     const ContextMenuParams& params) {
   if (!selection_popup_controller_ || is_in_vr_)
     return false;
 
-  return selection_popup_controller_->ShowSelectionMenu(params,
-                                                        GetTouchHandleHeight());
+  return selection_popup_controller_->ShowSelectionMenu(
+      render_frame_host, params, GetTouchHandleHeight());
 }
 
 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 3da6d4cb..eb8aea3 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -30,6 +30,7 @@
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/renderer_host/text_input_manager.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/render_frame_host.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/android/delegated_frame_host_android.h"
 #include "ui/android/view_android.h"
@@ -252,7 +253,8 @@
   void SendMouseEvent(const ui::MotionEventAndroid&, int action_button);
   void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event);
   void SendGestureEvent(const blink::WebGestureEvent& event);
-  bool ShowSelectionMenu(const ContextMenuParams& params);
+  bool ShowSelectionMenu(RenderFrameHost* render_frame_host,
+                         const ContextMenuParams& params);
   void set_ime_adapter(ImeAdapterAndroid* ime_adapter) {
     ime_adapter_android_ = ime_adapter;
   }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
index 26f4f28..26299d4 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm
@@ -7,7 +7,7 @@
 #import <objc/runtime.h>
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #import "content/browser/renderer_host/render_widget_host_view_mac.h"
 
diff --git a/content/browser/service_worker/service_worker_host.cc b/content/browser/service_worker/service_worker_host.cc
index fc215bc..1295393 100644
--- a/content/browser/service_worker/service_worker_host.cc
+++ b/content/browser/service_worker/service_worker_host.cc
@@ -137,18 +137,16 @@
   if (embedded_worker_status == EmbeddedWorkerStatus::STOPPING)
     return;
 
-  // Create a new CodeCacheHostImpl and bind it to the given receiver.
+  // It is possible that the RenderProcessHost is gone but we receive a request
+  // before we had the opportunity to Detach because the disconnect handler
+  // wasn't run yet. In such cases it is is safe to ignore these messages since
+  // we are about to stop the service worker.
   auto* process =
       RenderProcessHost::FromID(version_->embedded_worker()->process_id());
-  // TODO(crbug:1221042): Remove the following checks once the investigation of
-  // the crashes is done.
-  if (process == nullptr) {
-    SCOPED_CRASH_KEY_STRING32(
-        "SWHost::CreateCodeCacheHost", "info",
-        base::StringPrintf("status:%d,pid:%d", embedded_worker_status,
-                           version_->embedded_worker()->process_id()));
-    CHECK(false);
-  }
+  if (process == nullptr)
+    return;
+
+  // Create a new CodeCacheHostImpl and bind it to the given receiver.
   StoragePartition* storage_partition = process->GetStoragePartition();
   code_cache_host_receivers_.Add(
       std::make_unique<CodeCacheHostImpl>(
diff --git a/content/browser/speculation_rules/speculation_host_impl.cc b/content/browser/speculation_rules/speculation_host_impl.cc
index 6f873b5..96afffe 100644
--- a/content/browser/speculation_rules/speculation_host_impl.cc
+++ b/content/browser/speculation_rules/speculation_host_impl.cc
@@ -39,7 +39,6 @@
 void SpeculationHostImpl::Bind(
     RenderFrameHost* frame_host,
     mojo::PendingReceiver<blink::mojom::SpeculationHost> receiver) {
-  // Note: Currently SpeculationHostImpl doesn't trigger prerendering.
   // TODO(crbug.com/1190338): Allow SpeculationHostDelegate to participate in
   // this feature check.
   if (!base::FeatureList::IsEnabled(
@@ -60,6 +59,7 @@
     mojo::PendingReceiver<blink::mojom::SpeculationHost> receiver)
     : DocumentServiceBase(frame_host, std::move(receiver)) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   delegate_ = GetContentClient()->browser()->CreateSpeculationHostDelegate(
       *render_frame_host());
   if (blink::features::IsPrerender2Enabled()) {
@@ -69,16 +69,26 @@
 }
 
 SpeculationHostImpl::~SpeculationHostImpl() {
-  // Inform PrerenderHostRegistry of the destruction.
-  if (registry_ &&
-      started_prerender_host_id_ != RenderFrameHost::kNoFrameTreeNodeId) {
-    registry_->OnTriggerDestroyed(started_prerender_host_id_);
-  }
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  CancelStartedPrerenders();
+}
+
+void SpeculationHostImpl::PrimaryPageChanged() {
+  // Listen to the change of the primary page. Since only the primary page can
+  // trigger speculationrules, the change of the primary page indicates that the
+  // trigger associated with this host is destroyed, so the browser should
+  // cancel the prerenders that are initiated by it.
+  // We cannot do it in the destructor only, because DocumentService can be
+  // deleted asynchronously, but we want to make sure to cancel prerendering
+  // before the next primary page swaps in so that the next page can trigger a
+  // new prerender without hitting the max number of running prerenders.
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  CancelStartedPrerenders();
 }
 
 void SpeculationHostImpl::UpdateSpeculationCandidates(
     std::vector<blink::mojom::SpeculationCandidatePtr> candidates) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!CandidatesAreValid(candidates))
     return;
 
@@ -108,47 +118,34 @@
     return;
   }
 
-  // Limit the number of started prerenders to one. If
-  // `started_prerender_host_id_` does not equal kNoFrameTreeNodeId, it means
-  // `this` has started a prerender, and should ignore other prerender
-  // candidates.
-  // TODO(crbug.com/1197133): Cancel the started prerender and start a new
-  // one if the score of the new candidate is higher than the started one's.
-  // TODO(crbug.com/1197133): Record the cancellation reason via UMA.
-  // TODO(crbug.com/1173298): Let PrerenderHostRegistry control the maximum
-  // number of started prerenders.
-  if (started_prerender_host_id_ != RenderFrameHost::kNoFrameTreeNodeId) {
-    return;
-  }
-
-  // Find the first prerender candidate, since we limit the number of started
-  // prerenders to one.
-  // TODO(crbug.com/1197133): Find the candidate with the highest score.
-  // TODO(crbug.com/1176054): Support cross-origin prerendering.
-  // TODO(crbug.com/1197133): Record the cancellation reason of no same-origin
-  // candidates via UMA.
-  const auto prerender_filter =
-      [&](const blink::mojom::SpeculationCandidatePtr& it) {
-        return it->action == blink::mojom::SpeculationAction::kPrerender &&
-               origin().IsSameOriginWith(url::Origin::Create(it->url));
-      };
-  const auto candidate_it =
-      std::find_if(candidates.begin(), candidates.end(), prerender_filter);
-  if (candidate_it == candidates.end())
-    return;
-
-  const blink::mojom::SpeculationCandidatePtr& candidate = *candidate_it;
-  // TODO(https://crbug.com/1197133): Set up the field of size.
-  auto attributes = blink::mojom::PrerenderAttributes::New();
-  attributes->url = candidate->url;
-  attributes->referrer = std::move(candidate->referrer);
-  attributes->trigger_type =
-      blink::mojom::PrerenderTriggerType::kSpeculationRule;
-
   auto* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host());
-  if (registry_) {
-    started_prerender_host_id_ =
+  for (const auto& it : candidates) {
+    // TODO(crbug.com/1176054): Support cross-origin prerendering.
+    // TODO(crbug.com/1197133): Record the cancellation reason of no same-origin
+    // candidates via UMA.
+    if (it->action != blink::mojom::SpeculationAction::kPrerender ||
+        !origin().IsSameOriginWith(url::Origin::Create(it->url))) {
+      continue;
+    }
+
+    // TODO(https://crbug.com/1217903): Set up `attributes->size`.
+    auto attributes = blink::mojom::PrerenderAttributes::New();
+    attributes->url = it->url;
+    attributes->referrer = std::move(it->referrer);
+    attributes->trigger_type =
+        blink::mojom::PrerenderTriggerType::kSpeculationRule;
+    int prerender_host_id =
         registry_->CreateAndStartHost(std::move(attributes), *rfhi);
+    if (prerender_host_id != RenderFrameHost::kNoFrameTreeNodeId)
+      started_prerender_host_ids_.insert(prerender_host_id);
+  }
+}
+
+void SpeculationHostImpl::CancelStartedPrerenders() {
+  if (registry_) {
+    for (const auto id : started_prerender_host_ids_)
+      registry_->OnTriggerDestroyed(id);
+    started_prerender_host_ids_.clear();
   }
 }
 
diff --git a/content/browser/speculation_rules/speculation_host_impl.h b/content/browser/speculation_rules/speculation_host_impl.h
index 444b0a5b..d378458e 100644
--- a/content/browser/speculation_rules/speculation_host_impl.h
+++ b/content/browser/speculation_rules/speculation_host_impl.h
@@ -7,14 +7,15 @@
 
 #include <vector>
 
+#include "base/containers/flat_set.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/document_service_base.h"
-#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/speculation_host_delegate.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom.h"
 
 namespace content {
+class RenderFrameHost;
 class PrerenderHostRegistry;
 
 // Receiver for speculation rules from the web platform. See
@@ -34,6 +35,9 @@
   SpeculationHostImpl(SpeculationHostImpl&&) = delete;
   SpeculationHostImpl& operator=(SpeculationHostImpl&&) = delete;
 
+  // WebContentsObserver implementation:
+  void PrimaryPageChanged() override;
+
  private:
   SpeculationHostImpl(
       RenderFrameHost* frame_host,
@@ -45,8 +49,13 @@
   void ProcessCandidatesForPrerender(
       const std::vector<blink::mojom::SpeculationCandidatePtr>& candidates);
 
-  int started_prerender_host_id_ = RenderFrameHost::kNoFrameTreeNodeId;
+  void CancelStartedPrerenders();
+
   std::unique_ptr<SpeculationHostDelegate> delegate_;
+
+  // TODO(https://crbug.com/1197133): Record the prerendering URLs as well so
+  // that this can cancel started prerenders when candidates are updated.
+  base::flat_set<int> started_prerender_host_ids_;
   base::WeakPtr<PrerenderHostRegistry> registry_;
 };
 
diff --git a/content/browser/speculation_rules/speculation_host_impl_unittest.cc b/content/browser/speculation_rules/speculation_host_impl_unittest.cc
index f3c67d6..5124c013 100644
--- a/content/browser/speculation_rules/speculation_host_impl_unittest.cc
+++ b/content/browser/speculation_rules/speculation_host_impl_unittest.cc
@@ -101,29 +101,6 @@
   EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
 }
 
-// Tests that SpeculationHostImpl starts only one prerender when it receives
-// more than one prerender candidates.
-// TODO(crbug.com/1197133): Prerender the candidate with the highest score.
-TEST_F(SpeculationHostImplTest, StartOnePrerenderOnMultipleCandidates) {
-  RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
-  PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
-  mojo::Remote<blink::mojom::SpeculationHost> remote;
-  SpeculationHostImpl::Bind(render_frame_host,
-                            remote.BindNewPipeAndPassReceiver());
-
-  const std::vector<GURL> prerender_urls{GetSameOriginUrl("/empty.html?1"),
-                                         GetSameOriginUrl("/empty.html?2")};
-  std::vector<blink::mojom::SpeculationCandidatePtr> candidates;
-  for (const auto& url : prerender_urls) {
-    candidates.push_back(CreatePrerenderCandidate(url));
-  }
-
-  remote->UpdateSpeculationCandidates(std::move(candidates));
-  remote.FlushForTesting();
-  EXPECT_TRUE(registry->FindHostByUrlForTesting(prerender_urls[0]));
-  EXPECT_FALSE(registry->FindHostByUrlForTesting(prerender_urls[1]));
-}
-
 // Tests that SpeculationHostImpl will skip the prerender candidate if it is a
 // cross-origin url.
 TEST_F(SpeculationHostImplTest, SkipCrossOriginPrerenderCandidates) {
@@ -176,36 +153,6 @@
       registry->FindHostByUrlForTesting(kSecondPrerenderingUrlSameOrigin));
 }
 
-// Tests that SpeculationHostImpl will ignore prerender candidates if it has
-// started prerendering.
-// TODO(crbug.com/1197133): Cancel the started prerender and start a new
-// one if the score of the new candidate is higher than the started one's.
-TEST_F(SpeculationHostImplTest, PrerenderOnlyOnce) {
-  RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
-  PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
-  mojo::Remote<blink::mojom::SpeculationHost> remote;
-  SpeculationHostImpl::Bind(render_frame_host,
-                            remote.BindNewPipeAndPassReceiver());
-
-  const auto update_prerender_candidate = [&](const GURL& url) {
-    std::vector<blink::mojom::SpeculationCandidatePtr> candidates;
-    candidates.push_back(CreatePrerenderCandidate(url));
-    remote->UpdateSpeculationCandidates(std::move(candidates));
-    remote.FlushForTesting();
-  };
-
-  const GURL kFirstPrerenderingUrl = GetSameOriginUrl("/empty.html?1");
-  update_prerender_candidate(kFirstPrerenderingUrl);
-  EXPECT_TRUE(registry->FindHostByUrlForTesting(kFirstPrerenderingUrl));
-
-  // If there is a started prerender, new prerender candidates should be
-  // ignored.
-  const GURL kSecondPrerenderingUrl = GetSameOriginUrl("/empty.html?2");
-  update_prerender_candidate(kSecondPrerenderingUrl);
-  EXPECT_FALSE(registry->FindHostByUrlForTesting(kSecondPrerenderingUrl));
-  EXPECT_TRUE(registry->FindHostByUrlForTesting(kFirstPrerenderingUrl));
-}
-
 // Tests that SpeculationHostImpl crash the renderer process if it receives
 // non-http prerender candidates.
 TEST_F(SpeculationHostImplTest, ReportNonHttpMessage) {
diff --git a/content/browser/tracing/background_tracing_config_impl.cc b/content/browser/tracing/background_tracing_config_impl.cc
index 3291d08..5761ebb 100644
--- a/content/browser/tracing/background_tracing_config_impl.cc
+++ b/content/browser/tracing/background_tracing_config_impl.cc
@@ -391,6 +391,7 @@
   std::unique_ptr<BackgroundTracingRule> rule =
       BackgroundTracingRule::CreateRuleFromDict(dict);
   if (rule) {
+    has_crash_scenario_ = rule->is_crash();
     rules_.push_back(std::move(rule));
     return rules_.back().get();
   }
diff --git a/content/browser/tracing/background_tracing_config_impl.h b/content/browser/tracing/background_tracing_config_impl.h
index a07eec1a..b6942d4 100644
--- a/content/browser/tracing/background_tracing_config_impl.h
+++ b/content/browser/tracing/background_tracing_config_impl.h
@@ -44,7 +44,6 @@
   const std::vector<std::unique_ptr<BackgroundTracingRule>>& rules() const {
     return rules_;
   }
-  const std::string& scenario_name() const { return scenario_name_; }
 
   void AddPreemptiveRule(const base::DictionaryValue* dict);
   void AddReactiveRule(
@@ -110,7 +109,6 @@
   base::trace_event::TraceConfig trace_config_;
   CategoryPreset category_preset_;
   std::vector<std::unique_ptr<BackgroundTracingRule>> rules_;
-  std::string scenario_name_;
   std::string custom_categories_;
   std::string enabled_data_sources_;
 
diff --git a/content/browser/tracing/background_tracing_manager_browsertest.cc b/content/browser/tracing/background_tracing_manager_browsertest.cc
index 970dfc8..1f3ea89 100644
--- a/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -1092,7 +1092,14 @@
   background_tracing_helper.WaitForScenarioAborted();
 }
 
-IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest, CustomConfig) {
+// TODO(crbug.com/1227164): Test is flaky on Linux and Windows.
+#if defined(OS_LINUX) || defined(OS_WIN)
+#define MAYBE_CustomConfig DISABLED_CustomConfig
+#else
+#define MAYBE_CustomConfig CustomConfig
+#endif
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+                       MAYBE_CustomConfig) {
   TestBackgroundTracingHelper background_tracing_helper;
   TestTraceReceiverHelper trace_receiver_helper;
 
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc
index 1c1eb4e..d12ff02a 100644
--- a/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -182,21 +182,11 @@
   bool requires_anonymized_data = (data_filtering == ANONYMIZE_DATA);
   config_impl->set_requires_anonymized_data(requires_anonymized_data);
 
-  // If the profile hasn't loaded or been created yet, this is a startup
-  // scenario and we have to wait until initialization is finished to validate
-  // that the scenario can run.
-  if (!delegate_ || delegate_->IsProfileLoaded()) {
-    // TODO(oysteine): Retry when time_until_allowed has elapsed.
-    if (config_impl && delegate_ &&
-        !delegate_->IsAllowedToBeginBackgroundScenario(
-            *config_impl.get(), requires_anonymized_data)) {
-      return false;
-    }
-  } else {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&BackgroundTracingManagerImpl::ValidateStartupScenario,
-                       base::Unretained(this)));
+  // TODO(oysteine): Retry when time_until_allowed has elapsed.
+  if (config_impl && delegate_ &&
+      !delegate_->IsAllowedToBeginBackgroundScenario(
+          *config_impl.get(), requires_anonymized_data)) {
+    return false;
   }
 
   active_scenario_ = std::make_unique<BackgroundTracingActiveScenario>(
@@ -369,19 +359,6 @@
   return BackgroundTracingConfig::FromDict(dict);
 }
 
-void BackgroundTracingManagerImpl::ValidateStartupScenario() {
-  if (!active_scenario_ || !delegate_) {
-    return;
-  }
-
-  if (!delegate_->IsAllowedToBeginBackgroundScenario(
-          *active_scenario_->GetConfig(),
-          active_scenario_->GetConfig()->requires_anonymized_data())) {
-    AbortScenario();
-  }
-}
-
-
 void BackgroundTracingManagerImpl::OnHistogramTrigger(
     const std::string& histogram_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h
index 708498a..4652744 100644
--- a/content/browser/tracing/background_tracing_manager_impl.h
+++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -157,7 +157,6 @@
   BackgroundTracingManagerImpl();
   ~BackgroundTracingManagerImpl() override;
 
-  void ValidateStartupScenario();
   bool IsSupportedConfig(BackgroundTracingConfigImpl* config);
   std::unique_ptr<base::DictionaryValue> GenerateMetadataDict();
   void GenerateMetadataProto(
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 908b203e..7895449 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -74,6 +74,7 @@
 #include "content/browser/media/media_web_contents_observer.h"
 #include "content/browser/media/session/media_session_impl.h"
 #include "content/browser/permissions/permission_controller_impl.h"
+#include "content/browser/permissions/permission_util.h"
 #include "content/browser/portal/portal.h"
 #include "content/browser/prerender/prerender_host_registry.h"
 #include "content/browser/renderer_host/agent_scheduling_group_host.h"
@@ -490,27 +491,13 @@
   auto* controller =
       PermissionControllerImpl::FromBrowserContext(host->GetBrowserContext());
 
-  // If the frame's URL is about:blank, its origin may have been inherited.
-  // Unfortunately, many PermissionControllerDelegate implementations of
-  // `GetPermissionStatusForFrame()` use `GetLastCommittedURL()` which does not
-  // consider origin inheritance. In case the URL is about:blank, manually check
-  // the permission status ourselves by deriving a GURL from the Origin.
-  // TODO(crbug.com/698985): Resolve GetLastCommitted[URL|Origin]() usage and
-  // remove this workaround without regressing crbug.com/1210669.
-  if (host->GetLastCommittedURL().IsAboutBlank()) {
-    return controller &&
-           controller->GetPermissionStatus(
-               PermissionType::WINDOW_PLACEMENT,
-               host->GetLastCommittedOrigin().GetURL(),
-               host->GetMainFrame()->GetLastCommittedOrigin().GetURL()) ==
-               blink::mojom::PermissionStatus::GRANTED;
-  }
-
   // TODO(crbug.com/698985): Resolve GetLastCommitted[URL|Origin]() usage.
-  return controller && controller->GetPermissionStatusForFrame(
-                           PermissionType::WINDOW_PLACEMENT, host,
-                           host->GetLastCommittedURL()) ==
-                           blink::mojom::PermissionStatus::GRANTED;
+  return controller &&
+         controller->GetPermissionStatusForFrame(
+             PermissionType::WINDOW_PLACEMENT, host,
+             PermissionUtil::GetLastCommittedOriginAsURL(
+                 content::WebContents::FromRenderFrameHost(host))) ==
+             blink::mojom::PermissionStatus::GRANTED;
 }
 
 // Adjust the requested |bounds| for opening or placing a window and return the
@@ -1034,6 +1021,11 @@
   ClearWebContentsAndroid();
 #endif
 
+  // |save_package_| is refcounted so make sure we clear the page before
+  // we toss out our reference.
+  if (save_package_)
+    save_package_->ClearPage();
+
   observers_.NotifyObservers(&WebContentsObserver::WebContentsDestroyed);
   if (display_cutout_host_impl_)
     display_cutout_host_impl_->WebContentsDestroyed();
@@ -4748,7 +4740,7 @@
   // Create the save package and possibly prompt the user for the name to save
   // the page as. The user prompt is an asynchronous operation that runs on
   // another thread.
-  save_package_ = new SavePackage(this);
+  save_package_ = new SavePackage(GetPrimaryPage());
   save_package_->GetSaveInfo();
 }
 
@@ -4763,7 +4755,8 @@
   // Stop the page from navigating.
   Stop();
 
-  save_package_ = new SavePackage(this, save_type, main_file, dir_path);
+  save_package_ =
+      new SavePackage(GetPrimaryPage(), save_type, main_file, dir_path);
   return save_package_->Init(SavePackageDownloadCreatedCallback());
 }
 
@@ -8902,6 +8895,12 @@
 void WebContentsImpl::NotifyPageChanged() {
   OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::PrimaryPageChanged");
 
+  // Clear |save_package_| since the primary page changed.
+  if (save_package_) {
+    save_package_->ClearPage();
+    save_package_.reset();
+  }
+
   observers_.NotifyObservers(&WebContentsObserver::PrimaryPageChanged);
 }
 
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc
index 8e5eca0..bb74220 100644
--- a/content/browser/web_contents/web_contents_view_android.cc
+++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -267,7 +267,7 @@
 
   // See if context menu is handled by SelectionController as a selection menu.
   // If not, use the delegate to show it.
-  if (rwhv && rwhv->ShowSelectionMenu(params))
+  if (rwhv && rwhv->ShowSelectionMenu(render_frame_host, params))
     return;
 
   if (delegate_)
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
index e597626e..ed1a4170 100644
--- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -53,6 +53,7 @@
 import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory;
 import org.chromium.content_public.browser.ActionModeCallbackHelper;
 import org.chromium.content_public.browser.ImeEventObserver;
+import org.chromium.content_public.browser.RenderFrameHost;
 import org.chromium.content_public.browser.SelectionClient;
 import org.chromium.content_public.browser.SelectionPopupController;
 import org.chromium.content_public.browser.WebContents;
@@ -118,6 +119,7 @@
     private WindowAndroid mWindowAndroid;
     private WebContentsImpl mWebContents;
     private ActionMode.Callback mCallback;
+    private RenderFrameHost mRenderFrameHost;
     private long mNativeSelectionPopupController;
 
     private SelectionClient.ResultCallback mResultCallback;
@@ -338,6 +340,11 @@
     }
 
     @Override
+    public RenderFrameHost getRenderFrameHost() {
+        return mRenderFrameHost;
+    }
+
+    @Override
     public void setNonSelectionActionModeCallback(ActionMode.Callback callback) {
         mNonSelectionCallback = callback;
     }
@@ -395,7 +402,8 @@
     public void showSelectionMenu(int left, int top, int right, int bottom, int handleHeight,
             boolean isEditable, boolean isPasswordType, String selectionText,
             int selectionStartOffset, boolean canSelectAll, boolean canRichlyEdit,
-            boolean shouldSuggest, @MenuSourceType int sourceType) {
+            boolean shouldSuggest, @MenuSourceType int sourceType,
+            RenderFrameHost renderFrameHost) {
         int offsetBottom = bottom;
         // Legacy action mode expects the selection rectangle not to include touch handle.
         if (supportsFloatingActionMode()) offsetBottom += handleHeight;
@@ -410,6 +418,8 @@
         mUnselectAllOnDismiss = true;
 
         if (hasSelection()) {
+            mRenderFrameHost = renderFrameHost;
+
             if (mSmartSelectionEventProcessor != null) {
                 switch (sourceType) {
                     case MenuSourceType.MENU_SOURCE_ADJUST_SELECTION:
@@ -597,6 +607,7 @@
     public void finishActionMode() {
         mHidden = false;
         mHandler.removeCallbacks(mRepeatingHideRunnable);
+        mRenderFrameHost = null;
 
         if (isActionModeValid()) {
             mActionMode.finish();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java
index 863a741..060a17e 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java
@@ -12,6 +12,8 @@
 import android.view.View;
 import android.webkit.WebSettings;
 
+import androidx.annotation.Nullable;
+
 import org.chromium.content.browser.selection.SelectionPopupControllerImpl;
 
 /**
@@ -89,6 +91,13 @@
     public abstract String getSelectedText();
 
     /**
+     * @return {@link RenderFrameHost} object only available during page selection,
+     *      if there is a valid ActionMode available.
+     */
+    @Nullable
+    public abstract RenderFrameHost getRenderFrameHost();
+
+    /**
      * Called when the processed text is replied from an activity that supports
      * Intent.ACTION_PROCESS_TEXT.
      * @param resultCode the code that indicates if the activity successfully processed the text
diff --git a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
index c292fda..a911aa1 100644
--- a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
+++ b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
@@ -52,6 +52,7 @@
 import org.chromium.content.browser.RenderCoordinatesImpl;
 import org.chromium.content.browser.RenderWidgetHostViewImpl;
 import org.chromium.content.browser.webcontents.WebContentsImpl;
+import org.chromium.content_public.browser.RenderFrameHost;
 import org.chromium.content_public.browser.SelectionClient;
 import org.chromium.content_public.browser.SelectionEventProcessor;
 import org.chromium.content_public.browser.SelectionPopupController;
@@ -87,6 +88,7 @@
     private PopupController mPopupController;
     private ContentClassFactory mOriginalContentClassFactory;
     private GestureListenerManagerImpl mGestureStateListenerManager;
+    private RenderFrameHost mRenderFrameHost;
 
     private static final String MOUNTAIN_FULL = "585 Franklin Street, Mountain View, CA 94041";
     private static final String MOUNTAIN = "Mountain";
@@ -155,6 +157,7 @@
         mActionMode = Mockito.mock(ActionMode.class);
         mPackageManager = Mockito.mock(PackageManager.class);
         mRenderWidgetHostViewImpl = Mockito.mock(RenderWidgetHostViewImpl.class);
+        mRenderFrameHost = Mockito.mock(RenderFrameHost.class);
         mRenderCoordinates = Mockito.mock(RenderCoordinatesImpl.class);
         mLogger = Mockito.mock(SmartSelectionEventProcessor.class);
         mPopupController = Mockito.mock(PopupController.class);
@@ -208,7 +211,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         // adjustSelectionByCharacterOffset() should be called.
         order.verify(mWebContents)
@@ -223,7 +226,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         order.verify(mView).startActionMode(
                 isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
@@ -254,7 +257,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         // adjustSelectionByCharacterOffset() should be called.
         order.verify(mWebContents)
@@ -267,7 +270,7 @@
                 /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
         order.verify(mWebContents)
                 .adjustSelectionByCharacterOffset(newResult.startAdjust, newResult.endAdjust, true);
         assertFalse(mController.isActionModeValid());
@@ -280,7 +283,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         SelectionClient.Result returnResult = mController.getClassificationResult();
         assertEquals(-21, returnResult.startAdjust);
@@ -292,7 +295,7 @@
                 /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         order.verify(mView).startActionMode(
                 isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
@@ -315,14 +318,14 @@
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         // Another long press triggered showSelectionMenu() call.
         mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         // Then we done with the first classification.
         mController.getResultCallback().onClassified(result);
@@ -345,7 +348,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         SelectionClient.Result returnResult = mController.getClassificationResult();
         assertEquals(-21, returnResult.startAdjust);
@@ -357,7 +360,7 @@
                 /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         order.verify(mView).startActionMode(
                 isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
@@ -382,7 +385,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
                 .thenReturn(mActionMode);
@@ -396,7 +399,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+                MenuSourceType.MENU_SOURCE_ADJUST_SELECTION, mRenderFrameHost);
 
         order.verify(mLogger).onSelectionModified(
                 eq(AMPHITHEATRE_FULL), eq(0), isA(SelectionClient.Result.class));
@@ -407,7 +410,7 @@
                 /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_TOUCH_HANDLE);
+                MenuSourceType.MENU_SOURCE_TOUCH_HANDLE, mRenderFrameHost);
 
         order.verify(mLogger, never())
                 .onSelectionModified(anyString(), anyInt(), any(SelectionClient.Result.class));
@@ -436,7 +439,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
                 .thenReturn(mActionMode);
@@ -453,7 +456,7 @@
                 /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_TOUCH_HANDLE);
+                MenuSourceType.MENU_SOURCE_TOUCH_HANDLE, mRenderFrameHost);
 
         order.verify(mLogger, never())
                 .onSelectionModified(anyString(), anyInt(), any(SelectionClient.Result.class));
@@ -593,7 +596,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         Mockito.verify(mView).startActionMode(
                 isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
@@ -630,7 +633,7 @@
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
-                MenuSourceType.MENU_SOURCE_LONG_PRESS);
+                MenuSourceType.MENU_SOURCE_LONG_PRESS, mRenderFrameHost);
 
         Mockito.verify(mView).startActionMode(
                 isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
diff --git a/content/public/browser/background_tracing_config.h b/content/public/browser/background_tracing_config.h
index 809f52f3..84032453f 100644
--- a/content/public/browser/background_tracing_config.h
+++ b/content/public/browser/background_tracing_config.h
@@ -31,11 +31,18 @@
   };
   TracingMode tracing_mode() const { return tracing_mode_; }
 
+  const std::string& scenario_name() const { return scenario_name_; }
+  bool has_crash_scenario() const { return has_crash_scenario_; }
+
   static std::unique_ptr<BackgroundTracingConfig> FromDict(
       const base::DictionaryValue* dict);
 
   virtual void IntoDict(base::DictionaryValue* dict) = 0;
 
+ protected:
+  std::string scenario_name_;
+  bool has_crash_scenario_ = false;
+
  private:
   friend class BackgroundTracingConfigImpl;
   explicit BackgroundTracingConfig(TracingMode tracing_mode);
diff --git a/content/public/browser/tracing_delegate.cc b/content/public/browser/tracing_delegate.cc
index f2231a5c..a1620c1 100644
--- a/content/public/browser/tracing_delegate.cc
+++ b/content/public/browser/tracing_delegate.cc
@@ -21,10 +21,6 @@
   return false;
 }
 
-bool TracingDelegate::IsProfileLoaded() {
-  return false;
-}
-
 bool TracingDelegate::IsSystemWideTracingEnabled() {
   return false;
 }
diff --git a/content/public/browser/tracing_delegate.h b/content/public/browser/tracing_delegate.h
index c4ddfdd..23d732f 100644
--- a/content/public/browser/tracing_delegate.h
+++ b/content/public/browser/tracing_delegate.h
@@ -42,8 +42,6 @@
       bool requires_anonymized_data,
       bool is_crash_scenario);
 
-  virtual bool IsProfileLoaded();
-
   // Whether system-wide performance trace collection using the external system
   // tracing service is enabled.
   virtual bool IsSystemWideTracingEnabled();
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 530a3138..f80399a 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -119,6 +119,13 @@
 const base::Feature kBlockInsecurePrivateNetworkRequests{
     "BlockInsecurePrivateNetworkRequests", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables use of the PrivateNetworkAccessNonSecureContextsAllowed deprecation
+// trial. This is a necessary yet insufficient condition: documents that wish to
+// make use of the trial must additionally serve a valid origin trial token.
+const base::Feature kBlockInsecurePrivateNetworkRequestsDeprecationTrial{
+    "BlockInsecurePrivateNetworkRequestsDeprecationTrial",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 // When both kBlockInsecurePrivateNetworkRequestsForNavigations and
 // kBlockInsecurePrivateNetworkRequests are enabled, navigations initiated
 // by documents in a less-private network may only target a more-private network
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index e8baeec..80840a56 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -33,6 +33,8 @@
 CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources;
 CONTENT_EXPORT extern const base::Feature kBlockInsecurePrivateNetworkRequests;
 CONTENT_EXPORT extern const base::Feature
+    kBlockInsecurePrivateNetworkRequestsDeprecationTrial;
+CONTENT_EXPORT extern const base::Feature
     kBlockInsecurePrivateNetworkRequestsForNavigations;
 CONTENT_EXPORT extern const base::Feature kBrowserUseDisplayThreadPriority;
 CONTENT_EXPORT extern const base::Feature
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 932acff..bf0799bf 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -931,12 +931,6 @@
 // Disable Media Session API
 const char kDisableMediaSessionAPI[] = "disable-media-session-api";
 
-// Disable overscroll edge effects like those found in Android views.
-const char kDisableOverscrollEdgeEffect[]   = "disable-overscroll-edge-effect";
-
-// Disable the pull-to-refresh effect when vertically overscrolling content.
-const char kDisablePullToRefreshEffect[]   = "disable-pull-to-refresh-effect";
-
 // Disable the locking feature of the screen orientation API.
 const char kDisableScreenOrientationLock[]  = "disable-screen-orientation-lock";
 
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 693cf12..b960b6e 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -255,8 +255,6 @@
 #if defined(OS_ANDROID)
 CONTENT_EXPORT extern const char kDisableMediaSessionAPI[];
 CONTENT_EXPORT extern const char kDisableOoprDebugCrashDump[];
-CONTENT_EXPORT extern const char kDisableOverscrollEdgeEffect[];
-CONTENT_EXPORT extern const char kDisablePullToRefreshEffect[];
 CONTENT_EXPORT extern const char kDisableScreenOrientationLock[];
 CONTENT_EXPORT extern const char kDisableSiteIsolationForPolicy[];
 CONTENT_EXPORT extern const char kDisableTimeoutsForProfiling[];
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index a1497c3..1b6f66d 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1377,9 +1377,17 @@
                                    const std::string& script, double* result) {
   DCHECK(result);
   std::unique_ptr<base::Value> value;
-  return ExecuteScriptHelper(adapter.render_frame_host(), script, true,
-                             ISOLATED_WORLD_ID_GLOBAL, &value) &&
-         value && value->GetAsDouble(result);
+  if (!ExecuteScriptHelper(adapter.render_frame_host(), script, true,
+                           ISOLATED_WORLD_ID_GLOBAL, &value))
+    return false;
+  if (!value)
+    return false;
+  absl::optional<double> maybe_value = value->GetIfDouble();
+  if (!maybe_value.has_value())
+    return false;
+
+  *result = maybe_value.value();
+  return true;
 }
 
 bool ExecuteScriptAndExtractInt(const ToRenderFrameHost& adapter,
diff --git a/content/public/test/test_aggregation_service.cc b/content/public/test/test_aggregation_service.cc
new file mode 100644
index 0000000..3f3cc1e4
--- /dev/null
+++ b/content/public/test/test_aggregation_service.cc
@@ -0,0 +1,15 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/test/test_aggregation_service.h"
+
+#include "content/test/test_aggregation_service_impl.h"
+
+namespace content {
+
+std::unique_ptr<TestAggregationService> TestAggregationService::Create() {
+  return std::make_unique<TestAggregationServiceImpl>();
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/public/test/test_aggregation_service.h b/content/public/test/test_aggregation_service.h
new file mode 100644
index 0000000..3018340
--- /dev/null
+++ b/content/public/test/test_aggregation_service.h
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_TEST_TEST_AGGREGATION_SERVICE_H_
+#define CONTENT_PUBLIC_TEST_TEST_AGGREGATION_SERVICE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "url/origin.h"
+
+namespace content {
+
+// Interface for a test aggregation service which can be created without any
+// dependencies. Supports configuring public keys at runtime.
+class TestAggregationService {
+ public:
+  virtual ~TestAggregationService() = default;
+
+  // Creates an instance of the service.
+  static std::unique_ptr<TestAggregationService> Create();
+
+  // Parses the keys for `origin` from `json_string`, and saves the set of keys
+  // to storage. `callback` will be run once completed which takes a boolean
+  // value indicating whether the keys were parsed successfully.
+  virtual void SetPublicKeys(const url::Origin& origin,
+                             const std::string& json_string,
+                             base::OnceCallback<void(bool)> callback) = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_TEST_TEST_AGGREGATION_SERVICE_H_
\ No newline at end of file
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 4652ba5e..50973ec 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4452,20 +4452,6 @@
                                    .user_agent_override.ua_string_override);
   }
 
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // TODO(https://crbug.com/1114866): Implement proper L3 CDM support for
-  // Lacros. This is scheduled for Q2 2021. After that we can remove this hack.
-  WebSecurityOrigin frame_origin = frame_->GetDocument().GetSecurityOrigin();
-  if (frame_origin.Host().Utf8() == "www.netflix.com") {
-    WebString user_agent = RenderThreadImpl::current()->GetUserAgent();
-    std::string user_agent_utf8 =
-        user_agent.Utf8(WebString::UTF8ConversionMode::kStrict);
-    base::ReplaceSubstringsAfterOffset(&user_agent_utf8, /*start_offset=*/0,
-                                       " CrOS ", " Linux ");
-    return WebString::FromUTF8(user_agent_utf8);
-  }
-#endif
-
   return blink::WebString();
 }
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 0bc7245..95ab5d2 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -150,6 +150,7 @@
 #include "ui/base/layout.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/base/ui_base_switches_util.h"
 #include "ui/display/display_switches.h"
 #include "ui/gfx/rendering_pipeline.h"
 
@@ -627,21 +628,7 @@
   is_threaded_animation_enabled_ =
       !command_line.HasSwitch(cc::switches::kDisableThreadedAnimation);
 
-// On macOS this value is adjusted in `UpdateScrollbarTheme()`,
-// but the system default is true.
-#if defined(OS_MAC)
-  is_elastic_overscroll_enabled_ = true;
-#elif defined(OS_WIN)
-  is_elastic_overscroll_enabled_ =
-      base::FeatureList::IsEnabled(features::kElasticOverscroll);
-#elif defined(OS_ANDROID)
-  is_elastic_overscroll_enabled_ =
-      !base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisableOverscrollEdgeEffect) &&
-      base::FeatureList::IsEnabled(features::kElasticOverscroll);
-#else
-  is_elastic_overscroll_enabled_ = false;
-#endif
+  is_elastic_overscroll_enabled_ = switches::IsElasticOverscrollEnabled();
 
   is_zoom_for_dsf_enabled_ = content::IsUseZoomForDSFEnabled();
 
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 695fe82..586f914 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -367,6 +367,13 @@
     deps += [ "//chromeos/dbus" ]
   }
 
+  if (is_chromeos_lacros) {
+    deps += [
+      "//chromeos/dbus/constants",
+      "//chromeos/lacros",
+    ]
+  }
+
   if (is_linux || is_chromeos) {
     deps += [ "//build/config/freetype" ]
   }
diff --git a/content/shell/browser/DEPS b/content/shell/browser/DEPS
index f3e53bc2..1a83b0ee 100644
--- a/content/shell/browser/DEPS
+++ b/content/shell/browser/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+chromeos/lacros",
   "+components/keyed_service/content",
   "+components/metrics",
   "+components/network_session_configurator/common",
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc
index 0ff0f840..97559e3 100644
--- a/content/shell/browser/shell_browser_main_parts.cc
+++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -51,15 +51,19 @@
 #if defined(USE_OZONE) || defined(USE_X11)
 #include "ui/base/ui_base_features.h"
 #endif
+
 #if defined(USE_X11)
 #include "ui/base/x/x11_util.h"  // nogncheck
 #endif
+
 #if defined(USE_AURA) && defined(USE_X11)
 #include "ui/events/devices/x11/touch_factory_x11.h"  // nogncheck
 #endif
+
 #if defined(USE_AURA) && (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 #include "ui/base/ime/init/input_method_initializer.h"
 #endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
@@ -67,6 +71,10 @@
 #include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
 #endif  // #elif (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#endif
+
 #if BUILDFLAG(USE_GTK)
 #include "ui/gtk/gtk_ui_factory.h"
 #include "ui/views/linux_ui/linux_ui.h"  // nogncheck
@@ -134,6 +142,9 @@
 #elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
   bluez::DBusBluezManagerWrapperLinux::Initialize();
 #endif
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  chromeos::LacrosDBusThreadManager::Initialize();
+#endif
 }
 
 int ShellBrowserMainParts::PreEarlyInitialization() {
@@ -225,6 +236,9 @@
 }
 
 void ShellBrowserMainParts::PostDestroyThreads() {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  chromeos::LacrosDBusThreadManager::Shutdown();
+#endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   device::BluetoothAdapterFactory::Shutdown();
   bluez::BluezDBusManager::Shutdown();
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index d7fbed42..37ae87c7 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -44,6 +44,8 @@
   sources = [
     "../browser/accessibility/test_browser_accessibility_delegate.cc",
     "../browser/accessibility/test_browser_accessibility_delegate.h",
+    "../browser/aggregation_service/aggregation_service_test_utils.cc",
+    "../browser/aggregation_service/aggregation_service_test_utils.h",
     "../browser/background_fetch/background_fetch_test_base.cc",
     "../browser/background_fetch/background_fetch_test_base.h",
     "../browser/background_fetch/background_fetch_test_browser_context.cc",
@@ -221,6 +223,8 @@
     "../public/test/slow_download_http_response.h",
     "../public/test/slow_http_response.cc",
     "../public/test/slow_http_response.h",
+    "../public/test/test_aggregation_service.cc",
+    "../public/test/test_aggregation_service.h",
     "../public/test/test_browser_context.cc",
     "../public/test/test_browser_context.h",
     "../public/test/test_content_client_initializer.cc",
@@ -346,6 +350,8 @@
     "stub_render_widget_host_owner_delegate.h",
     "task_runner_deferring_throttle.cc",
     "task_runner_deferring_throttle.h",
+    "test_aggregation_service_impl.cc",
+    "test_aggregation_service_impl.h",
     "test_background_sync_context.cc",
     "test_background_sync_context.h",
     "test_background_sync_manager.cc",
@@ -1823,6 +1829,8 @@
     "../browser/accessibility/browser_accessibility_unittest.cc",
     "../browser/accessibility/one_shot_accessibility_tree_search_unittest.cc",
     "../browser/accessibility/touch_passthrough_manager_unittest.cc",
+    "../browser/aggregation_service/aggregation_service_storage_unittest.cc",
+    "../browser/aggregation_service/public_key_parsing_utils_unittest.cc",
     "../browser/appcache/appcache_cache_test_helper.cc",
     "../browser/appcache/appcache_cache_test_helper.h",
     "../browser/appcache/appcache_cache_test_helper_unittest.cc",
@@ -2247,6 +2255,7 @@
     "../renderer/v8_value_converter_impl_unittest.cc",
     "../renderer/worker/worker_thread_registry_unittest.cc",
     "navigation_simulator_unittest.cc",
+    "test_aggregation_service_impl_unittest.cc",
     "test_render_frame_host_unittest.cc",
   ]
 
diff --git a/content/test/data/accessibility/html/video-text-only-expected-blink.txt b/content/test/data/accessibility/html/video-text-only-expected-blink.txt
deleted file mode 100644
index c38319c..0000000
--- a/content/test/data/accessibility/html/video-text-only-expected-blink.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-rootWebArea
-++genericContainer ignored
-++++genericContainer
-++++++video name='Unable to play media.' restriction=disabled
-++++++++genericContainer ignored
-++++++++++genericContainer ignored
-++++++++++genericContainer ignored
-++++++++++menu ignored invisible
-++++++++++menu ignored invisible
-++++++++++menu ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++staticText name=' '
-++++++++inlineTextBox name=' '
-++++++video name='Unable to play media.' restriction=disabled
-++++++++genericContainer ignored
-++++++++++genericContainer ignored
-++++++++++genericContainer ignored
-++++++++++menu ignored invisible
-++++++++++menu ignored invisible
-++++++++++menu ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
-++++++++++++button ignored invisible
-++++++++++++genericContainer ignored invisible
diff --git a/content/test/data/accessibility/html/video-text-only-expected-mac.txt b/content/test/data/accessibility/html/video-text-only-expected-mac.txt
new file mode 100644
index 0000000..2746f3fb
--- /dev/null
+++ b/content/test/data/accessibility/html/video-text-only-expected-mac.txt
@@ -0,0 +1,5 @@
+AXWebArea
+++AXGroup
+++++AXGroup AXDescription='Unable to play media.'
+++++AXStaticText AXValue=' '
+++++AXGroup AXDescription='Unable to play media.'
diff --git a/content/test/data/accessibility/html/video-text-only-expected-uia-win.txt b/content/test/data/accessibility/html/video-text-only-expected-uia-win.txt
new file mode 100644
index 0000000..3b0c535
--- /dev/null
+++ b/content/test/data/accessibility/html/video-text-only-expected-uia-win.txt
@@ -0,0 +1,5 @@
+Document
+++Group IsControlElement=false
+++++Group Name='Unable to play media.' IsEnabled=false
+++++Text Name=' '
+++++Group Name='Unable to play media.' IsEnabled=false
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/video-text-only-expected-win.txt b/content/test/data/accessibility/html/video-text-only-expected-win.txt
new file mode 100644
index 0000000..1ef7acc
--- /dev/null
+++ b/content/test/data/accessibility/html/video-text-only-expected-win.txt
@@ -0,0 +1,5 @@
+ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
+++IA2_ROLE_SECTION
+++++ROLE_SYSTEM_GROUPING name='Unable to play media.' UNAVAILABLE
+++++ROLE_SYSTEM_STATICTEXT name=' '
+++++ROLE_SYSTEM_GROUPING name='Unable to play media.' UNAVAILABLE
\ No newline at end of file
diff --git a/content/test/fuzzer/browser_accessibility_fuzzer.cc b/content/test/fuzzer/browser_accessibility_fuzzer.cc
index 54c8c66..e9913d3 100644
--- a/content/test/fuzzer/browser_accessibility_fuzzer.cc
+++ b/content/test/fuzzer/browser_accessibility_fuzzer.cc
@@ -10,9 +10,11 @@
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/accessibility/one_shot_accessibility_tree_search.h"
 #include "content/browser/accessibility/test_browser_accessibility_delegate.h"
+#include "content/public/test/browser_task_environment.h"
 
 struct Env {
   Env() { base::CommandLine::Init(0, nullptr); }
+  content::BrowserTaskEnvironment task_environment;
   base::AtExitManager at_exit;
 };
 
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
index 92c69cb7..03f604d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -83,7 +83,7 @@
 # Flaking on Nexus 5X
 crbug.com/965268 [ android android-nexus-5x ] ContextLost_WebGLBlockedAfterJSNavigation [ Skip ]
 crbug.com/965268 [ android android-nexus-5x ] ContextLost_WebGLUnblockedAfterUserInitiatedReload [ Skip ]
-crbug.com/880078 [ android android-nexus-5x ] ContextLost_WorkerRAFAfterGPUCrash [ RetryOnFailure ]
+crbug.com/1210594 [ android android-nexus-5x ] ContextLost_WorkerRAFAfterGPUCrash [ Skip ]
 crbug.com/1064853 [ android android-nexus-5x ] ContextLost_WebGLContextLostFromSelectElement [ Skip ]
 
 # Nexus 6
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 0ad3f30..420cdfe 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -482,6 +482,10 @@
 
 # Mac / Passthrough command decoder / Metal
 crbug.com/angleproject/4846 [ mac angle-metal passthrough ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ]
+crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/extensions/webgl-debug-shaders.html [ Failure ]
+crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/ogles/GL/acos/acos_001_to_006.html [ Failure ]
+crbug.com/angleproject/5505 [ mac angle-metal passthrough ] conformance/ogles/GL/asin/asin_001_to_006.html [ Failure ]
+crbug.com/1227129 [ mac angle-metal passthrough ] conformance/glsl/misc/ternary-operators-in-initializers.html [ Failure ]
 
 # Mac / Passthrough command decoder / Metal / Intel
 crbug.com/1144258 [ mac angle-metal passthrough intel-0x3e9b ] conformance/glsl/functions/glsl-function-atan-xy.html [ Failure ]
@@ -797,23 +801,16 @@
 crbug.com/1114284 [ linux angle-swiftshader passthrough google-0xffff ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ RetryOnFailure ]
 crbug.com/1114284 [ mac angle-swiftshader passthrough google-0xffff ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ RetryOnFailure ]
 
-# Mac. All backends.
-crbug.com/1099960 [ mac angle-swiftshader passthrough ] conformance/context/context-no-alpha-fbo-with-alpha.html [ Failure ]
-crbug.com/1099960 [ mac angle-swiftshader passthrough ] conformance/rendering/color-mask-preserved-during-implicit-clears.html [ Failure ]
-crbug.com/1099960 [ mac angle-swiftshader passthrough ] conformance/rendering/scissor-rect-repeated-rendering.html [ Failure ]
+# Mac. GL backend.
+crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ]
+crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/glsl/bugs/sampler-array-struct-function-arg.html [ Failure ]
 crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/context/context-no-alpha-fbo-with-alpha.html [ Failure ]
 crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/rendering/color-mask-preserved-during-implicit-clears.html [ Failure ]
 crbug.com/1099960 [ mac swiftshader-gl no-passthrough ] conformance/rendering/scissor-rect-repeated-rendering.html [ Failure ]
 
-# Mac. GL backend.
-crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/context/context-attribute-preserve-drawing-buffer.html [ Failure ]
-crbug.com/1099977 [ mac swiftshader-gl no-passthrough ] conformance/glsl/bugs/sampler-array-struct-function-arg.html [ Failure ]
-
 # Mac. Vulkan backend.
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/canvas/canvas-test.html [ Failure ]
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/canvas/webgl-to-2d-canvas.html [ Failure ]
-crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
-crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/context/context-hidden-alpha.html [ Failure ]
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/context/premultiplyalpha-test.html [ Failure ]
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/extensions/oes-texture-float-with-canvas.html [ Failure ]
 crbug.com/1099978 [ mac angle-swiftshader passthrough ] conformance/extensions/oes-texture-float-with-video.html [ Failure ]
@@ -852,7 +849,6 @@
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ Failure ]
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Failure ]
 crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
-crbug.com/1099979 [ mac angle-swiftshader passthrough ] conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Failure ]
 
 crbug.com/1134756 [ mac angle-swiftshader passthrough ] conformance/textures/misc/copy-tex-image-2d-formats.html [ Failure ]
 crbug.com/1134756 [ mac angle-swiftshader passthrough ] conformance/misc/uninitialized-test.html [ Failure ]
diff --git a/content/test/test_aggregation_service_impl.cc b/content/test/test_aggregation_service_impl.cc
new file mode 100644
index 0000000..4ae5b5f
--- /dev/null
+++ b/content/test/test_aggregation_service_impl.cc
@@ -0,0 +1,61 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/test/test_aggregation_service_impl.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/logging.h"
+#include "base/task/thread_pool.h"
+#include "content/browser/aggregation_service/aggregation_service_storage.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/browser/aggregation_service/public_key_parsing_utils.h"
+
+namespace content {
+
+TestAggregationServiceImpl::TestAggregationServiceImpl()
+    : storage_(base::SequenceBound<AggregationServiceStorage>(
+          base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))) {}
+
+TestAggregationServiceImpl::~TestAggregationServiceImpl() = default;
+
+const base::SequenceBound<AggregationServiceKeyStorage>&
+TestAggregationServiceImpl::GetKeyStorage() {
+  return storage_;
+}
+
+void TestAggregationServiceImpl::SetPublicKeys(
+    const url::Origin& origin,
+    const std::string& json_string,
+    base::OnceCallback<void(bool)> callback) {
+  JSONStringValueDeserializer deserializer(json_string);
+  std::string error_message;
+  std::unique_ptr<base::Value> value_ptr =
+      deserializer.Deserialize(nullptr, &error_message);
+  if (!value_ptr) {
+    LOG(ERROR) << "Unable to deserialze json string: " << json_string
+               << ", error: " << error_message;
+    std::move(callback).Run(false);
+    return;
+  }
+
+  content::PublicKeysForOrigin keys(
+      origin, content::aggregation_service::GetPublicKeys(*value_ptr));
+  storage_.AsyncCall(&AggregationServiceKeyStorage::SetPublicKeys)
+      .WithArgs(std::move(keys))
+      .Then(base::BindOnce(std::move(callback), true));
+}
+
+void TestAggregationServiceImpl::GetPublicKeys(
+    const url::Origin& origin,
+    base::OnceCallback<void(PublicKeysForOrigin)> callback) const {
+  storage_.AsyncCall(&AggregationServiceKeyStorage::GetPublicKeys)
+      .WithArgs(origin)
+      .Then(std::move(callback));
+}
+
+}  // namespace content
\ No newline at end of file
diff --git a/content/test/test_aggregation_service_impl.h b/content/test/test_aggregation_service_impl.h
new file mode 100644
index 0000000..927afe01
--- /dev/null
+++ b/content/test/test_aggregation_service_impl.h
@@ -0,0 +1,47 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_TEST_TEST_AGGREGATION_SERVICE_IMPL_H_
+#define CONTENT_TEST_TEST_AGGREGATION_SERVICE_IMPL_H_
+
+#include "base/callback.h"
+#include "base/threading/sequence_bound.h"
+#include "content/browser/aggregation_service/aggregatable_report_manager.h"
+#include "content/browser/aggregation_service/aggregation_service_key_storage.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/public/test/test_aggregation_service.h"
+#include "url/origin.h"
+
+namespace content {
+
+// Implementation class of a test aggregation service.
+class TestAggregationServiceImpl : public AggregatableReportManager,
+                                   public TestAggregationService {
+ public:
+  TestAggregationServiceImpl();
+  TestAggregationServiceImpl(const TestAggregationServiceImpl& other) = delete;
+  TestAggregationServiceImpl& operator=(
+      const TestAggregationServiceImpl& other) = delete;
+  ~TestAggregationServiceImpl() override;
+
+  // AggregatableReportManager:
+  const base::SequenceBound<AggregationServiceKeyStorage>& GetKeyStorage()
+      override;
+
+  // TestAggregationService:
+  void SetPublicKeys(const url::Origin& origin,
+                     const std::string& json_string,
+                     base::OnceCallback<void(bool)> callback) override;
+
+  void GetPublicKeys(
+      const url::Origin& origin,
+      base::OnceCallback<void(PublicKeysForOrigin)> callback) const;
+
+ private:
+  base::SequenceBound<AggregationServiceKeyStorage> storage_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_TEST_TEST_AGGREGATION_SERVICE_IMPL_H_
\ No newline at end of file
diff --git a/content/test/test_aggregation_service_impl_unittest.cc b/content/test/test_aggregation_service_impl_unittest.cc
new file mode 100644
index 0000000..8e56d19
--- /dev/null
+++ b/content/test/test_aggregation_service_impl_unittest.cc
@@ -0,0 +1,69 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/test/test_aggregation_service_impl.h"
+
+#include <memory>
+#include <string>
+
+#include "base/run_loop.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+class TestAggregationServiceImplTest : public testing::Test {
+ public:
+  TestAggregationServiceImplTest()
+      : impl_(std::make_unique<TestAggregationServiceImpl>()) {}
+
+ protected:
+  base::test::TaskEnvironment task_environment_;
+  std::unique_ptr<TestAggregationServiceImpl> impl_;
+};
+
+TEST_F(TestAggregationServiceImplTest, SetPublicKeys) {
+  std::string json_string = R"(
+        {
+            "1.0" : [
+                {
+                    "id" : "abcd",
+                    "key" : "defg",
+                    "not_before": "1623000000000",
+                    "not_after" : "1624000000000"
+                }
+            ]
+        }
+    )";
+
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+
+  base::RunLoop set_loop;
+  impl_->SetPublicKeys(origin, json_string,
+                       base::BindLambdaForTesting([&](bool succeeded) {
+                         EXPECT_TRUE(succeeded);
+                         set_loop.Quit();
+                       }));
+  set_loop.Run();
+
+  base::RunLoop get_loop;
+  impl_->GetPublicKeys(
+      origin, base::BindLambdaForTesting([&](PublicKeysForOrigin keys) {
+        EXPECT_TRUE(content::aggregation_service::PublicKeysEqual(
+            {content::PublicKey("abcd", "defg",
+                                base::Time::FromJavaTime(1623000000000),
+                                base::Time::FromJavaTime(1624000000000))},
+            keys.keys));
+        get_loop.Quit();
+      }));
+  get_loop.Run();
+}
+
+}  // namespace content
diff --git a/courgette/encoded_program_unittest.cc b/courgette/encoded_program_unittest.cc
index d394724..39061b4 100644
--- a/courgette/encoded_program_unittest.cc
+++ b/courgette/encoded_program_unittest.cc
@@ -10,7 +10,7 @@
 #include <memory>
 #include <vector>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "courgette/image_utils.h"
 #include "courgette/label_manager.h"
 #include "courgette/streams.h"
diff --git a/courgette/memory_allocator_unittest.cc b/courgette/memory_allocator_unittest.cc
index c861c36..bb922c0b 100644
--- a/courgette/memory_allocator_unittest.cc
+++ b/courgette/memory_allocator_unittest.cc
@@ -8,7 +8,7 @@
 
 #include <algorithm>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(MemoryAllocatorTest, NoThrowBuffer) {
diff --git a/courgette/third_party/bsdiff/bsdiff_search_unittest.cc b/courgette/third_party/bsdiff/bsdiff_search_unittest.cc
index 2ea8ffd1b..0ab2d28 100644
--- a/courgette/third_party/bsdiff/bsdiff_search_unittest.cc
+++ b/courgette/third_party/bsdiff/bsdiff_search_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <cstring>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "courgette/third_party/bsdiff/paged_array.h"
 #include "courgette/third_party/divsufsort/divsufsort.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/crypto/ec_private_key_unittest.cc b/crypto/ec_private_key_unittest.cc
index c4662d09..20249aac 100644
--- a/crypto/ec_private_key_unittest.cc
+++ b/crypto/ec_private_key_unittest.cc
@@ -9,7 +9,7 @@
 #include <memory>
 #include <vector>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
diff --git a/crypto/encryptor_unittest.cc b/crypto/encryptor_unittest.cc
index b4785cabe..95c9cc5 100644
--- a/crypto/encryptor_unittest.cc
+++ b/crypto/encryptor_unittest.cc
@@ -9,7 +9,7 @@
 #include <memory>
 #include <string>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "crypto/symmetric_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/crypto/hmac_unittest.cc b/crypto/hmac_unittest.cc
index 7e81f0a..783aaf1 100644
--- a/crypto/hmac_unittest.cc
+++ b/crypto/hmac_unittest.cc
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "crypto/hmac.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/crypto/mock_apple_keychain.cc b/crypto/mock_apple_keychain.cc
index 7cf93738..f67b397 100644
--- a/crypto/mock_apple_keychain.cc
+++ b/crypto/mock_apple_keychain.cc
@@ -5,8 +5,8 @@
 #include "crypto/mock_apple_keychain.h"
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 
 namespace {
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index bc4333f..ea37b9ae 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -11,10 +11,10 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/cxx17_backports.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/thread.h"
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc
index 0efdd60..2ac3e80 100644
--- a/dbus/property_unittest.cc
+++ b/dbus/property_unittest.cc
@@ -12,9 +12,9 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread.h"
diff --git a/dbus/values_util_unittest.cc b/dbus/values_util_unittest.cc
index 16dcd16..fd8bf35 100644
--- a/dbus/values_util_unittest.cc
+++ b/dbus/values_util_unittest.cc
@@ -12,8 +12,8 @@
 #include <utility>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/json/json_writer.h"
-#include "base/stl_util.h"
 #include "base/values.h"
 #include "dbus/message.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/device/gamepad/gamepad_device_mac.mm b/device/gamepad/gamepad_device_mac.mm
index 1651ba3..3353cfd 100644
--- a/device/gamepad/gamepad_device_mac.mm
+++ b/device/gamepad/gamepad_device_mac.mm
@@ -6,9 +6,9 @@
 
 #import <Foundation/Foundation.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "device/gamepad/dualshock4_controller.h"
 #include "device/gamepad/gamepad_data_fetcher.h"
diff --git a/device/gamepad/public/cpp/gamepad.cc b/device/gamepad/public/cpp/gamepad.cc
index 687b2b7..ffcfbfb5 100644
--- a/device/gamepad/public/cpp/gamepad.cc
+++ b/device/gamepad/public/cpp/gamepad.cc
@@ -26,6 +26,8 @@
 
 Gamepad::Gamepad(const Gamepad& other) = default;
 
+Gamepad& Gamepad::operator=(const Gamepad& other) = default;
+
 void Gamepad::SetID(const std::u16string& src) {
   memset(id, 0, sizeof(id));
   src.copy(id, kIdLengthCap - 1);
diff --git a/device/gamepad/public/cpp/gamepad.h b/device/gamepad/public/cpp/gamepad.h
index ab0a699..720c9e3 100644
--- a/device/gamepad/public/cpp/gamepad.h
+++ b/device/gamepad/public/cpp/gamepad.h
@@ -114,6 +114,7 @@
 
   Gamepad();
   Gamepad(const Gamepad& other);
+  Gamepad& operator=(const Gamepad& other);
 
   // If src is too long, then the contents of id will be truncated to
   // kIdLengthCap-1. id will be null-terminated and any extra space in the
diff --git a/device/vr/android/arcore/arcore_device.cc b/device/vr/android/arcore/arcore_device.cc
index 31ffb87..e7c2150 100644
--- a/device/vr/android/arcore/arcore_device.cc
+++ b/device/vr/android/arcore/arcore_device.cc
@@ -61,7 +61,7 @@
 
 const std::vector<mojom::XRSessionFeature>& GetSupportedFeatures() {
   static base::NoDestructor<std::vector<mojom::XRSessionFeature>>
-      kSupportedFeatures({
+      kSupportedFeatures{{
     mojom::XRSessionFeature::REF_SPACE_VIEWER,
     mojom::XRSessionFeature::REF_SPACE_LOCAL,
     mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR,
@@ -72,7 +72,7 @@
     mojom::XRSessionFeature::PLANE_DETECTION,
     mojom::XRSessionFeature::DEPTH,
     mojom::XRSessionFeature::IMAGE_TRACKING
-  });
+  }};
 
   return *kSupportedFeatures;
 }
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc
index 9108df8..1c4250d 100644
--- a/device/vr/android/gvr/gvr_device.cc
+++ b/device/vr/android/gvr/gvr_device.cc
@@ -115,11 +115,11 @@
 
 const std::vector<mojom::XRSessionFeature>& GetSupportedFeatures() {
   static base::NoDestructor<std::vector<mojom::XRSessionFeature>>
-      kSupportedFeatures({
+      kSupportedFeatures{{
     mojom::XRSessionFeature::REF_SPACE_VIEWER,
     mojom::XRSessionFeature::REF_SPACE_LOCAL,
     mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR,
-  });
+  }};
 
   return *kSupportedFeatures;
 }
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc
index 70ae0e15..4447dc9a 100644
--- a/device/vr/openxr/openxr_device.cc
+++ b/device/vr/openxr/openxr_device.cc
@@ -57,14 +57,14 @@
 
 const std::vector<mojom::XRSessionFeature>& GetSupportedFeatures() {
   static base::NoDestructor<std::vector<mojom::XRSessionFeature>>
-      kSupportedFeatures({
+      kSupportedFeatures{{
     mojom::XRSessionFeature::REF_SPACE_VIEWER,
     mojom::XRSessionFeature::REF_SPACE_LOCAL,
     mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR,
     mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR,
     mojom::XRSessionFeature::REF_SPACE_UNBOUNDED,
     mojom::XRSessionFeature::ANCHORS,
-  });
+  }};
 
   return *kSupportedFeatures;
 }
diff --git a/device/vr/openxr/test/openxr_test_helper.h b/device/vr/openxr/test/openxr_test_helper.h
index 69078097c..f89f1da 100644
--- a/device/vr/openxr/test/openxr_test_helper.h
+++ b/device/vr/openxr/test/openxr_test_helper.h
@@ -14,7 +14,7 @@
 #include <unordered_set>
 #include <vector>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/synchronization/lock.h"
 #include "device/vr/openxr/openxr_defs.h"
 #include "device/vr/test/test_hook.h"
diff --git a/docs/speed/how_does_chrome_measure_performance.md b/docs/speed/how_does_chrome_measure_performance.md
index c9ae3b0b..09b9cf4 100644
--- a/docs/speed/how_does_chrome_measure_performance.md
+++ b/docs/speed/how_does_chrome_measure_performance.md
@@ -63,7 +63,9 @@
 The **[Speed Launch Metrics](https://docs.google.com/document/d/1Ww487ZskJ-xBmJGwPO-XPz_QcJvw-kSNffm0nPhVpj8/edit)**
 doc explains metrics available in UMA for end user performance. If you want to
 test how your change impacts these metrics for end users, you'll probably want
-to **[Run a Finch Trial](http://goto.google.com/finch101)**.
+to **[Run a Finch Trial (Googlers only)](http://goto.google.com/finch101)**. If
+you want to run a trial and are not a Googler, you'll need a Google-internal partner
+to help you run it.
 
 The **[UMA Sampling Profiler (Googlers only)](http://goto.google.com/uma-sampling-profiler-overview)**
 measures Chrome execution using statistical profiling, producing aggregate
diff --git a/docs/webui_in_chrome.md b/docs/webui_in_chrome.md
index 71ca188..b9b8dc9 100644
--- a/docs/webui_in_chrome.md
+++ b/docs/webui_in_chrome.md
@@ -247,8 +247,8 @@
 ```
 
 ## Add an entry to resource_ids.spec
-This file is for automatically generating resource ids. Ensure that the previous
-entry number plus the size equals the next entry number.
+This file is for automatically generating resource ids. Ensure that your entry
+has a unique ID and preserves numerical ordering.
 
 `tools/gritsettings/resource_ids.spec`
 
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index 6171cbea..4916968 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -149,23 +149,31 @@
     "//base",
     "//build:chromeos_buildflags",
     "//chrome/common:buildflags",
+    "//components/crx_file",
     "//components/guest_view/browser:test_support",
+    "//components/keyed_service/content",
     "//components/prefs:test_support",
+    "//components/pref_registry",
     "//components/sync_preferences:test_support",
+    "//components/update_client",
+    "//components/user_prefs",
     "//content/public/common",
     "//content/test:test_support",
     "//extensions/browser",
     "//extensions/browser:test_support",
     "//extensions/browser/api",
+    "//extensions/browser/updater",
     "//extensions/common",
     "//extensions/common:core_api_provider",
     "//extensions/common/api",
     "//extensions/common/api:extensions_features",
+    "//extensions/renderer",
     "//net:test_support",
     "//services/network/public/mojom",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/cld_3/src/src:cld_3",
+    "//third_party/zlib/google:zip",
   ]
 
   public_deps = [ "//content/public/browser" ]
@@ -314,7 +322,9 @@
     "//crypto:platform",
     "//crypto:test_support",
     "//device/bluetooth:mocks",
+    "//extensions/browser/api/bluetooth",
     "//extensions/common/api",
+    "//extensions/renderer",
     "//google_apis:test_support",
     "//media:test_support",
     "//net",
diff --git a/extensions/browser/api/lock_screen_data/data_item.cc b/extensions/browser/api/lock_screen_data/data_item.cc
index 26a1f1a..4225496 100644
--- a/extensions/browser/api/lock_screen_data/data_item.cc
+++ b/extensions/browser/api/lock_screen_data/data_item.cc
@@ -101,7 +101,6 @@
 
   values->Clear();
 
-  std::unique_ptr<base::Value> registered_items;
   if (!read.status().ok()) {
     *result = OperationResult::kFailed;
     return;
@@ -110,7 +109,9 @@
   // Using remove to pass ownership of registered_item dict to
   // |registered_items| (and avoid doing a copy |read.settings()|
   // sub-dictionary).
-  if (!read.settings().Remove(kStoreKeyRegisteredItems, &registered_items)) {
+  absl::optional<base::Value> registered_items =
+      read.settings().ExtractKey(kStoreKeyRegisteredItems);
+  if (!registered_items) {
     // If the registered items dictionary cannot be found, assume no items have
     // yet been registered, and return empty result.
     *result = OperationResult::kSuccess;
@@ -118,7 +119,8 @@
   }
 
   std::unique_ptr<base::DictionaryValue> items_dict =
-      base::DictionaryValue::From(std::move(registered_items));
+      base::DictionaryValue::From(
+          base::Value::ToUniquePtrValue(std::move(*registered_items)));
 
   *result =
       items_dict.get() ? OperationResult::kSuccess : OperationResult::kFailed;
@@ -132,16 +134,17 @@
                   ValueStore* store) {
   ValueStore::ReadResult read = store->Get(kStoreKeyRegisteredItems);
 
-  std::unique_ptr<base::Value> registered_items;
   if (!read.status().ok()) {
     *result = OperationResult::kFailed;
     return;
   }
-  if (!read.settings().Remove(kStoreKeyRegisteredItems, &registered_items))
-    registered_items = std::make_unique<base::DictionaryValue>();
+  absl::optional<base::Value> registered_items =
+      read.settings().ExtractKey(kStoreKeyRegisteredItems);
+  if (!registered_items)
+    registered_items = base::Value(base::Value::Type::DICTIONARY);
 
-  std::unique_ptr<base::DictionaryValue> dict =
-      base::DictionaryValue::From(std::move(registered_items));
+  std::unique_ptr<base::DictionaryValue> dict = base::DictionaryValue::From(
+      base::Value::ToUniquePtrValue(std::move(*registered_items)));
   if (!dict) {
     *result = OperationResult::kFailed;
     return;
@@ -250,7 +253,7 @@
   base::DictionaryValue* registered_items = nullptr;
   if (!read.settings().GetDictionary(kStoreKeyRegisteredItems,
                                      &registered_items) ||
-      !registered_items->Remove(item_id, nullptr)) {
+      !registered_items->RemoveKey(item_id)) {
     *result = OperationResult::kNotFound;
     return;
   }
diff --git a/extensions/browser/api/storage/settings_quota_unittest.cc b/extensions/browser/api/storage/settings_quota_unittest.cc
index e192c0e6..0fa89ff9 100644
--- a/extensions/browser/api/storage/settings_quota_unittest.cc
+++ b/extensions/browser/api/storage/settings_quota_unittest.cc
@@ -195,7 +195,7 @@
 
   // Try again with "b" removed, enough quota.
   EXPECT_TRUE(storage_->Remove("b").status().ok());
-  settings.Remove("b", NULL);
+  settings.RemoveKey("b");
   EXPECT_TRUE(storage_->Set(DEFAULTS, "c", byte_value_256_).status().ok());
   settings.SetKey("c", byte_value_256_.Clone());
   EXPECT_TRUE(SettingsEqual(settings));
@@ -210,7 +210,7 @@
 
   // Back under max keys.
   EXPECT_TRUE(storage_->Remove("a").status().ok());
-  settings.Remove("a", NULL);
+  settings.RemoveKey("a");
   EXPECT_TRUE(storage_->Set(DEFAULTS, "b", byte_value_1_).status().ok());
   settings.SetKey("b", byte_value_1_.Clone());
   EXPECT_TRUE(SettingsEqual(settings));
@@ -397,8 +397,8 @@
   to_remove.push_back("a");
   to_remove.push_back("b");
   storage_->Remove(to_remove);
-  settings.Remove("a", NULL);
-  settings.Remove("b", NULL);
+  settings.RemoveKey("a");
+  settings.RemoveKey("b");
   EXPECT_TRUE(SettingsEqual(settings));
 
   EXPECT_TRUE(storage_->Set(DEFAULTS, "d", byte_value_256_).status().ok());
@@ -460,9 +460,9 @@
 
   // Should be able after removing 2.
   storage_->Remove("a");
-  settings.Remove("a", NULL);
+  settings.RemoveKey("a");
   storage_->Remove("b");
-  settings.Remove("b", NULL);
+  settings.RemoveKey("b");
   EXPECT_TRUE(SettingsEqual(settings));
 
   EXPECT_TRUE(storage_->Set(DEFAULTS, "e", byte_value_1_).status().ok());
diff --git a/extensions/browser/api_test_utils.cc b/extensions/browser/api_test_utils.cc
index 5a9e9be..9f4cbedf 100644
--- a/extensions/browser/api_test_utils.cc
+++ b/extensions/browser/api_test_utils.cc
@@ -158,7 +158,7 @@
   // is no specified result.
   const base::ListValue* results = function->GetResultList();
   CHECK(results);
-  EXPECT_TRUE(results->empty()) << "Did not expect a result";
+  EXPECT_TRUE(results->GetList().empty()) << "Did not expect a result";
   CHECK(function->response_type());
   EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
   return function->GetError();
diff --git a/extensions/browser/extension_pref_value_map_unittest.cc b/extensions/browser/extension_pref_value_map_unittest.cc
index 0f4cd7a..5185e81 100644
--- a/extensions/browser/extension_pref_value_map_unittest.cc
+++ b/extensions/browser/extension_pref_value_map_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "components/prefs/pref_store_observer_mock.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc
index b908c08..fa460ea 100644
--- a/extensions/browser/extension_prefs.cc
+++ b/extensions/browser/extension_prefs.cc
@@ -571,7 +571,7 @@
   if (data_value)
     update->Set(key, std::move(data_value));
   else
-    update->Remove(key, NULL);
+    update->Remove(key);
 }
 
 void ExtensionPrefs::DeleteExtensionPrefs(const std::string& extension_id) {
@@ -579,7 +579,7 @@
   for (auto& observer : observer_list_)
     observer.OnExtensionPrefsDeleted(extension_id);
   prefs::ScopedDictionaryPrefUpdate update(prefs_, pref_names::kExtensions);
-  update->Remove(extension_id, NULL);
+  update->Remove(extension_id);
 }
 
 bool ExtensionPrefs::ReadPrefAsBoolean(const std::string& extension_id,
@@ -1643,7 +1643,7 @@
   if (!GetExtensionPref(extension_id))
     return false;
   ScopedExtensionPrefUpdate update(prefs_, extension_id);
-  bool result = update->Remove(kDelayedInstallInfo, NULL);
+  bool result = update->Remove(kDelayedInstallInfo);
   return result;
 }
 
@@ -1667,9 +1667,9 @@
                                       &serialized_ordinal)) {
     suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal);
     needs_sort_ordinal = true;
-    pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL);
+    pending_install_dict->Remove(kPrefSuggestedPageOrdinal);
   }
-  pending_install_dict->Remove(kDelayedInstallReason, NULL);
+  pending_install_dict->Remove(kDelayedInstallReason);
 
   const base::Time install_time = clock_->Now();
   pending_install_dict->SetString(
@@ -1869,7 +1869,7 @@
       continue;
 
     if (extension_dict->HasKey(kPrefLastLaunchTime))
-      extension_dict->Remove(kPrefLastLaunchTime, NULL);
+      extension_dict->Remove(kPrefLastLaunchTime);
   }
 }
 
@@ -2419,7 +2419,7 @@
   // the previous install are cleared up in case of an update. Else just set the
   // entry (which will overwrite any existing value).
   if (ruleset_install_prefs.empty()) {
-    extension_dict->Remove(kDNRStaticRulesetPref, nullptr /* out_value */);
+    extension_dict->Remove(kDNRStaticRulesetPref);
   } else {
     auto ruleset_prefs = std::make_unique<base::DictionaryValue>();
     for (const declarative_net_request::RulesetInstallPref& install_pref :
@@ -2441,7 +2441,7 @@
 
   // Clear the list of enabled static rulesets for the extension since it
   // shouldn't persist across extension updates.
-  extension_dict->Remove(kDNREnabledStaticRulesetIDs, nullptr /* out_value */);
+  extension_dict->Remove(kDNREnabledStaticRulesetIDs);
 
   if (util::CanWithholdPermissionsFromExtension(*extension)) {
     // If the withhold permission creation flag is present it takes precedence
@@ -2472,7 +2472,7 @@
   if (install_flags & kInstallFlagDoNotSync)
     extension_dict->SetBoolean(kPrefDoNotSync, true);
   else
-    extension_dict->Remove(kPrefDoNotSync, NULL);
+    extension_dict->Remove(kPrefDoNotSync);
 }
 
 void ExtensionPrefs::InitExtensionControlledPrefs(
@@ -2558,11 +2558,11 @@
 
   // If this point has been reached, any pending installs should be considered
   // out of date.
-  extension_dict->Remove(kDelayedInstallInfo, NULL);
+  extension_dict->Remove(kDelayedInstallInfo);
 
   // Clear state that may be registered from a previous install.
-  extension_dict->Remove(EventRouter::kRegisteredLazyEvents, nullptr);
-  extension_dict->Remove(EventRouter::kRegisteredServiceWorkerEvents, nullptr);
+  extension_dict->Remove(EventRouter::kRegisteredLazyEvents);
+  extension_dict->Remove(EventRouter::kRegisteredServiceWorkerEvents);
 
   // FYI, all code below here races on sudden shutdown because |extension_dict|,
   // |app_sorting|, |extension_pref_value_map_|, and (potentially) observers
@@ -2657,7 +2657,7 @@
     }
 
     for (const char* key : kObsoleteKeys)
-      inner_update->Remove(key, nullptr);
+      inner_update->Remove(key);
   }
 }
 
diff --git a/extensions/common/api/declarative/declarative_manifest_data.cc b/extensions/common/api/declarative/declarative_manifest_data.cc
index 4a898e1..5d9b464 100644
--- a/extensions/common/api/declarative/declarative_manifest_data.cc
+++ b/extensions/common/api/declarative/declarative_manifest_data.cc
@@ -61,7 +61,7 @@
           }
           if (type == declarative_content_constants::kLegacyShowAction)
             type = declarative_content_constants::kShowAction;
-          dictionary->Remove("type", nullptr);
+          dictionary->RemoveKey("type");
           dictionary->SetString("instanceType", type);
         }
         return true;
diff --git a/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc b/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc
index 8a738c4..4d0a690 100644
--- a/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc
+++ b/extensions/common/api/declarative_net_request/dnr_manifest_unittest.cc
@@ -226,7 +226,7 @@
   std::vector<TestRulesetInfo> rulesets({CreateDefaultRuleset()});
   std::unique_ptr<base::DictionaryValue> manifest = CreateManifest(rulesets);
   // Remove "declarativeNetRequest" permission.
-  manifest->Remove(manifest_keys::kPermissions, nullptr);
+  manifest->RemoveKey(manifest_keys::kPermissions);
 
   WriteManifestAndRuleset(*manifest, rulesets);
 
diff --git a/extensions/renderer/bindings/api_binding.cc b/extensions/renderer/bindings/api_binding.cc
index 0d6ff9b..6a9910b 100644
--- a/extensions/renderer/bindings/api_binding.cc
+++ b/extensions/renderer/bindings/api_binding.cc
@@ -314,8 +314,8 @@
       std::string full_name =
           base::StringPrintf("%s.%s", api_name_.c_str(), name.c_str());
       const base::ListValue* filters = nullptr;
-      bool supports_filters =
-          event_dict->GetList("filters", &filters) && !filters->empty();
+      bool supports_filters = event_dict->GetList("filters", &filters) &&
+                              !filters->GetList().empty();
 
       std::vector<std::string> rule_actions;
       std::vector<std::string> rule_conditions;
diff --git a/extensions/renderer/bindings/argument_spec.cc b/extensions/renderer/bindings/argument_spec.cc
index 39f5b40..0222401a0 100644
--- a/extensions/renderer/bindings/argument_spec.cc
+++ b/extensions/renderer/bindings/argument_spec.cc
@@ -97,7 +97,7 @@
   {
     const base::ListValue* choices = nullptr;
     if (dict->GetList("choices", &choices)) {
-      DCHECK(!choices->empty());
+      DCHECK(!choices->GetList().empty());
       type_ = ArgumentType::CHOICES;
       choices_.reserve(choices->GetSize());
       for (const auto& choice : choices->GetList())
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index dcc4728..2c2e9c7 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -432,6 +432,13 @@
   }
 
   VLOG(1) << "Num tracked contexts: " << script_context_set_->size();
+
+  ExtensionFrameHelper* frame_helper =
+      ExtensionFrameHelper::Get(content::RenderFrame::FromWebFrame(frame));
+  if (!frame_helper)
+    return;  // The frame is invisible to extensions.
+
+  frame_helper->set_did_create_script_context();
 }
 
 void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread(
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc
index c34886d6..1bde0ce 100644
--- a/extensions/renderer/extension_frame_helper.cc
+++ b/extensions/renderer/extension_frame_helper.cc
@@ -45,6 +45,9 @@
 
 // Returns true if the render frame corresponding with |frame_helper| matches
 // the given criteria.
+//
+// We deliberately do not access any methods that require a v8::Context or
+// ScriptContext.  See also comment below.
 bool RenderFrameMatches(const ExtensionFrameHelper* frame_helper,
                         mojom::ViewType match_view_type,
                         int match_window_id,
@@ -75,7 +78,16 @@
       frame_helper->tab_id() != match_tab_id)
     return false;
 
-  return true;
+  // Returning handles to frames that haven't created a script context yet
+  // can result in the caller "forcing" a script context (by accessing
+  // properties on the window object). This, in turn, can cause the script
+  // context to be initialized prematurely, with invalid values (e.g., the
+  // inability to retrieve a valid URL from the frame). That then leads to
+  // the ScriptContext being misclassified.
+  // Don't return any frames until they have a valid ScriptContext to limit
+  // the chances for bindings to prematurely initialize these contexts.
+  // This speculatively fixes https://crbug.com/1021014.
+  return frame_helper->did_create_script_context();
 }
 
 // Runs every callback in |callbacks_to_be_run_and_cleared| while |frame_helper|
diff --git a/extensions/renderer/extension_frame_helper.h b/extensions/renderer/extension_frame_helper.h
index 4580ff93..a3d24537 100644
--- a/extensions/renderer/extension_frame_helper.h
+++ b/extensions/renderer/extension_frame_helper.h
@@ -116,6 +116,9 @@
                                 const std::string& script_id,
                                 const GURL& url) override;
 
+  void set_did_create_script_context() { did_create_script_context_ = true; }
+  bool did_create_script_context() const { return did_create_script_context_; }
+
   // Called when the document element has been inserted in this frame. This
   // method may invoke untrusted JavaScript code that invalidate the frame and
   // this ExtensionFrameHelper.
@@ -211,6 +214,8 @@
   // navigation happens, it is either the initial one or a reload.
   bool has_started_first_navigation_ = false;
 
+  bool did_create_script_context_ = false;
+
   mojo::AssociatedRemote<mojom::LocalFrameHost> local_frame_host_remote_;
 
   mojo::AssociatedReceiver<mojom::LocalFrame> local_frame_receiver_{this};
diff --git a/extensions/renderer/resources/app_window_custom_bindings.js b/extensions/renderer/resources/app_window_custom_bindings.js
index 5df0aca6..3e4168b 100644
--- a/extensions/renderer/resources/app_window_custom_bindings.js
+++ b/extensions/renderer/resources/app_window_custom_bindings.js
@@ -180,11 +180,21 @@
 
   apiFunctions.setHandleRequest('getAll', function() {
     var views = runtimeNatives.GetExtensionViews(-1, -1, 'APP_WINDOW');
-    // In certain corner cases, renderers may not load correctly, and are
-    // missing the chrome.app bindings. Filter these views out so that the next
-    // lines don't crash.
-    // See https://crbug.com/1021014.
-    views = $Array.filter(views, (w) => w.chrome.app);
+
+    views = $Array.filter(views, (w) => {
+      if (!w.chrome.app.window.current()) {
+        // Even though the script context has been created, the initialization
+        // hasn't finished. chrome.app.window.current() is based upon the
+        // completion of the app.window.create() callback, and it's possible
+        // this is called before that.
+        // Treat not-fully-initialized windows as invisible; the app can query
+        // them once the callback for app.window.create() is fired (which is
+        // in-line with API expectations).
+        // See https://crbug.com/1021014.
+        return false;
+      }
+      return true;
+    });
     return $Array.map(views, function(win) {
       return win.chrome.app.window.current();
     });
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index ebc40363..6e3fcee8e 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -225,6 +225,10 @@
     ]
   }
 
+  if (is_chromeos_ash || is_chromeos_lacros) {
+    deps += [ "//chromeos/dbus/constants" ]
+  }
+
   if (is_chromeos_ash) {
     sources += [
       "browser/shell_screen.cc",
@@ -245,6 +249,9 @@
     ]
   }
 
+  if (is_chromeos_lacros) {
+    deps += [ "//chromeos/lacros" ]
+  }
   if (enable_nacl) {
     sources += [
       "browser/shell_nacl_browser_delegate.cc",
diff --git a/extensions/shell/app/shell_main_delegate.cc b/extensions/shell/app/shell_main_delegate.cc
index e9ec671..7abc285 100644
--- a/extensions/shell/app/shell_main_delegate.cc
+++ b/extensions/shell/app/shell_main_delegate.cc
@@ -22,9 +22,12 @@
 #include "extensions/shell/renderer/shell_content_renderer_client.h"
 #include "ui/base/resource/resource_bundle.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/dbus/constants/dbus_paths.h"
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_paths.h"
-#include "chromeos/dbus/constants/dbus_paths.h"
 #endif
 
 #if BUILDFLAG(ENABLE_NACL)
@@ -142,6 +145,8 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::RegisterPathProvider();
+#endif
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_ASH)
   chromeos::dbus_paths::RegisterPathProvider();
 #endif
 #if BUILDFLAG(ENABLE_NACL) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc
index 1fb8a249..8c65375 100644
--- a/extensions/shell/browser/shell_browser_main_parts.cc
+++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -73,6 +73,10 @@
 #include "device/bluetooth/dbus/bluez_dbus_thread_manager.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/lacros/lacros_dbus_thread_manager.h"
+#endif
+
 #if BUILDFLAG(ENABLE_NACL)
 #include "components/nacl/browser/nacl_browser.h"
 #include "components/nacl/browser/nacl_process_host.h"
@@ -162,6 +166,9 @@
 #else
   ui::InitializeInputMethodForTesting();
 #endif
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  chromeos::LacrosDBusThreadManager::Initialize();
+#endif
 }
 
 int ShellBrowserMainParts::PreEarlyInitialization() {
@@ -319,6 +326,9 @@
   extensions_browser_client_.reset();
   ExtensionsBrowserClient::Set(nullptr);
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  chromeos::LacrosDBusThreadManager::Shutdown();
+#endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   network_controller_.reset();
   chromeos::NetworkHandler::Shutdown();
diff --git a/fuchsia/engine/browser/accessibility_bridge.cc b/fuchsia/engine/browser/accessibility_bridge.cc
index 3179b236..dc428dd3 100644
--- a/fuchsia/engine/browser/accessibility_bridge.cc
+++ b/fuchsia/engine/browser/accessibility_bridge.cc
@@ -583,6 +583,19 @@
     return true;
   }
 
+  // Make sure that all trees are reachable from the main frame semantic tree.
+  // If a tree is not reachable, this means that when committed it would result
+  // in a dangling tree, which is not valid.
+  for (const auto& kv : ax_trees_) {
+    const ui::AXTreeID& tree_id = kv.first;
+    if (tree_id == main_frame_tree_id)
+      continue;
+
+    auto it = tree_connections_.find(tree_id);
+    if (it == tree_connections_.end())
+      return true;
+  }
+
   for (const auto& kv : tree_connections_) {
     if (!kv.second.is_connected) {
       // Trees are not connected, which means that a node is pointing to
diff --git a/fuchsia/engine/browser/web_engine_content_browser_client.cc b/fuchsia/engine/browser/web_engine_content_browser_client.cc
index 4f7d8ff..2f9d49e5 100644
--- a/fuchsia/engine/browser/web_engine_content_browser_client.cc
+++ b/fuchsia/engine/browser/web_engine_content_browser_client.cc
@@ -7,8 +7,8 @@
 #include <string>
 #include <utility>
 
+#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
-#include "base/stl_util.h"
 #include "base/strings/string_split.h"
 #include "components/policy/content/safe_sites_navigation_throttle.h"
 #include "components/site_isolation/features.h"
diff --git a/gin/converter_unittest.cc b/gin/converter_unittest.cc
index f3f57be..195d719 100644
--- a/gin/converter_unittest.cc
+++ b/gin/converter_unittest.cc
@@ -11,7 +11,7 @@
 #include <string>
 
 #include "base/compiler_specific.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "gin/function_template.h"
 #include "gin/handle.h"
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn
index a0ec864..2f2ec72 100644
--- a/google_apis/BUILD.gn
+++ b/google_apis/BUILD.gn
@@ -218,6 +218,7 @@
   sources = [
     "gaia/gaia_auth_fetcher_unittest.cc",
     "gaia/gaia_auth_util_unittest.cc",
+    "gaia/gaia_config_unittest.cc",
     "gaia/gaia_oauth_client_unittest.cc",
     "gaia/gaia_urls_unittest.cc",
     "gaia/google_service_auth_error_unittest.cc",
diff --git a/google_apis/gaia/gaia_config.cc b/google_apis/gaia/gaia_config.cc
index 1123927..1785e58 100644
--- a/google_apis/gaia/gaia_config.cc
+++ b/google_apis/gaia/gaia_config.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/no_destructor.h"
@@ -19,31 +20,54 @@
 
 namespace {
 
-std::unique_ptr<GaiaConfig> ReadConfigFromDisk() {
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (!command_line->HasSwitch(switches::kGaiaConfig))
-    return nullptr;
-
-  const base::FilePath config_path =
-      command_line->GetSwitchValuePath(switches::kGaiaConfig);
-  std::string config_contents;
-  if (!base::ReadFileToString(config_path, &config_contents)) {
-    LOG(ERROR) << "Couldn't read gaia config file " << config_path;
-    return nullptr;
-  }
-
+std::unique_ptr<GaiaConfig> ReadConfigFromString(
+    const std::string& config_contents) {
   absl::optional<base::Value> dict = base::JSONReader::Read(config_contents);
   if (!dict || !dict->is_dict()) {
-    LOG(ERROR) << "Couldn't parse gaia config file " << config_path;
+    LOG(FATAL) << "Couldn't parse Gaia config file";
     return nullptr;
   }
 
   return std::make_unique<GaiaConfig>(std::move(dict.value()));
 }
 
+std::unique_ptr<GaiaConfig> ReadConfigFromDisk(
+    const base::FilePath& config_path) {
+  std::string config_contents;
+  if (!base::ReadFileToString(config_path, &config_contents)) {
+    LOG(FATAL) << "Couldn't read Gaia config file " << config_path;
+    return nullptr;
+  }
+  return ReadConfigFromString(config_contents);
+}
+
+std::unique_ptr<GaiaConfig> ReadConfigFromCommandLineSwitches(
+    const base::CommandLine* command_line) {
+  if (command_line->HasSwitch(switches::kGaiaConfigPath) &&
+      command_line->HasSwitch(switches::kGaiaConfigContents)) {
+    LOG(FATAL) << "Either a Gaia config file path or a config file contents "
+                  "can be provided; "
+               << "not both";
+    return nullptr;
+  }
+
+  if (command_line->HasSwitch(switches::kGaiaConfigContents)) {
+    return ReadConfigFromString(
+        command_line->GetSwitchValueASCII(switches::kGaiaConfigContents));
+  }
+
+  if (command_line->HasSwitch(switches::kGaiaConfigPath)) {
+    return ReadConfigFromDisk(
+        command_line->GetSwitchValuePath(switches::kGaiaConfigPath));
+  }
+
+  return nullptr;
+}
+
 std::unique_ptr<GaiaConfig>* GetGlobalConfig() {
   static base::NoDestructor<std::unique_ptr<GaiaConfig>> config(
-      ReadConfigFromDisk());
+      ReadConfigFromCommandLineSwitches(
+          base::CommandLine::ForCurrentProcess()));
   return config.get();
 }
 
@@ -100,7 +124,22 @@
   return true;
 }
 
+void GaiaConfig::SerializeContentsToCommandLineSwitch(
+    base::CommandLine* command_line) const {
+  std::string config_contents;
+  base::JSONWriter::Write(parsed_config_, &config_contents);
+  command_line->AppendSwitchASCII(switches::kGaiaConfigContents,
+                                  config_contents);
+}
+
+// static
+std::unique_ptr<GaiaConfig> GaiaConfig::CreateFromCommandLineForTesting(
+    const base::CommandLine* command_line) {
+  return ReadConfigFromCommandLineSwitches(command_line);
+}
+
 // static
 void GaiaConfig::ResetInstanceForTesting() {
-  *GetGlobalConfig() = ReadConfigFromDisk();
+  *GetGlobalConfig() =
+      ReadConfigFromCommandLineSwitches(base::CommandLine::ForCurrentProcess());
 }
diff --git a/google_apis/gaia/gaia_config.h b/google_apis/gaia/gaia_config.h
index 7889d21a..eeae2fa 100644
--- a/google_apis/gaia/gaia_config.h
+++ b/google_apis/gaia/gaia_config.h
@@ -15,9 +15,14 @@
 
 class GURL;
 
+namespace base {
+class CommandLine;
+}  // namespace base
+
 // Class representing a configuration for Gaia URLs and Google API keys.
-// Parses a JSON config file specified by |switches::kGaiaConfig| and provides
-// convenient getters for reading this config.
+// Parses a JSON config file specified by |switches::kGaiaConfigPath| or
+// |switches::kGaiaConfigContents| and provides convenient getters for reading
+// this config.
 //
 // The config is represented by a JSON object with the following structure:
 // {
@@ -26,7 +31,7 @@
 //       "url": "https://accounts.example.com"
 //     },
 //     ...
-//   }
+//   },
 //   "api_keys": {
 //     "GOOGLE_CLIENT_ID_MAIN": "example_key",
 //     ...
@@ -36,12 +41,14 @@
  public:
   // Returns a global instance of GaiaConfig.
   // This may return nullptr if the config file was not specified by a command
-  // line parameter or couldn't be parsed correctly.
+  // line parameter.
   static GaiaConfig* GetInstance();
 
   // Constructs a new GaiaConfig from a parsed JSON dictionary.
   // Prefer GetInstance() over this constructor.
   explicit GaiaConfig(base::Value parsed_config);
+  GaiaConfig(const GaiaConfig&) = delete;
+  GaiaConfig& operator=(const GaiaConfig&) = delete;
   ~GaiaConfig();
 
   // Searches for a URL by |key|.
@@ -56,6 +63,17 @@
   // Otherwise, returns false. |out_api_key| will be unmodified.
   bool GetAPIKeyIfExists(base::StringPiece key, std::string* out_api_key);
 
+  // Serializes the state of |this| into |command_line|, in a way that
+  // GaiaConfig::GetInstance() would honor. Internally, it uses switch
+  // |kGaiaConfigContents| for this purpose, which is appended to
+  // |*command_line|.
+  void SerializeContentsToCommandLineSwitch(
+      base::CommandLine* command_line) const;
+
+  // Instantiates this object given |base::CommandLine|, used in tests.
+  static std::unique_ptr<GaiaConfig> CreateFromCommandLineForTesting(
+      const base::CommandLine* command_line);
+
  private:
   friend class GaiaUrlsTest;
   FRIEND_TEST_ALL_PREFIXES(GoogleAPIKeysTest, OverrideAllKeysUsingConfig);
diff --git a/google_apis/gaia/gaia_config_unittest.cc b/google_apis/gaia/gaia_config_unittest.cc
new file mode 100644
index 0000000..ce304d5
--- /dev/null
+++ b/google_apis/gaia/gaia_config_unittest.cc
@@ -0,0 +1,96 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "google_apis/gaia/gaia_config.h"
+
+#include "base/command_line.h"
+#include "base/json/json_reader.h"
+#include "google_apis/gaia/gaia_switches.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+
+namespace {
+
+using testing::Eq;
+using testing::IsNull;
+
+const char kTestConfigContents[] = R"(
+{
+  "urls": {
+    "test_url": {
+      "url": "https://accounts.example.com/"
+    }
+  },
+  "api_keys": {
+    "test_api_key": "test_api_key_value"
+  }
+})";
+
+TEST(GaiaConfigTest, ShouldGetURLIfExists) {
+  absl::optional<base::Value> dict =
+      base::JSONReader::Read(kTestConfigContents);
+  ASSERT_TRUE(dict.has_value());
+
+  GaiaConfig config(std::move(*dict));
+  GURL url;
+  EXPECT_TRUE(config.GetURLIfExists("test_url", &url));
+  EXPECT_THAT(url, Eq("https://accounts.example.com/"));
+}
+
+TEST(GaiaConfigTest, ShouldReturnNullIfURLDoesNotExists) {
+  absl::optional<base::Value> dict =
+      base::JSONReader::Read(kTestConfigContents);
+  ASSERT_TRUE(dict.has_value());
+
+  GaiaConfig config(std::move(*dict));
+  GURL url;
+  EXPECT_FALSE(config.GetURLIfExists("missing_url", &url));
+}
+
+TEST(GaiaConfigTest, ShouldGetAPIKeyIfExists) {
+  absl::optional<base::Value> dict =
+      base::JSONReader::Read(kTestConfigContents);
+  ASSERT_TRUE(dict.has_value());
+
+  GaiaConfig config(std::move(*dict));
+  std::string api_key;
+  EXPECT_TRUE(config.GetAPIKeyIfExists("test_api_key", &api_key));
+  EXPECT_THAT(api_key, Eq("test_api_key_value"));
+}
+
+TEST(GaiaConfigTest, ShouldReturnNullIfAPIKeyDoesNotExists) {
+  absl::optional<base::Value> dict =
+      base::JSONReader::Read(kTestConfigContents);
+  ASSERT_TRUE(dict.has_value());
+
+  GaiaConfig config(std::move(*dict));
+  std::string api_key;
+  EXPECT_FALSE(config.GetAPIKeyIfExists("missing_api_key", &api_key));
+}
+
+TEST(GaiaConfigTest, ShouldSerializeContentsToCommandLineSwitch) {
+  absl::optional<base::Value> dict =
+      base::JSONReader::Read(kTestConfigContents);
+  ASSERT_TRUE(dict.has_value());
+
+  GaiaConfig config(std::move(*dict));
+  GURL url;
+  ASSERT_TRUE(config.GetURLIfExists("test_url", &url));
+  ASSERT_THAT(url, Eq("https://accounts.example.com/"));
+
+  base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
+  config.SerializeContentsToCommandLineSwitch(&command_line);
+  EXPECT_TRUE(command_line.HasSwitch(switches::kGaiaConfigContents));
+
+  std::unique_ptr<GaiaConfig> deserialized_config =
+      GaiaConfig::CreateFromCommandLineForTesting(&command_line);
+  GURL deserialized_url;
+  EXPECT_TRUE(
+      deserialized_config->GetURLIfExists("test_url", &deserialized_url));
+  EXPECT_THAT(deserialized_url, Eq("https://accounts.example.com/"));
+}
+
+}  // namespace
diff --git a/google_apis/gaia/gaia_switches.cc b/google_apis/gaia/gaia_switches.cc
index 95faee3..e8e3618 100644
--- a/google_apis/gaia/gaia_switches.cc
+++ b/google_apis/gaia/gaia_switches.cc
@@ -6,7 +6,8 @@
 
 namespace switches {
 
-const char kGaiaConfig[] = "gaia-config";
+const char kGaiaConfigPath[] = "gaia-config";
+const char kGaiaConfigContents[] = "gaia-config-contents";
 const char kGoogleUrl[]                     = "google-url";
 const char kGaiaUrl[]                       = "gaia-url";
 const char kGoogleApisUrl[]                 = "google-apis-url";
diff --git a/google_apis/gaia/gaia_switches.h b/google_apis/gaia/gaia_switches.h
index 3ce1e3e6..089a43c 100644
--- a/google_apis/gaia/gaia_switches.h
+++ b/google_apis/gaia/gaia_switches.h
@@ -9,7 +9,12 @@
 
 // Specifies the path to a config file containing GAIA urls.
 // See "google_apis/test/data/gaia/all_urls.json" for a format example.
-extern const char kGaiaConfig[];
+extern const char kGaiaConfigPath[];
+
+// Specifies a string containing the JSON config for GAIA urls. This is
+// equivalent to pointing to a file with the same content via kGaiaConfigPath.
+// See "google_apis/test/data/gaia/all_urls.json" for a format example.
+extern const char kGaiaConfigContents[];
 
 // Specifies the domain of the SAPISID cookie. The default value is
 // "http://.google.com".
diff --git a/google_apis/gaia/gaia_urls_unittest.cc b/google_apis/gaia/gaia_urls_unittest.cc
index c5cd7e6..59dd5b8b 100644
--- a/google_apis/gaia/gaia_urls_unittest.cc
+++ b/google_apis/gaia/gaia_urls_unittest.cc
@@ -13,6 +13,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "google_apis/gaia/gaia_config.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -452,6 +453,21 @@
             "https://accounts.example.com/");
 }
 
+TEST_F(GaiaUrlsTest, InitializeFromConfigContents) {
+  base::test::ScopedCommandLine command_line;
+  command_line.GetProcessCommandLine()->AppendSwitchASCII(
+      "gaia-config-contents", R"(
+{
+  "urls": {
+    "gaia_url": {
+      "url": "https://accounts.example.com"
+    }
+  }
+})");
+
+  EXPECT_EQ(gaia_urls()->gaia_url().spec(), "https://accounts.example.com/");
+}
+
 TEST_F(GaiaUrlsTest, InitializeFromConfig_BadUrl) {
   base::test::ScopedCommandLine command_line;
   command_line.GetProcessCommandLine()->AppendSwitchPath(
@@ -484,8 +500,7 @@
   command_line.GetProcessCommandLine()->AppendSwitchPath(
       "gaia-config", GetTestFilePath("no_such_file.json"));
 
-  // Fallback to the default URL.
-  EXPECT_EQ(gaia_urls()->google_url().spec(), "http://google.com/");
+  EXPECT_DEATH_IF_SUPPORTED(gaia_urls(), "Couldn't read Gaia config file");
 }
 
 TEST_F(GaiaUrlsTest, InitializeFromConfig_NotAJson) {
@@ -493,6 +508,5 @@
   command_line.GetProcessCommandLine()->AppendSwitchPath(
       "gaia-config", GetTestFilePath("not_a_json.txt"));
 
-  // Fallback to the default URL.
-  EXPECT_EQ(gaia_urls()->google_url().spec(), "http://google.com/");
+  EXPECT_DEATH_IF_SUPPORTED(gaia_urls(), "Couldn't parse Gaia config file");
 }
diff --git a/gpu/command_buffer/common/raster_cmd_format_test.cc b/gpu/command_buffer/common/raster_cmd_format_test.cc
index dd4ca4c7..0126355f 100644
--- a/gpu/command_buffer/common/raster_cmd_format_test.cc
+++ b/gpu/command_buffer/common/raster_cmd_format_test.cc
@@ -10,9 +10,9 @@
 #include <limits>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread.h"
 #include "gpu/command_buffer/common/raster_cmd_format.h"
diff --git a/gpu/command_buffer/common/webgpu_cmd_enums.h b/gpu/command_buffer/common/webgpu_cmd_enums.h
index 83615b30..f565583 100644
--- a/gpu/command_buffer/common/webgpu_cmd_enums.h
+++ b/gpu/command_buffer/common/webgpu_cmd_enums.h
@@ -5,6 +5,8 @@
 #ifndef GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_ENUMS_H_
 #define GPU_COMMAND_BUFFER_COMMON_WEBGPU_CMD_ENUMS_H_
 
+#include <stdint.h>
+
 namespace gpu {
 namespace webgpu {
 
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index e234eb68..dd61c1b49 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/config/ui.gni")
 import("//gpu/vulkan/features.gni")
 import("//skia/features.gni")
+import("//third_party/dawn/scripts/dawn_features.gni")
 import("//third_party/protobuf/proto_library.gni")
 import("//ui/gl/features.gni")
 
@@ -403,9 +404,16 @@
 
   if (use_dawn) {
     deps += [
+      "//third_party/dawn/src/dawn:dawn_proc",
       "//third_party/dawn/src/dawn_native",
       "//third_party/dawn/src/dawn_platform",
     ]
+    if (dawn_enable_opengles) {
+      sources += [
+        "shared_image_representation_dawn_egl_image.cc",
+        "shared_image_representation_dawn_egl_image.h",
+      ]
+    }
   }
 
   if (is_mac) {
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index b96b5a4..2e6fd71 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -12,6 +12,7 @@
 
 #include "build/build_config.h"
 #include "gpu/command_buffer/common/constants.h"
+#include "gpu/gpu_gles2_export.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/overlay_transform.h"
@@ -91,9 +92,9 @@
                        GLsizei length,
                        const GLchar* message,
                        Logger* error_logger);
-void InitializeGLDebugLogging(bool log_non_errors,
-                              GLDEBUGPROC callback,
-                              const void* user_param);
+GPU_GLES2_EXPORT void InitializeGLDebugLogging(bool log_non_errors,
+                                               GLDEBUGPROC callback,
+                                               const void* user_param);
 
 bool ValidContextLostReason(GLenum reason);
 error::ContextLostReason GetContextLostReasonFromResetStatus(
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.cc b/gpu/command_buffer/service/image_reader_gl_owner.cc
index d01528f7..426d0b7 100644
--- a/gpu/command_buffer/service/image_reader_gl_owner.cc
+++ b/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -68,6 +68,17 @@
     DCHECK(!features::LimitAImageReaderMaxSizeToOne());
     if (features::IncreaseBufferCountForHighFrameRate())
       return 5;
+
+    // WebView overlays relies on WebView zero copy at the moment, which
+    // requires at least 3 buffers (one renderer prepares, one is locked by
+    // display compositor in latest compositor frame and one is pending
+    // deletion). These are additional to normal 3 that we need to surface
+    // control.
+    // TODO(vasilyt): This needs to be resolved before feature launch, but
+    // should work for dogfoog.
+    if (features::IncreaseBufferCountForWebViewOverlays())
+      return 6;
+
     return 3;
   }
   return features::LimitAImageReaderMaxSizeToOne() ? 1 : 2;
diff --git a/gpu/command_buffer/service/raster_cmd_validation.cc b/gpu/command_buffer/service/raster_cmd_validation.cc
index ec66e6ba..676ddcf0 100644
--- a/gpu/command_buffer/service/raster_cmd_validation.cc
+++ b/gpu/command_buffer/service/raster_cmd_validation.cc
@@ -6,7 +6,7 @@
 
 #include "gpu/command_buffer/service/raster_cmd_validation.h"
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "gpu/command_buffer/service/gl_utils.h"
 
 namespace gpu {
diff --git a/gpu/command_buffer/service/shared_image_backing_d3d.cc b/gpu/command_buffer/service/shared_image_backing_d3d.cc
index b069b06..bebccf84 100644
--- a/gpu/command_buffer/service/shared_image_backing_d3d.cc
+++ b/gpu/command_buffer/service/shared_image_backing_d3d.cc
@@ -12,6 +12,9 @@
 #include "gpu/command_buffer/common/shared_image_trace_utils.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/command_buffer/service/shared_image_representation_d3d.h"
+#if BUILDFLAG(USE_DAWN) && BUILDFLAG(DAWN_ENABLE_BACKEND_OPENGLES)
+#include "gpu/command_buffer/service/shared_image_representation_dawn_egl_image.h"
+#endif
 #include "gpu/command_buffer/service/shared_image_representation_skia_gl.h"
 #include "ui/gl/trace_util.h"
 
@@ -433,29 +436,42 @@
                                    WGPUDevice device,
                                    WGPUBackendType backend_type) {
 #if BUILDFLAG(USE_DAWN)
+  const viz::ResourceFormat viz_resource_format = format();
+  const WGPUTextureFormat wgpu_format = viz::ToWGPUFormat(viz_resource_format);
+  if (wgpu_format == WGPUTextureFormat_Undefined) {
+    DLOG(ERROR) << "Unsupported viz format found: " << viz_resource_format;
+    return nullptr;
+  }
+
+  WGPUTextureDescriptor texture_descriptor = {};
+  texture_descriptor.nextInChain = nullptr;
+  texture_descriptor.format = wgpu_format;
+  texture_descriptor.usage = GetAllowedDawnUsages();
+  texture_descriptor.dimension = WGPUTextureDimension_2D;
+  texture_descriptor.size = {static_cast<uint32_t>(size().width()),
+                             static_cast<uint32_t>(size().height()), 1};
+  texture_descriptor.mipLevelCount = 1;
+  texture_descriptor.sampleCount = 1;
+
+#if BUILDFLAG(DAWN_ENABLE_BACKEND_OPENGLES)
+  if (backend_type == WGPUBackendType_OpenGLES) {
+    // EGLImage textures do not support sampling, at the moment.
+    texture_descriptor.usage &= ~WGPUTextureUsage_Sampled;
+    EGLImage egl_image =
+        static_cast<gl::GLImageD3D*>(GetGLImage())->egl_image();
+    if (!egl_image) {
+      DLOG(ERROR) << "Failed to create EGLImage";
+      return nullptr;
+    }
+    return std::make_unique<SharedImageRepresentationDawnEGLImage>(
+        manager, this, tracker, device, egl_image, texture_descriptor);
+  }
+#endif
 
   // Persistently open the shared handle by caching it on this backing.
   if (!external_image_) {
     DCHECK(base::win::HandleTraits::IsHandleValid(GetSharedHandle()));
 
-    const viz::ResourceFormat viz_resource_format = format();
-    const WGPUTextureFormat wgpu_format =
-        viz::ToWGPUFormat(viz_resource_format);
-    if (wgpu_format == WGPUTextureFormat_Undefined) {
-      DLOG(ERROR) << "Unsupported viz format found: " << viz_resource_format;
-      return nullptr;
-    }
-
-    WGPUTextureDescriptor texture_descriptor = {};
-    texture_descriptor.nextInChain = nullptr;
-    texture_descriptor.format = wgpu_format;
-    texture_descriptor.usage = GetAllowedDawnUsages();
-    texture_descriptor.dimension = WGPUTextureDimension_2D;
-    texture_descriptor.size = {static_cast<uint32_t>(size().width()),
-                               static_cast<uint32_t>(size().height()), 1};
-    texture_descriptor.mipLevelCount = 1;
-    texture_descriptor.sampleCount = 1;
-
     dawn_native::d3d12::ExternalImageDescriptorDXGISharedHandle
         externalImageDesc;
     externalImageDesc.cTextureDescriptor = &texture_descriptor;
diff --git a/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.cc b/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.cc
new file mode 100644
index 0000000..f5e664a
--- /dev/null
+++ b/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.cc
@@ -0,0 +1,79 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/shared_image_representation_dawn_egl_image.h"
+
+#include "build/build_config.h"
+#if defined(OS_WIN)
+#include "gpu/command_buffer/service/shared_image_backing_d3d.h"
+#endif
+
+#include <dawn_native/OpenGLBackend.h>
+
+namespace gpu {
+
+SharedImageRepresentationDawnEGLImage::SharedImageRepresentationDawnEGLImage(
+    SharedImageManager* manager,
+    SharedImageBacking* backing,
+    MemoryTypeTracker* tracker,
+    WGPUDevice device,
+    EGLImage image,
+    const WGPUTextureDescriptor& texture_descriptor)
+    : SharedImageRepresentationDawn(manager, backing, tracker),
+      device_(device),
+      image_(image),
+      texture_descriptor_(texture_descriptor),
+      dawn_procs_(dawn_native::GetProcs()) {
+  DCHECK(device_);
+  DCHECK(image_);
+
+  // Keep a reference to the device so that it stays valid.
+  dawn_procs_.deviceReference(device_);
+}
+
+SharedImageRepresentationDawnEGLImage::
+    ~SharedImageRepresentationDawnEGLImage() {
+  EndAccess();
+
+  dawn_procs_.deviceRelease(device_);
+}
+
+WGPUTexture SharedImageRepresentationDawnEGLImage::BeginAccess(
+    WGPUTextureUsage usage) {
+#if defined(OS_WIN)
+  // On D3D11 backings, we must acquire the keyed mutex to do interop. If we
+  // ever switch to non-D3D backings on Windows, this code will break horribly.
+  // TODO(senorblanco): This should probably be a virtual on SharedImageBacking
+  // to avoid this cast.
+  static_cast<SharedImageBackingD3D*>(backing())->BeginAccessD3D11();
+#endif
+  dawn_native::opengl::ExternalImageDescriptorEGLImage externalImageDesc;
+  externalImageDesc.cTextureDescriptor = &texture_descriptor_;
+  externalImageDesc.image = image_;
+  externalImageDesc.isInitialized = true;
+  texture_ =
+      dawn_native::opengl::WrapExternalEGLImage(device_, &externalImageDesc);
+  return texture_;
+}
+
+void SharedImageRepresentationDawnEGLImage::EndAccess() {
+  if (!texture_) {
+    return;
+  }
+  if (dawn_native::IsTextureSubresourceInitialized(texture_, 0, 1, 0, 1)) {
+    SetCleared();
+  }
+#if defined(OS_WIN)
+  // TODO(senorblanco): This should probably be a virtual on SharedImageBacking
+  // to avoid this cast.
+  static_cast<SharedImageBackingD3D*>(backing())->EndAccessD3D11();
+#endif
+  // All further operations on the textures are errors (they would be racy
+  // with other backings).
+  dawn_procs_.textureDestroy(texture_);
+  dawn_procs_.textureRelease(texture_);
+  texture_ = nullptr;
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.h b/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.h
new file mode 100644
index 0000000..baa82154
--- /dev/null
+++ b/gpu/command_buffer/service/shared_image_representation_dawn_egl_image.h
@@ -0,0 +1,40 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_DAWN_EGL_IMAGE_H_
+#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_DAWN_EGL_IMAGE_H_
+
+#include "gpu/command_buffer/service/shared_image_representation.h"
+
+typedef void* EGLImage;
+
+namespace gpu {
+
+class GPU_GLES2_EXPORT SharedImageRepresentationDawnEGLImage
+    : public SharedImageRepresentationDawn {
+ public:
+  SharedImageRepresentationDawnEGLImage(
+      SharedImageManager* manager,
+      SharedImageBacking* backing,
+      MemoryTypeTracker* tracker,
+      WGPUDevice device,
+      EGLImage image,
+      const WGPUTextureDescriptor& texture_descriptor);
+  ~SharedImageRepresentationDawnEGLImage() override;
+
+ private:
+  WGPUTexture BeginAccess(WGPUTextureUsage usage) override;
+  void EndAccess() override;
+
+ private:
+  WGPUDevice device_;
+  EGLImage image_;
+  WGPUTextureDescriptor texture_descriptor_;
+  DawnProcTable dawn_procs_;
+  WGPUTexture texture_ = nullptr;
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_DAWN_EGL_IMAGE_H_
diff --git a/gpu/command_buffer/service/webgpu_cmd_validation.cc b/gpu/command_buffer/service/webgpu_cmd_validation.cc
index d87568d..7bd602e7 100644
--- a/gpu/command_buffer/service/webgpu_cmd_validation.cc
+++ b/gpu/command_buffer/service/webgpu_cmd_validation.cc
@@ -5,6 +5,8 @@
 // Contains various validation functions for the Webgpu service.
 
 #include "gpu/command_buffer/service/webgpu_cmd_validation.h"
+
+#include "base/cxx17_backports.h"
 #include "gpu/command_buffer/service/gl_utils.h"
 
 namespace gpu {
diff --git a/gpu/command_buffer/service/webgpu_cmd_validation.h b/gpu/command_buffer/service/webgpu_cmd_validation.h
index 5b43276..12cd952 100644
--- a/gpu/command_buffer/service/webgpu_cmd_validation.h
+++ b/gpu/command_buffer/service/webgpu_cmd_validation.h
@@ -7,7 +7,6 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_WEBGPU_CMD_VALIDATION_H_
 #define GPU_COMMAND_BUFFER_SERVICE_WEBGPU_CMD_VALIDATION_H_
 
-#include "base/stl_util.h"
 #include "gpu/command_buffer/common/webgpu_cmd_enums.h"
 #include "gpu/command_buffer/common/webgpu_cmd_format.h"
 #include "gpu/command_buffer/service/value_validator.h"
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index c1f886f..09ed847 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -5,6 +5,7 @@
 #include "gpu/command_buffer/service/webgpu_decoder_impl.h"
 
 #include <dawn_native/DawnNative.h>
+#include <dawn_native/OpenGLBackend.h>
 #include <dawn_platform/DawnPlatform.h>
 #include <dawn_wire/WireServer.h>
 
@@ -29,6 +30,8 @@
 #include "gpu/command_buffer/service/webgpu_decoder.h"
 #include "gpu/config/gpu_preferences.h"
 #include "ipc/ipc_channel.h"
+#include "ui/gl/gl_context_egl.h"
+#include "ui/gl/gl_surface_egl.h"
 
 #if defined(OS_WIN)
 #include <dawn_native/D3D12Backend.h>
@@ -181,7 +184,12 @@
     return nullptr;
   }
   void Destroy(bool have_context) override;
-  bool MakeCurrent() override { return true; }
+  bool MakeCurrent() override {
+    if (gl_context_.get()) {
+      gl_context_->MakeCurrent(gl_surface_.get());
+    }
+    return true;
+  }
   gl::GLContext* GetGLContext() override { return nullptr; }
   gl::GLSurface* GetGLSurface() override {
     NOTREACHED();
@@ -438,6 +446,7 @@
   std::vector<dawn_native::Adapter> dawn_adapters_;
 
   bool allow_spirv_ = false;
+  bool force_webgpu_compat_ = false;
   std::vector<std::string> force_enabled_toggles_;
   std::vector<std::string> force_disabled_toggles_;
 
@@ -466,6 +475,9 @@
 
   bool has_polling_work_ = false;
 
+  scoped_refptr<gl::GLContext> gl_context_;
+  scoped_refptr<gl::GLSurface> gl_surface_;
+
   DISALLOW_COPY_AND_ASSIGN(WebGPUDecoderImpl);
 };
 
@@ -525,6 +537,7 @@
   }
 
   allow_spirv_ = gpu_preferences.enable_webgpu_spirv;
+  force_webgpu_compat_ = gpu_preferences.force_webgpu_compat;
   force_enabled_toggles_ = gpu_preferences.enabled_dawn_features_list;
   force_disabled_toggles_ = gpu_preferences.disabled_dawn_features_list;
 
@@ -545,6 +558,15 @@
 }
 
 ContextResult WebGPUDecoderImpl::Initialize() {
+  if (force_webgpu_compat_) {
+    gl_surface_ = new gl::SurfacelessEGL(gfx::Size(1, 1));
+    gl::GLContextAttribs attribs;
+    attribs.client_major_es_version = 3;
+    attribs.client_minor_es_version = 1;
+    gl_context_ = new gl::GLContextEGL(nullptr);
+    gl_context_->Initialize(gl_surface_.get(), attribs);
+    gl_context_->MakeCurrent(gl_surface_.get());
+  }
   DiscoverAdapters();
   return ContextResult::kSuccess;
 }
@@ -627,6 +649,16 @@
 }
 
 void WebGPUDecoderImpl::DiscoverAdapters() {
+#if BUILDFLAG(DAWN_ENABLE_BACKEND_OPENGLES)
+  if (force_webgpu_compat_) {
+    auto getProc = [](const char* pname) {
+      return reinterpret_cast<void*>(eglGetProcAddress(pname));
+    };
+    dawn_native::opengl::AdapterDiscoveryOptionsES optionsES;
+    optionsES.getProc = getProc;
+    dawn_instance_->DiscoverAdapters(&optionsES);
+  }
+#endif
 #if defined(OS_WIN)
   Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
       gl::QueryD3D11DeviceObjectFromANGLE();
@@ -647,8 +679,12 @@
 
   std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters();
   for (const dawn_native::Adapter& adapter : adapters) {
-    if (adapter.GetBackendType() != dawn_native::BackendType::Null &&
-        adapter.GetBackendType() != dawn_native::BackendType::OpenGL) {
+    if (force_webgpu_compat_) {
+      if (adapter.GetBackendType() == dawn_native::BackendType::OpenGLES) {
+        dawn_adapters_.push_back(adapter);
+      }
+    } else if (adapter.GetBackendType() != dawn_native::BackendType::Null &&
+               adapter.GetBackendType() != dawn_native::BackendType::OpenGL) {
       dawn_adapters_.push_back(adapter);
     }
   }
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index c464c404c..ac75405 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -389,6 +389,11 @@
   return increase;
 }
 
+bool IncreaseBufferCountForWebViewOverlays() {
+  return IsAndroidSurfaceControlEnabled() &&
+         base::FeatureList::IsEnabled(kWebViewSurfaceControl);
+}
+
 #endif
 
 }  // namespace features
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index e83c829..e77067d4 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -71,6 +71,7 @@
 GPU_EXPORT bool LimitAImageReaderMaxSizeToOne();
 GPU_EXPORT bool IsWebViewZeroCopyVideoEnabled();
 GPU_EXPORT bool IncreaseBufferCountForHighFrameRate();
+GPU_EXPORT bool IncreaseBufferCountForWebViewOverlays();
 #endif
 
 }  // namespace features
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index 9f82752..d475902e 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -12,6 +12,7 @@
 #include "base/bind_post_task.h"
 #include "base/command_line.h"
 #include "base/debug/crash_logging.h"
+#include "base/debug/dump_without_crashing.h"
 #include "base/location.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/run_loop.h"
@@ -25,6 +26,7 @@
 #include "gpu/command_buffer/common/context_creation_attribs.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/service/feature_info.h"
+#include "gpu/command_buffer/service/gl_utils.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
 #include "gpu/command_buffer/service/mailbox_manager_factory.h"
 #include "gpu/command_buffer/service/memory_program_cache.h"
@@ -44,6 +46,7 @@
 #include "ui/gl/gl_angle_util_win.h"
 #endif
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_enums.h"
 #include "ui/gl/gl_share_group.h"
 #include "ui/gl/gl_surface_egl.h"
 #include "ui/gl/gl_version_info.h"
@@ -83,6 +86,25 @@
 }
 #endif
 
+void APIENTRY CrashReportOnGLErrorDebugCallback(GLenum source,
+                                                GLenum type,
+                                                GLuint id,
+                                                GLenum severity,
+                                                GLsizei length,
+                                                const GLchar* message,
+                                                const GLvoid* user_param) {
+  if (type == GL_DEBUG_TYPE_ERROR && source == GL_DEBUG_SOURCE_API &&
+      user_param) {
+    LOG(ERROR) << gl::GLEnums::GetStringEnum(id) << ": " << message;
+    int* remaining_reports =
+        const_cast<int*>(static_cast<const int*>(user_param));
+    if (*remaining_reports > 0) {
+      base::debug::DumpWithoutCrashing();
+      (*remaining_reports)--;
+    }
+  }
+}
+
 void FormatAllocationSourcesForTracing(
     base::trace_event::TracedValue* dict,
     base::flat_map<GpuPeakMemoryAllocationSource, uint64_t>&
@@ -778,14 +800,6 @@
       // attribs.robust_resource_initialization = false;
     }
 
-    // Only skip validation if the GLContext will be used exclusively by the
-    // SharedContextState and dcheck is off.
-#if DCHECK_IS_ON()
-    attribs.can_skip_validation = false;
-#else
-    attribs.can_skip_validation = !use_virtualized_gl_contexts;
-#endif
-
     context =
         gl::init::CreateGLContext(share_group.get(), surface.get(), attribs);
     if (!context) {
@@ -840,6 +854,23 @@
     return nullptr;
   }
 
+  // Log crash reports when GL errors are generated.
+  if (gl::GetGLImplementation() == gl::kGLImplementationEGLANGLE &&
+      feature_info->feature_flags().khr_debug) {
+    static int remaining_gl_error_reports =
+#if defined(OS_ANDROID)
+        // Don't generate crash reports on Android due to errors generated
+        // during video decode.
+        0;
+#else
+        // Limit the total number of gl error crash reports to 1 per GPU
+        // process.
+        1;
+#endif
+    gles2::InitializeGLDebugLogging(false, CrashReportOnGLErrorDebugCallback,
+                                    &remaining_gl_error_reports);
+  }
+
   // OOP-R needs GrContext for raster tiles.
   bool need_gr_context =
       gpu_feature_info_.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
diff --git a/headless/test/headless_policy_browsertest.cc b/headless/test/headless_policy_browsertest.cc
index 8d2beee12..cd330e73 100644
--- a/headless/test/headless_policy_browsertest.cc
+++ b/headless/test/headless_policy_browsertest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/pattern.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
+#include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
@@ -233,7 +234,7 @@
   // DevTools starts its remote debugging port listener asynchronously and
   // there is no reliable way to know when it is started, so resort to an
   // ugly wait then check captured stderr.
-  base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(5));
+  base::PlatformThread::Sleep(TestTimeouts::action_timeout());
   capture_stderr_.StopCapture();
 
   enum { kUnknown, kDisallowed, kListening } remote_debugging_state = kUnknown;
diff --git a/infra/config/dev/subprojects/chromium/ci.star b/infra/config/dev/subprojects/chromium/ci.star
index 07110fe4..2a81ed2 100644
--- a/infra/config/dev/subprojects/chromium/ci.star
+++ b/infra/config/dev/subprojects/chromium/ci.star
@@ -35,6 +35,8 @@
     "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",
 )
 
+luci.recipe.defaults.use_bbagent.set(True)
+
 defaults.bucket.set("ci")
 defaults.build_numbers.set(True)
 defaults.builder_group.set("chromium.dev")
diff --git a/infra/config/generated/cr-buildbucket-dev.cfg b/infra/config/generated/cr-buildbucket-dev.cfg
index 9802f47..ff1908a 100644
--- a/infra/config/generated/cr-buildbucket-dev.cfg
+++ b/infra/config/generated/cr-buildbucket-dev.cfg
@@ -28,15 +28,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -71,15 +68,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -114,15 +108,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -164,15 +155,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -208,15 +196,12 @@
       dimensions: "builder:linux-ssd-rel-swarming"
       dimensions: "cpu:x86-64"
       dimensions: "os:Ubuntu-18.04"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -252,15 +237,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Mac-10.15"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -295,15 +277,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Windows-10"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
@@ -338,15 +317,12 @@
       swarming_tags: "vpython:native-python-wrapper"
       dimensions: "cpu:x86-64"
       dimensions: "os:Windows-10"
-      recipe {
-        name: "swarming/staging"
+      exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
         cipd_version: "refs/heads/master"
-        properties_j: "$build/goma:{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true}"
-        properties_j: "$recipe_engine/isolated:{\"server\":\"https://isolateserver-dev.appspot.com\"}"
-        properties_j: "$recipe_engine/resultdb/test_presentation:{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]}"
-        properties_j: "builder_group:\"chromium.dev\""
+        cmd: "luciexe"
       }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver-dev.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.dev\",\"recipe\":\"swarming/staging\"}"
       execution_timeout_secs: 10800
       build_numbers: YES
       service_account: "chromium-ci-builder-dev@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index bf841c9..3100175 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -2017,10 +2017,6 @@
         value: 50
       }
       experiments {
-        key: "chromium.isolate.use_new_lib"
-        value: 100
-      }
-      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -2886,6 +2882,74 @@
       }
     }
     builders {
+      name: "Comparison Linux"
+      swarming_host: "chromium-swarm.appspot.com"
+      swarming_tags: "vpython:native-python-wrapper"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-18.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/master"
+        cmd: "luciexe"
+      }
+      properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$build/reclient\":{\"instance\":\"rbe-chromium-trusted\",\"jobs\":500,\"metrics_project\":\"chromium-reclient-metrics\"},\"$kitchen\":{\"devshell\":true,\"emulate_gce\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.fyi\",\"recipe\":\"reclient_goma_comparison\"}"
+      execution_timeout_secs: 21600
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium.resultdb.result_sink"
+        value: 100
+      }
+      experiments {
+        key: "chromium.resultdb.result_sink.gtests_local"
+        value: 100
+      }
+      experiments {
+        key: "chromium.resultdb.result_sink.junit_tests"
+        value: 100
+      }
+      experiments {
+        key: "luci.use_realms"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "luci-resultdb"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "luci-resultdb"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+    }
+    builders {
       name: "CrWinAsan"
       swarming_host: "chromium-swarm.appspot.com"
       swarming_tags: "vpython:native-python-wrapper"
@@ -7722,10 +7786,6 @@
         value: 20
       }
       experiments {
-        key: "chromium.isolate.use_new_lib"
-        value: 100
-      }
-      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -28391,7 +28451,7 @@
         cipd_version: "refs/heads/master"
         cmd: "luciexe"
       }
-      properties: "{\"$build/code_coverage\":{\"coverage_test_types\":[\"overall\",\"unit\"],\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}"
+      properties: "{\"$build/code_coverage\":{\"coverage_reference_commit\":\"c942891373445199f69afd905965ad1e89cdee09\",\"coverage_test_types\":[\"overall\",\"unit\"],\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}"
       execution_timeout_secs: 72000
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -36333,6 +36393,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36344,10 +36408,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -36406,6 +36466,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36417,10 +36481,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -36479,6 +36539,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36490,10 +36554,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -36552,6 +36612,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36563,10 +36627,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -36625,6 +36685,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36636,10 +36700,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -36698,6 +36758,10 @@
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -36709,10 +36773,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38353,6 +38413,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38364,10 +38428,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38432,6 +38492,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38443,10 +38507,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38511,6 +38571,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38522,10 +38586,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38589,6 +38649,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38600,10 +38664,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38667,6 +38727,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38678,10 +38742,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38746,6 +38806,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38757,10 +38821,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38825,6 +38885,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38836,10 +38900,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38903,6 +38963,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38914,10 +38978,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -38982,6 +39042,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -38993,10 +39057,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39061,6 +39121,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39072,10 +39136,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39140,6 +39200,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39151,10 +39215,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39219,6 +39279,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39230,10 +39294,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39298,6 +39358,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39309,10 +39373,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39376,6 +39436,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39387,10 +39451,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39455,6 +39515,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39466,10 +39530,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39534,6 +39594,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39545,10 +39609,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39613,6 +39673,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39624,10 +39688,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39692,6 +39752,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39703,10 +39767,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39771,6 +39831,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39782,10 +39846,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39850,6 +39910,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39861,10 +39925,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -39929,6 +39989,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -39940,10 +40004,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40008,6 +40068,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40019,10 +40083,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40087,6 +40147,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40098,10 +40162,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40166,6 +40226,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40177,10 +40241,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40245,6 +40305,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40256,10 +40320,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40323,6 +40383,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40334,10 +40398,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40402,6 +40462,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40413,10 +40477,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40481,6 +40541,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40492,10 +40556,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40560,6 +40620,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40571,10 +40635,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40639,6 +40699,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40650,10 +40714,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40718,6 +40778,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40729,10 +40793,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40797,6 +40857,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40808,10 +40872,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40876,6 +40936,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40887,10 +40951,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -40955,6 +41015,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -40966,10 +41030,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41034,6 +41094,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41045,10 +41109,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41113,6 +41173,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41124,10 +41188,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41192,6 +41252,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41203,10 +41267,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41271,6 +41331,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41282,10 +41346,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41350,6 +41410,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41361,10 +41425,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41429,6 +41489,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41440,10 +41504,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41508,6 +41568,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41519,10 +41583,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41586,6 +41646,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41597,10 +41661,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41664,6 +41724,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41675,10 +41739,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41743,6 +41803,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41754,10 +41818,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41822,6 +41882,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41833,10 +41897,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41901,6 +41961,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41912,10 +41976,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -41980,6 +42040,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -41991,10 +42055,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42059,6 +42119,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42070,10 +42134,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42137,6 +42197,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42148,10 +42212,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42216,6 +42276,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42227,10 +42291,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42295,6 +42355,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42306,10 +42370,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42373,6 +42433,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42384,10 +42448,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42452,6 +42512,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42463,10 +42527,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42531,6 +42591,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42542,10 +42606,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42609,6 +42669,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42620,10 +42684,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42688,6 +42748,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42699,10 +42763,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42768,6 +42828,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42779,10 +42843,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42847,6 +42907,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42858,10 +42922,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -42925,6 +42985,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -42936,10 +43000,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43004,6 +43064,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43015,10 +43079,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43082,6 +43142,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43093,10 +43157,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43161,6 +43221,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43172,10 +43236,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43240,6 +43300,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43251,10 +43315,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43319,6 +43379,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43330,10 +43394,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43397,6 +43457,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43408,10 +43472,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43476,6 +43536,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43487,10 +43551,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43554,6 +43614,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43565,10 +43629,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43633,6 +43693,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43644,10 +43708,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43711,6 +43771,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43722,10 +43786,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43790,6 +43850,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43801,10 +43865,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43869,6 +43929,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43880,10 +43944,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -43949,6 +44009,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -43960,10 +44024,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44026,6 +44086,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44037,10 +44101,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44103,6 +44163,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44114,10 +44178,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44180,6 +44240,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44191,10 +44255,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44257,6 +44317,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44268,10 +44332,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44334,6 +44394,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44345,10 +44409,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44411,6 +44471,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44422,10 +44486,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44489,6 +44549,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44500,10 +44564,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44567,6 +44627,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44578,10 +44642,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44646,6 +44706,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44657,10 +44721,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44725,6 +44785,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44736,10 +44800,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44804,6 +44864,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44815,10 +44879,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44883,6 +44943,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44894,10 +44958,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -44962,6 +45022,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -44973,10 +45037,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45041,6 +45101,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45052,10 +45116,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45120,6 +45180,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45131,10 +45195,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45199,6 +45259,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45210,10 +45274,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45278,6 +45338,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45289,10 +45353,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45356,6 +45416,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45367,10 +45431,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45434,6 +45494,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45445,10 +45509,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45512,6 +45572,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45523,10 +45587,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45590,6 +45650,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45601,10 +45665,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45665,6 +45725,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45676,10 +45740,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45740,6 +45800,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45751,10 +45815,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45815,6 +45875,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45826,10 +45890,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45890,6 +45950,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45901,10 +45965,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -45965,6 +46025,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -45976,10 +46040,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46040,6 +46100,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46051,10 +46115,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46115,6 +46175,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46126,10 +46190,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46190,6 +46250,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46201,10 +46265,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46265,6 +46325,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46276,10 +46340,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46340,6 +46400,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46351,10 +46415,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46415,6 +46475,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46426,10 +46490,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46490,6 +46550,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46501,10 +46565,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46565,6 +46625,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46576,10 +46640,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46640,6 +46700,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46651,10 +46715,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46715,6 +46775,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46726,10 +46790,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46790,6 +46850,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46801,10 +46865,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46865,6 +46925,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46876,10 +46940,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -46940,6 +47000,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -46951,10 +47015,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47015,6 +47075,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47026,10 +47090,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47090,6 +47150,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47101,10 +47165,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47165,6 +47225,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47176,10 +47240,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47240,6 +47300,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47251,10 +47315,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47315,6 +47375,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47326,10 +47390,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47390,6 +47450,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47401,10 +47465,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47465,6 +47525,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47476,10 +47540,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47540,6 +47600,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47551,10 +47615,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47614,6 +47674,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47625,10 +47689,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47688,6 +47748,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47699,10 +47763,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47762,6 +47822,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47773,10 +47837,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47836,6 +47896,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47847,10 +47911,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47910,6 +47970,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47921,10 +47985,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -47984,6 +48044,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -47995,10 +48059,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48058,6 +48118,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48069,10 +48133,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48132,6 +48192,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48143,10 +48207,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48206,6 +48266,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48217,10 +48281,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48280,6 +48340,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48291,10 +48355,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48354,6 +48414,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48365,10 +48429,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48428,6 +48488,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48439,10 +48503,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48502,6 +48562,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48513,10 +48577,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48577,6 +48637,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48588,10 +48652,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48652,6 +48712,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48663,10 +48727,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48727,6 +48787,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48738,10 +48802,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48802,6 +48862,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48813,10 +48877,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48877,6 +48937,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48888,10 +48952,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -48952,6 +49012,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -48963,10 +49027,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49027,6 +49087,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49038,10 +49102,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49102,6 +49162,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49113,10 +49177,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49177,6 +49237,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49188,10 +49252,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49252,6 +49312,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49263,10 +49327,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49327,6 +49387,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49338,10 +49402,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49402,6 +49462,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49413,10 +49477,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49477,6 +49537,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49488,10 +49552,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49552,6 +49612,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49563,10 +49627,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49627,6 +49687,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49638,10 +49702,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49702,6 +49762,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49713,10 +49777,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49776,6 +49836,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49787,10 +49851,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49850,6 +49910,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49861,10 +49925,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -49925,6 +49985,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -49936,10 +50000,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50003,6 +50063,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50014,10 +50078,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50084,6 +50144,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50095,10 +50159,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50165,6 +50225,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50176,10 +50240,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50246,6 +50306,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50257,10 +50321,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50327,6 +50387,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50338,10 +50402,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50408,6 +50468,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50419,10 +50483,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50489,6 +50549,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50500,10 +50564,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50570,6 +50630,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50581,10 +50645,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50651,6 +50711,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50662,10 +50726,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50732,6 +50792,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50743,10 +50807,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50813,6 +50873,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50824,10 +50888,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50894,6 +50954,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50905,10 +50969,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -50975,6 +51035,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -50986,10 +51050,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51053,6 +51113,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51064,10 +51128,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51131,6 +51191,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51142,10 +51206,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51210,6 +51270,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51221,10 +51285,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51289,6 +51349,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51300,10 +51364,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51367,6 +51427,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51378,10 +51442,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51445,6 +51505,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51456,10 +51520,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51523,6 +51583,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51534,10 +51598,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51601,6 +51661,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51612,10 +51676,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51680,6 +51740,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51691,10 +51755,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51759,6 +51819,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51770,10 +51834,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51838,6 +51898,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51849,10 +51913,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51917,6 +51977,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -51928,10 +51992,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -51996,6 +52056,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52007,10 +52071,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52075,6 +52135,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52086,10 +52150,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52154,6 +52214,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52165,10 +52229,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52233,6 +52293,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52244,10 +52308,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52312,6 +52372,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52323,10 +52387,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52391,6 +52451,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52402,10 +52466,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52470,6 +52530,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52481,10 +52545,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52549,6 +52609,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52560,10 +52624,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52627,6 +52687,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52638,10 +52702,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52706,6 +52766,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52717,10 +52781,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52785,6 +52845,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52796,10 +52860,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52864,6 +52924,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52875,10 +52939,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -52942,6 +53002,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -52953,10 +53017,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53021,6 +53081,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53032,10 +53096,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53100,6 +53160,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53111,10 +53175,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53177,6 +53237,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53188,10 +53252,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53256,6 +53316,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53267,10 +53331,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53335,6 +53395,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53346,10 +53410,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53414,6 +53474,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53425,10 +53489,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53493,6 +53553,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53504,10 +53568,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53572,6 +53632,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53583,10 +53647,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53651,6 +53711,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53662,10 +53726,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53730,6 +53790,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53741,10 +53805,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53809,6 +53869,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53820,10 +53884,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53888,6 +53948,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53899,10 +53963,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -53966,6 +54026,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -53977,10 +54041,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54045,6 +54105,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54056,10 +54120,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54124,6 +54184,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54135,10 +54199,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54203,6 +54263,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54214,10 +54278,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54281,6 +54341,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54292,10 +54356,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54360,6 +54420,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54371,10 +54435,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54438,6 +54498,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54449,10 +54513,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54515,6 +54575,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54526,10 +54590,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54593,6 +54653,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54604,10 +54668,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54672,6 +54732,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54683,10 +54747,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54750,6 +54810,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54761,10 +54825,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54826,6 +54886,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54837,10 +54901,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54902,6 +54962,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54913,10 +54977,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -54978,6 +55038,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -54989,10 +55053,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55054,6 +55114,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55065,10 +55129,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55133,6 +55193,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55144,10 +55208,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55212,6 +55272,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55223,10 +55287,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55291,6 +55351,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55302,10 +55366,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55370,6 +55430,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55381,10 +55445,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55449,6 +55509,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55460,10 +55524,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55528,6 +55588,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55539,10 +55603,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55607,6 +55667,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55618,10 +55682,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55686,6 +55746,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55697,10 +55761,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55764,6 +55824,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55775,10 +55839,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55843,6 +55903,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55854,10 +55918,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -55922,6 +55982,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -55933,10 +55997,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56001,6 +56061,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56012,10 +56076,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56080,6 +56140,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56091,10 +56155,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56159,6 +56219,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56170,10 +56234,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56238,6 +56298,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56249,10 +56313,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56317,6 +56377,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56328,10 +56392,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56396,6 +56456,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56407,10 +56471,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56475,6 +56535,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56486,10 +56550,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56557,6 +56617,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56568,10 +56632,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56636,6 +56696,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56647,10 +56711,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56719,6 +56779,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56730,10 +56794,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56798,6 +56858,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56809,10 +56873,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56876,6 +56936,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56887,10 +56951,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -56954,6 +57014,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -56965,10 +57029,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57033,6 +57093,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57044,10 +57108,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57112,6 +57172,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57123,10 +57187,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57191,6 +57251,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57202,10 +57266,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57270,6 +57330,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57281,10 +57345,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57349,6 +57409,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57360,10 +57424,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57427,6 +57487,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57438,10 +57502,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57506,6 +57566,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57517,10 +57581,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57585,6 +57645,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57596,10 +57660,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57662,6 +57722,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57673,10 +57737,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57739,6 +57799,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57750,10 +57814,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57817,6 +57877,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57828,10 +57892,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57894,6 +57954,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57905,10 +57969,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -57972,6 +58032,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -57983,10 +58047,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58049,6 +58109,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58060,10 +58124,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58127,6 +58187,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58138,10 +58202,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58205,6 +58265,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58216,10 +58280,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58283,6 +58343,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58294,10 +58358,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58357,6 +58417,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58368,10 +58432,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58434,6 +58494,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58445,10 +58509,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58511,6 +58571,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58522,10 +58586,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58589,6 +58649,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58600,10 +58664,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58667,6 +58727,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58678,10 +58742,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58745,6 +58805,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58756,10 +58820,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58823,6 +58883,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58834,10 +58898,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58901,6 +58961,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58912,10 +58976,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -58979,6 +59039,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -58990,10 +59054,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59057,6 +59117,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59068,10 +59132,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59135,6 +59195,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59146,10 +59210,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59213,6 +59273,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59224,10 +59288,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59291,6 +59351,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59302,10 +59366,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59369,6 +59429,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59380,10 +59444,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59447,6 +59507,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59458,10 +59522,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59525,6 +59585,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59536,10 +59600,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59603,6 +59663,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59614,10 +59678,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59681,6 +59741,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59692,10 +59756,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59759,6 +59819,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59770,10 +59834,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59836,6 +59896,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59847,10 +59911,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59914,6 +59974,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -59925,10 +59989,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -59992,6 +60052,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60003,10 +60067,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60071,6 +60131,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60082,10 +60146,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60150,6 +60210,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60161,10 +60225,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60229,6 +60289,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60240,10 +60304,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60308,6 +60368,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60319,10 +60383,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60387,6 +60447,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60398,10 +60462,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60465,6 +60525,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60476,10 +60540,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60543,6 +60603,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60554,10 +60618,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60621,6 +60681,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60632,10 +60696,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60699,6 +60759,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60710,10 +60774,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60778,6 +60838,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60789,10 +60853,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60857,6 +60917,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60868,10 +60932,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -60936,6 +60996,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -60947,10 +61011,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61013,6 +61073,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61024,10 +61088,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61091,6 +61151,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61102,10 +61166,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61170,6 +61230,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61181,10 +61245,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61246,6 +61306,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61257,10 +61321,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61322,6 +61382,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61333,10 +61397,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61398,6 +61458,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61409,10 +61473,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61474,6 +61534,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61485,10 +61549,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61550,6 +61610,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61561,10 +61625,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61626,6 +61686,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61637,10 +61701,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61702,6 +61762,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61713,10 +61777,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61781,6 +61841,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61792,10 +61856,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61860,6 +61920,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61871,10 +61935,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -61939,6 +61999,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -61950,10 +62014,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62002,7 +62062,7 @@
         cipd_version: "refs/heads/master"
         cmd: "luciexe"
       }
-      properties: "{\"$build/goma\":{\"enable_ats\":false,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.win\",\"orchestrator\":{\"builder_group\":\"tryserver.chromium.win\",\"builder_name\":\"win10-orchestrator\"},\"recipe\":\"chromium/compilator\"}"
+      properties: "{\"$build/goma\":{\"enable_ats\":false,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.win\",\"orchestrator\":{\"builder_group\":\"tryserver.chromium.win\",\"builder_name\":\"win10-rel-orchestrator\"},\"recipe\":\"chromium/compilator\"}"
       execution_timeout_secs: 14400
       expiration_secs: 7200
       grace_period {
@@ -62018,6 +62078,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62029,10 +62093,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62080,7 +62140,7 @@
         cipd_version: "refs/heads/master"
         cmd: "luciexe"
       }
-      properties: "{\"$build/code_coverage\":{\"coverage_test_types\":[\"unit\",\"overall\"],\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.linux\",\"compilator\":\"win10-compilator\",\"recipe\":\"chromium/orchestrator\"}"
+      properties: "{\"$build/code_coverage\":{\"coverage_test_types\":[\"unit\",\"overall\"],\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"$recipe_engine/resultdb/test_presentation\":{\"column_keys\":[],\"grouping_keys\":[\"status\",\"v.test_suite\"]},\"builder_group\":\"tryserver.chromium.win\",\"compilator\":\"win10-rel-compilator\",\"recipe\":\"chromium/orchestrator\"}"
       execution_timeout_secs: 14400
       expiration_secs: 7200
       grace_period {
@@ -62096,6 +62156,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62107,10 +62171,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62175,6 +62235,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62186,10 +62250,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62254,6 +62314,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62265,10 +62329,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62332,6 +62392,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62343,10 +62407,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62411,6 +62471,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62422,10 +62486,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62490,6 +62550,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62501,10 +62565,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62568,6 +62628,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62579,10 +62643,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62646,6 +62706,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62657,10 +62721,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62725,6 +62785,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62736,10 +62800,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62804,6 +62864,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62815,10 +62879,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62883,6 +62943,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62894,10 +62958,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -62962,6 +63022,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -62973,10 +63037,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63041,6 +63101,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63052,10 +63116,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63120,6 +63180,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63131,10 +63195,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63199,6 +63259,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63210,10 +63274,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63278,6 +63338,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63289,10 +63353,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63357,6 +63417,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63368,10 +63432,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63436,6 +63496,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63447,10 +63511,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63514,6 +63574,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63525,10 +63589,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -63593,6 +63653,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.chromium_tests.use_rbe_cas"
+        value: 5
+      }
+      experiments {
         key: "chromium.resultdb.result_sink"
         value: 100
       }
@@ -63604,10 +63668,6 @@
         key: "luci.use_realms"
         value: 100
       }
-      experiments {
-        key: "use_rbe_cas"
-        value: 5
-      }
       resultdb {
         enable: true
         bq_exports {
diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg
index 9ef521a..bbc9cb1d 100644
--- a/infra/config/generated/luci-milo.cfg
+++ b/infra/config/generated/luci-milo.cfg
@@ -6199,6 +6199,11 @@
     short_name: "c32rg"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/Comparison Linux"
+    category: "linux"
+    short_name: "cmp"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/Leak Detection Linux"
     category: "linux"
     short_name: "lk"
@@ -15145,9 +15150,6 @@
   builders {
     name: "buildbucket/luci.chromium.try/tricium-simple"
   }
-  builders {
-    name: "buildbucket/luci.chromium.try/win10-rel-orchestrator"
-  }
   builder_view_only: true
 }
 consoles {
@@ -15420,6 +15422,9 @@
     name: "buildbucket/luci.chromium.try/win10-rel-compilator"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/win10-rel-orchestrator"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng"
   }
   builders {
diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg
index e98daae..e13fb34 100644
--- a/infra/config/generated/luci-scheduler.cfg
+++ b/infra/config/generated/luci-scheduler.cfg
@@ -684,6 +684,16 @@
   }
 }
 job {
+  id: "Comparison Linux"
+  realm: "ci"
+  acl_sets: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "luci.chromium.ci"
+    builder: "Comparison Linux"
+  }
+}
+job {
   id: "CrWinAsan"
   realm: "ci"
   acl_sets: "ci"
@@ -7036,6 +7046,7 @@
   triggers: "ChromeOS FYI Release (amd64-generic)"
   triggers: "ChromeOS FYI Release (kevin)"
   triggers: "ChromiumOS ASAN Release"
+  triggers: "Comparison Linux"
   triggers: "CrWinAsan"
   triggers: "CrWinAsan(dll)"
   triggers: "Dawn Linux x64 Builder"
diff --git a/infra/config/lib/try.star b/infra/config/lib/try.star
index 0d58877..15caeaf 100644
--- a/infra/config/lib/try.star
+++ b/infra/config/lib/try.star
@@ -168,7 +168,7 @@
             fail("Try Windows builder {} must disable ATS".format(name))
 
     # TODO(crbug.com/1143122): remove this after migration.
-    experiments["use_rbe_cas"] = 5
+    experiments["chromium.chromium_tests.use_rbe_cas"] = 5
 
     # Define the builder first so that any validation of luci.builder arguments
     # (e.g. bucket) occurs before we try to use it
diff --git a/infra/config/recipes.star b/infra/config/recipes.star
index 75c79f5..632869e 100644
--- a/infra/config/recipes.star
+++ b/infra/config/recipes.star
@@ -148,6 +148,10 @@
 )
 
 build_recipe(
+    name = "recipe:reclient_goma_comparison",
+)
+
+build_recipe(
     name = "recipe:swarming/deterministic_build",
 )
 
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index ec19318..a42d450 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -572,8 +572,6 @@
     experiments = {
         # TODO(crbug.com/1143122): remove this.
         "chromium.chromium_tests.use_rbe_cas": 50,
-        # TODO(crbug.com/1225524): remove this.
-        "chromium.isolate.use_new_lib": 100,
     },
 )
 
@@ -3755,6 +3753,21 @@
 )
 
 ci.fyi_builder(
+    name = "Comparison Linux",
+    console_view_entry = consoles.console_view_entry(
+        category = "linux",
+        short_name = "cmp",
+    ),
+    executable = "recipe:reclient_goma_comparison",
+    execution_timeout = 6 * time.hour,
+    reclient_instance = rbe_instance.DEFAULT,
+    reclient_jobs = 500,
+    configure_kitchen = True,
+    kitchen_emulate_gce = True,
+    os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT,
+)
+
+ci.fyi_builder(
     name = "Linux TSan Builder (goma cache silo)",
     console_view_entry = consoles.console_view_entry(
         category = "linux",
@@ -4188,6 +4201,8 @@
     ),
     use_clang_coverage = True,
     coverage_test_types = ["overall", "unit"],
+    # last commit of 2020
+    coverage_reference_commit = "c942891373445199f69afd905965ad1e89cdee09",
     triggered_by = [],
 )
 
@@ -5290,8 +5305,6 @@
     experiments = {
         # TODO(crbug.com/1143122): remove this.
         "chromium.chromium_tests.use_rbe_cas": 20,
-        # TODO(crbug.com/1225524): remove this.
-        "chromium.isolate.use_new_lib": 100,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star
index ce06af13..130db17d 100644
--- a/infra/config/subprojects/chromium/try.star
+++ b/infra/config/subprojects/chromium/try.star
@@ -1853,16 +1853,17 @@
     tryjob = try_.job(),
 )
 
-try_.chromium_linux_builder(
+try_.chromium_win_builder(
     name = "win10-rel-orchestrator",
     branch_selector = branches.STANDARD_MILESTONE,
     builderless = False,
     cores = 2,
+    os = os.LINUX_BIONIC,
     executable = "recipe:chromium/orchestrator",
     use_clang_coverage = True,
     coverage_test_types = ["unit", "overall"],
     properties = {
-        "compilator": "win10-compilator",
+        "compilator": "win10-rel-compilator",
     },
     service_account = "chromium-orchestrator@chops-service-accounts.iam.gserviceaccount.com",
 )
@@ -1878,7 +1879,7 @@
     executable = "recipe:chromium/compilator",
     properties = {
         "orchestrator": {
-            "builder_name": "win10-orchestrator",
+            "builder_name": "win10-rel-orchestrator",
             "builder_group": "tryserver.chromium.win",
         },
     },
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index e1633f2..64a9cba 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -150,10 +150,9 @@
   deps = [
     "//components/ntp_snippets",
     "//components/previous_session_info",
-    "//ios/chrome/app/application_delegate:app_state_header",
+    "//ios/chrome/app/application_delegate:observing_app_state_agent",
     "//ios/chrome/browser/metrics",
     "//ios/chrome/browser/ntp_snippets",
-    "//ios/chrome/browser/ui/main:scene_state_header",
   ]
 }
 
@@ -165,11 +164,10 @@
   ]
   deps = [
     "//base",
-    "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/app/application_delegate:application_delegate_internal",
+    "//ios/chrome/app/application_delegate:observing_app_state_agent",
     "//ios/chrome/browser/metrics",
     "//ios/chrome/browser/ui/main:scene",
-    "//ios/chrome/browser/ui/main:scene_state_header",
   ]
 }
 
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn
index 8b0eaa2..da405b23 100644
--- a/ios/chrome/app/application_delegate/BUILD.gn
+++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -154,6 +154,24 @@
   ]
 }
 
+source_set("observing_app_state_agent") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+
+  sources = [
+    "observing_app_state_agent.h",
+    "observing_app_state_agent.mm",
+  ]
+
+  frameworks = [ "UIKit.framework" ]
+
+  deps = [ "//base" ]
+
+  public_deps = [
+    ":app_state_header",
+    "//ios/chrome/browser/ui/main:scene_state_header",
+  ]
+}
+
 source_set("application_delegate_internal") {
   configs += [ "//build/config/compiler:enable_arc" ]
   public_deps = [ ":app_state_header" ]
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 376927a9..6323ffb 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -265,10 +265,14 @@
     scoped_refptr<net::URLRequestContextGetter> getter =
         currentInterface.browserState->GetRequestContext();
     _savingCookies = YES;
+    __weak AppState* weakSelf = self;
+
     __block base::OnceClosure criticalClosure = base::MakeCriticalClosure(
         "applicationDidEnterBackground:_savingCookies", base::BindOnce(^{
           DCHECK_CURRENTLY_ON(web::WebThread::UI);
-          self->_savingCookies = NO;
+          AppState* strongSelf = weakSelf;
+          if (strongSelf)
+            strongSelf->_savingCookies = NO;
         }));
     base::PostTask(
         FROM_HERE, {web::WebThread::IO}, base::BindOnce(^{
@@ -336,7 +340,7 @@
   [metricsMediator updateMetricsStateBasedOnPrefsUserTriggered:NO];
 
   // Send any feedback that might be still on temporary storage.
-  ios::GetChromeBrowserProvider()->GetUserFeedbackProvider()->Synchronize();
+  ios::GetChromeBrowserProvider().GetUserFeedbackProvider()->Synchronize();
 
   GetApplicationContext()->OnAppEnterForeground();
 
@@ -380,9 +384,8 @@
   [_appCommandDispatcher prepareForShutdown];
 
   // Cancel any in-flight distribution notifications.
-  CHECK(ios::GetChromeBrowserProvider());
   ios::GetChromeBrowserProvider()
-      ->GetAppDistributionProvider()
+      .GetAppDistributionProvider()
       ->CancelDistributionNotifications();
 
   // Halt the tabs, so any outstanding requests get cleaned up, without actually
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index 370a386..fffbba8 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -736,7 +736,7 @@
   }
   FakeAppDistributionProvider* provider =
       static_cast<FakeAppDistributionProvider*>(
-          ios::GetChromeBrowserProvider()->GetAppDistributionProvider());
+          ios::GetChromeBrowserProvider().GetAppDistributionProvider());
   EXPECT_TRUE(provider->cancel_called());
 }
 
@@ -796,7 +796,7 @@
   EXPECT_OCMOCK_VERIFY(getStartupInformationMock());
   FakeUserFeedbackProvider* user_feedback_provider =
       static_cast<FakeUserFeedbackProvider*>(
-          ios::GetChromeBrowserProvider()->GetUserFeedbackProvider());
+          ios::GetChromeBrowserProvider().GetUserFeedbackProvider());
   EXPECT_TRUE(user_feedback_provider->synchronize_called());
 }
 
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm
index 615ac1f..ce2ad68f 100644
--- a/ios/chrome/app/application_delegate/metrics_mediator.mm
+++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -368,7 +368,7 @@
     PrefService* prefs = GetApplicationContext()->GetLocalState();
     NSString* brandCode =
         base::SysUTF8ToNSString(ios::GetChromeBrowserProvider()
-                                    ->GetAppDistributionProvider()
+                                    .GetAppDistributionProvider()
                                     ->GetDistributionBrandCode());
 
     app_group::main_app::EnableMetrics(
diff --git a/ios/chrome/app/application_delegate/observing_app_state_agent.h b/ios/chrome/app/application_delegate/observing_app_state_agent.h
new file mode 100644
index 0000000..fe71e26
--- /dev/null
+++ b/ios/chrome/app/application_delegate/observing_app_state_agent.h
@@ -0,0 +1,58 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_APP_APPLICATION_DELEGATE_OBSERVING_APP_STATE_AGENT_H_
+#define IOS_CHROME_APP_APPLICATION_DELEGATE_OBSERVING_APP_STATE_AGENT_H_
+
+#import "ios/chrome/app/application_delegate/app_state_agent.h"
+#import "ios/chrome/app/application_delegate/app_state_observer.h"
+#import "ios/chrome/browser/ui/main/scene_state_observer.h"
+
+// An app agent that acts as a app state observer.
+// Since most agents are also app state observers, this is a convenience base
+// class that provides universally useful functionality for app agents.
+@interface ObservingAppAgent : NSObject <AppStateAgent, AppStateObserver>
+
+// App state this agent serves and observes.
+@property(nonatomic, weak) AppState* appState;
+
+@end
+
+// An App Agent that observes the AppState and every connected scene.
+// Provides some convenient synthetic events.
+// Use this class when you want to observe some simple event that is made
+// complicated because of the multiple windows, e.g. "the app is foreground".
+// Extend this class with new events as necessary.
+@interface SceneObservingAppAgent : ObservingAppAgent <SceneStateObserver>
+
+// For convenience overridable events below, the events will not be delivered
+// until this stage is reached. The default is Final.
+@property(nonatomic, assign) InitStage minimumStageForNotifications;
+
+// For convenience overridable events below, will call events such as "some
+// scene is foreground" if the conditions are met when the minimum init stage is
+// reached. The default is YES.
+@property(nonatomic, assign) BOOL notifyOfPastEventsWhenMinimumStageReached;
+
+// Overridable methods.
+
+// Called when the app enters foreground, e.g. any scene is foreground.
+// See also minimumStageForNotifications.
+- (void)appDidEnterForeground;
+
+// Called when the app enters background, e.g. no scene is foreground.
+// See also minimumStageForNotifications.
+- (void)appDidEnterBackground;
+
+// Require super calls for overriden observer callbacks:
+- (void)appState:(AppState*)appState
+    sceneConnected:(SceneState*)sceneState NS_REQUIRES_SUPER;
+- (void)appState:(AppState*)appState
+    didTransitionFromInitStage:(InitStage)previousInitStage NS_REQUIRES_SUPER;
+- (void)sceneState:(SceneState*)sceneState
+    transitionedToActivationLevel:(SceneActivationLevel)level NS_REQUIRES_SUPER;
+
+@end
+
+#endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_OBSERVING_APP_STATE_AGENT_H_
diff --git a/ios/chrome/app/application_delegate/observing_app_state_agent.mm b/ios/chrome/app/application_delegate/observing_app_state_agent.mm
new file mode 100644
index 0000000..f1d390e
--- /dev/null
+++ b/ios/chrome/app/application_delegate/observing_app_state_agent.mm
@@ -0,0 +1,101 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/app/application_delegate/observing_app_state_agent.h"
+
+#include "base/check.h"
+#import "ios/chrome/app/application_delegate/app_state.h"
+#import "ios/chrome/browser/ui/main/scene_state.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation ObservingAppAgent
+
+#pragma mark - AppStateAgent
+
+- (void)setAppState:(AppState*)appState {
+  // This should only be called once!
+  DCHECK(!_appState);
+
+  _appState = appState;
+  [appState addObserver:self];
+}
+
+@end
+
+#pragma mark - SceneObservingAppAgent
+
+@interface SceneObservingAppAgent ()
+
+// Tracks if the app has already notified that some scenes are in foreground.
+// Reset when the app goes background.
+@property(nonatomic, assign) BOOL notifiedForeground;
+// Tracks if the app has already notified that some scenes are in background.
+// Reset when the app goes foreground.
+@property(nonatomic, assign) BOOL notifiedBackground;
+
+@end
+
+@implementation SceneObservingAppAgent
+
+- (instancetype)init {
+  self = [super init];
+  if (self) {
+    _minimumStageForNotifications = InitStageFinal;
+    _notifyOfPastEventsWhenMinimumStageReached = YES;
+    // The app starts with no connected scenes, so the first event should be
+    // foreground.
+    _notifiedBackground = YES;
+  }
+  return self;
+}
+
+#pragma mark - AppStateObserver
+
+- (void)appState:(AppState*)appState sceneConnected:(SceneState*)sceneState {
+  [sceneState addObserver:self];
+}
+
+- (void)appState:(AppState*)appState
+    didTransitionFromInitStage:(InitStage)previousInitStage {
+  if (appState.initStage == self.minimumStageForNotifications &&
+      self.notifyOfPastEventsWhenMinimumStageReached) {
+    [self notifyOfConvenienceEventsIfNecessary];
+  }
+}
+
+#pragma mark - SceneStateObserver
+
+- (void)sceneState:(SceneState*)sceneState
+    transitionedToActivationLevel:(SceneActivationLevel)level {
+  if (self.appState.initStage <= self.minimumStageForNotifications) {
+    return;
+  }
+
+  [self notifyOfConvenienceEventsIfNecessary];
+}
+
+- (void)notifyOfConvenienceEventsIfNecessary {
+  if (self.appState.foregroundScenes.count > 0 && !self.notifiedForeground) {
+    self.notifiedForeground = YES;
+    self.notifiedBackground = NO;
+    [self appDidEnterForeground];
+  }
+
+  if (self.appState.foregroundScenes.count == 0 && !self.notifiedBackground) {
+    self.notifiedBackground = YES;
+    self.notifiedForeground = NO;
+    [self appDidEnterBackground];
+  }
+}
+
+#pragma mark - template methods methods
+- (void)appDidEnterForeground {
+}
+- (void)appDidEnterBackground {
+}
+
+@end
diff --git a/ios/chrome/app/content_suggestions_scheduler_app_state_agent.h b/ios/chrome/app/content_suggestions_scheduler_app_state_agent.h
index 308846b..285eb66 100644
--- a/ios/chrome/app/content_suggestions_scheduler_app_state_agent.h
+++ b/ios/chrome/app/content_suggestions_scheduler_app_state_agent.h
@@ -5,11 +5,11 @@
 #ifndef IOS_CHROME_APP_CONTENT_SUGGESTIONS_SCHEDULER_APP_STATE_AGENT_H_
 #define IOS_CHROME_APP_CONTENT_SUGGESTIONS_SCHEDULER_APP_STATE_AGENT_H_
 
-#import "ios/chrome/app/application_delegate/app_state_agent.h"
+#import "ios/chrome/app/application_delegate/observing_app_state_agent.h"
 
 // The agent that notifies the content suggestions service about app lifecycle
 // events to keep the model up to date.
-@interface ContentSuggestionsSchedulerAppAgent : NSObject <AppStateAgent>
+@interface ContentSuggestionsSchedulerAppAgent : SceneObservingAppAgent
 @end
 
 #endif  // IOS_CHROME_APP_CONTENT_SUGGESTIONS_SCHEDULER_APP_STATE_AGENT_H_
diff --git a/ios/chrome/app/content_suggestions_scheduler_app_state_agent.mm b/ios/chrome/app/content_suggestions_scheduler_app_state_agent.mm
index fe98545..79cd03a 100644
--- a/ios/chrome/app/content_suggestions_scheduler_app_state_agent.mm
+++ b/ios/chrome/app/content_suggestions_scheduler_app_state_agent.mm
@@ -14,11 +14,7 @@
 #error "This file requires ARC support."
 #endif
 
-@interface ContentSuggestionsSchedulerAppAgent () <AppStateObserver,
-                                                   SceneStateObserver>
-
-// Observed app state.
-@property(nonatomic, weak) AppState* appState;
+@interface ContentSuggestionsSchedulerAppAgent ()
 
 // Flag to keep track if we notified the service once at the cold app start.
 @property(nonatomic, assign) BOOL hasNotifiedColdStart;
@@ -27,29 +23,10 @@
 
 @implementation ContentSuggestionsSchedulerAppAgent
 
-#pragma mark - AppStateAgent
-
-- (void)setAppState:(AppState*)appState {
-  // This should only be called once!
-  DCHECK(!_appState);
-
-  _appState = appState;
-  [appState addObserver:self];
-}
-
-#pragma mark - AppStateObserver
-
-- (void)appState:(AppState*)appState sceneConnected:(SceneState*)sceneState {
-  [sceneState addObserver:self];
-}
-
 #pragma mark - SceneStateObserver
 
-- (void)sceneState:(SceneState*)sceneState
-    transitionedToActivationLevel:(SceneActivationLevel)level {
-  if (level >= SceneActivationLevelForegroundInactive) {
-    [self notifyForeground];
-  }
+- (void)appDidEnterForeground {
+  [self notifyForeground];
 }
 
 #pragma mark - private
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index 3c55e423..f1b4865 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -165,7 +165,7 @@
 - (void)application:(UIApplication*)application
     didDiscardSceneSessions:(NSSet<UISceneSession*>*)sceneSessions {
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->ApplicationDidDiscardSceneSessions(sceneSessions);
   [_appState application:application didDiscardSceneSessions:sceneSessions];
 }
diff --git a/ios/chrome/app/main_application_delegate_unittest.mm b/ios/chrome/app/main_application_delegate_unittest.mm
index 671a03c..a7cae0b16 100644
--- a/ios/chrome/app/main_application_delegate_unittest.mm
+++ b/ios/chrome/app/main_application_delegate_unittest.mm
@@ -29,7 +29,7 @@
 
   // Save both ChromeBrowserProvider as MainController register new instance.
   ios::ChromeBrowserProvider* stashed_chrome_browser_provider =
-      ios::GetChromeBrowserProvider();
+      ios::SetChromeBrowserProvider(nullptr);
 
   id application = [OCMockObject niceMockForClass:[UIApplication class]];
   UIApplicationState backgroundState = UIApplicationStateBackground;
@@ -42,9 +42,13 @@
 
   // Restore both ChromeBrowserProvider to its original value and destroy
   // instances created by MainController.
-  DCHECK_NE(ios::GetChromeBrowserProvider(), stashed_chrome_browser_provider);
-  delete ios::GetChromeBrowserProvider();
-  ios::SetChromeBrowserProvider(stashed_chrome_browser_provider);
+  DCHECK_NE(&ios::GetChromeBrowserProvider(), stashed_chrome_browser_provider);
+
+  ios::ChromeBrowserProvider* registered_provider =
+      ios::SetChromeBrowserProvider(stashed_chrome_browser_provider);
+
+  EXPECT_TRUE(registered_provider);
+  delete registered_provider;
 }
 
 // Tests that the application does not crash if |applicationWillTerminate:| is
@@ -59,12 +63,14 @@
   // ios::GetChromeBrowserProvider() return nullptr. Clear the previously-set
   // provider before proceeding.
   ios::ChromeBrowserProvider* stashed_chrome_browser_provider =
-      ios::GetChromeBrowserProvider();
-  ios::SetChromeBrowserProvider(nullptr);
+      ios::SetChromeBrowserProvider(nullptr);
 
   MainApplicationDelegate* delegate = [[MainApplicationDelegate alloc] init];
   [delegate applicationWillTerminate:application];
 
   // Restore ChromeBrowserProvider to its original value.
-  ios::SetChromeBrowserProvider(stashed_chrome_browser_provider);
+  ios::ChromeBrowserProvider* registered_provider =
+      ios::SetChromeBrowserProvider(stashed_chrome_browser_provider);
+
+  EXPECT_FALSE(registered_provider);
 }
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 42b97485..a38da5e9 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -419,7 +419,7 @@
   _chromeMain = [ChromeMainStarter startChromeMain];
 
   // Initialize the ChromeBrowserProvider.
-  ios::GetChromeBrowserProvider()->Initialize();
+  ios::GetChromeBrowserProvider().Initialize();
 
   // If the user is interacting, crashes affect the user experience. Start
   // reporting as soon as possible.
@@ -548,7 +548,7 @@
       logLaunchMetricsWithStartupInformation:self
                              connectedScenes:self.appState.connectedScenes];
 
-  ios::GetChromeBrowserProvider()->GetOverridesProvider()->InstallOverrides();
+  ios::GetChromeBrowserProvider().GetOverridesProvider()->InstallOverrides();
 
   [self scheduleLowPriorityStartupTasks];
 
@@ -762,7 +762,7 @@
       enqueueBlockNamed:kSendQueuedFeedback
                   block:^{
                     ios::GetChromeBrowserProvider()
-                        ->GetUserFeedbackProvider()
+                        .GetUserFeedbackProvider()
                         ->Synchronize();
                   }];
 }
@@ -825,7 +825,7 @@
                                                 ->GetSharedURLLoaderFactory();
                     const bool is_first_run = FirstRun::IsChromeFirstRun();
                     ios::GetChromeBrowserProvider()
-                        ->GetAppDistributionProvider()
+                        .GetAppDistributionProvider()
                         ->ScheduleDistributionNotifications(URLLoaderFactory,
                                                             is_first_run);
 
@@ -834,7 +834,7 @@
                             metrics::prefs::kInstallDate));
 
                     ios::GetChromeBrowserProvider()
-                        ->GetAppDistributionProvider()
+                        .GetAppDistributionProvider()
                         ->InitializeFirebase(install_date, is_first_run);
                   }];
 }
@@ -937,13 +937,13 @@
                       return;
                     }
                     ios::GetChromeBrowserProvider()
-                        ->GetMailtoHandlerProvider()
+                        .GetMailtoHandlerProvider()
                         ->PrepareMailtoHandling(
                             strongSelf.appState.mainBrowserState);
 
                     [strongSelf registerCleanupClosure:base::BindOnce([] {
                                   ios::GetChromeBrowserProvider()
-                                      ->GetMailtoHandlerProvider()
+                                      .GetMailtoHandlerProvider()
                                       ->RemoveMailtoHandling();
                                 })];
                   }];
diff --git a/ios/chrome/app/spotlight/base_spotlight_manager.mm b/ios/chrome/app/spotlight/base_spotlight_manager.mm
index 0fa4c63f..dc27508 100644
--- a/ios/chrome/app/spotlight/base_spotlight_manager.mm
+++ b/ios/chrome/app/spotlight/base_spotlight_manager.mm
@@ -248,7 +248,7 @@
     l10n_util::GetNSString(IDS_IOS_SPOTLIGHT_KEYWORD_TEN)
   ]];
   NSArray* additionalArray = ios::GetChromeBrowserProvider()
-                                 ->GetSpotlightProvider()
+                                 .GetSpotlightProvider()
                                  ->GetAdditionalKeywords();
   if (additionalArray) {
     [keywordsArray addObjectsFromArray:additionalArray];
diff --git a/ios/chrome/app/spotlight/spotlight_manager_unittest.mm b/ios/chrome/app/spotlight/spotlight_manager_unittest.mm
index dc81e57a..2eeda63b 100644
--- a/ios/chrome/app/spotlight/spotlight_manager_unittest.mm
+++ b/ios/chrome/app/spotlight/spotlight_manager_unittest.mm
@@ -180,7 +180,7 @@
   // Check static/hardcoded keywords exist
   NSSet* hardCodedKeywordsSet =
       [NSSet setWithArray:ios::GetChromeBrowserProvider()
-                              ->GetSpotlightProvider()
+                              .GetSpotlightProvider()
                               ->GetAdditionalKeywords()];
   EXPECT_TRUE([hardCodedKeywordsSet isSubsetOfSet:spotlightManagerKeywords]);
 }
diff --git a/ios/chrome/app/spotlight/spotlight_util.mm b/ios/chrome/app/spotlight/spotlight_util.mm
index 808d2e0..c87bc68 100644
--- a/ios/chrome/app/spotlight/spotlight_util.mm
+++ b/ios/chrome/app/spotlight/spotlight_util.mm
@@ -84,7 +84,7 @@
 
 Domain SpotlightDomainFromString(NSString* domain) {
   SpotlightProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSpotlightProvider();
+      ios::GetChromeBrowserProvider().GetSpotlightProvider();
   if ([domain hasPrefix:[provider->GetBookmarkDomain()
                             stringByAppendingString:@"."]]) {
     return DOMAIN_BOOKMARKS;
@@ -103,7 +103,7 @@
 
 NSString* StringFromSpotlightDomain(Domain domain) {
   SpotlightProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSpotlightProvider();
+      ios::GetChromeBrowserProvider().GetSpotlightProvider();
   switch (domain) {
     case DOMAIN_BOOKMARKS:
       return provider->GetBookmarkDomain();
@@ -159,7 +159,7 @@
 
 bool IsSpotlightAvailable() {
   bool provided = ios::GetChromeBrowserProvider()
-                      ->GetSpotlightProvider()
+                      .GetSpotlightProvider()
                       ->IsSpotlightEnabled();
   if (!provided) {
     // The product does not support Spotlight, do not go further.
@@ -189,7 +189,7 @@
 
 NSString* GetSpotlightCustomAttributeItemID() {
   return ios::GetChromeBrowserProvider()
-      ->GetSpotlightProvider()
+      .GetSpotlightProvider()
       ->GetCustomAttributeItemID();
 }
 
diff --git a/ios/chrome/app/startup/provider_registration.mm b/ios/chrome/app/startup/provider_registration.mm
index cfa84a4..06dd5c8 100644
--- a/ios/chrome/app/startup/provider_registration.mm
+++ b/ios/chrome/app/startup/provider_registration.mm
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/app/startup/provider_registration.h"
 
+#include "base/check.h"
 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -17,7 +18,11 @@
       ios::CreateChromeBrowserProvider();
 
   // Leak the providers.
-  ios::SetChromeBrowserProvider(provider.release());
+  ios::ChromeBrowserProvider* previous_provider =
+      ios::SetChromeBrowserProvider(provider.release());
+
+  DCHECK(!previous_provider)
+      << "-registerProviders with an existing ChromeBrowserProvider registered";
 }
 
 @end
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index b33661d6..a33d6d9 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -550,16 +550,22 @@
         You won't be signed out of your Google Account. Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK">BEGIN_LINK</ph>history.google.com<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE" desc="Footer message in the settings to clear browsing data that informs the user they can seperately delete their search history and/or other account info at the 2 links provided.">
-        You won't be signed out of your Google Account. To clear <ph name="BEGIN_LINK">BEGIN_LINK</ph>search<ph name="END_LINK">END_LINK</ph> or other forms of history, visit <ph name="BEGIN_LINK">BEGIN_LINK</ph>My Google Account<ph name="END_LINK">END_LINK</ph>
+        <ph name="BEGIN_LINK">BEGIN_LINK</ph>Search history<ph name="END_LINK">END_LINK</ph> and <ph name="BEGIN_LINK">BEGIN_LINK</ph>other forms of activity<ph name="END_LINK">END_LINK</ph> may be saved in your Google Account when you’re signed in. You can delete them at any time.
       </message>
       <message name="IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN" desc="Footer message in the settings to clear browsing data that informs a signed in user that they will need to look up instructions to delete their search history from their DSE, as well as that they won't be signed out and where to delete other account data.">
-        Your search engine is <ph name="DSE_NAME">$1<ex>DuckDuckGo</ex></ph>. See their instructions for deleting your search history, if applicable. You won't be signed out of your Google Account. To clear other forms of history visit <ph name="BEGIN_LINK">BEGIN_LINK</ph>My Google Activity<ph name="END_LINK">END_LINK</ph>.
+        You won't be signed out of your Google Account. <ph name="BEGIN_LINK">BEGIN_LINK</ph>Other forms of activity<ph name="END_LINK">END_LINK</ph> may be saved in your Google Account when you’re signed in. You can delete them at any time.
+
+        
+Your search engine is <ph name="DSE_NAME">$1<ex>DuckDuckGo</ex></ph>. See their instructions for deleting your search history, if applicable.
       </message>
       <message name="IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_OUT" desc="Footer message in the settings to clear browsing data that informs the user that they will need to look up instructions to delete their search history from their DSE.">
         Your search engine is <ph name="DSE_NAME">$1<ex>DuckDuckGo</ex></ph>. See their instructions for deleting your search history, if applicable.
       </message>
       <message name="IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN" desc="Footer message in the settings to clear browsing data that informs a signed in user that they will need to look up instructions to delete their search history from a DSE that is not well known to Google, as well as that they won't be signed out and where to delete other account data.">
-        See your search engine’s instructions for deleting your search history, if applicable. You won't be signed out of your Google Account. To clear other forms of history visit <ph name="BEGIN_LINK">BEGIN_LINK</ph>My Google Activity<ph name="END_LINK">END_LINK</ph>.
+        You won't be signed out of your Google Account. <ph name="BEGIN_LINK">BEGIN_LINK</ph>Other forms of activity<ph name="END_LINK">END_LINK</ph> may be saved in your Google Account when you’re signed in. You can delete them at any time.
+
+
+See your search engine’s instructions for deleting your search history, if applicable.
       </message>
       <message name="IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_OUT" desc="Footer message in the settings to clear browsing data that informs the user that they will need to look up instructions to delete their search history from a DSE that is not well known to Google.">
         See your search engine’s instructions for deleting your search history, if applicable.
@@ -2325,14 +2331,11 @@
       <message name="IDS_IOS_SIGNOUT_DIALOG_KEEP_DATA_BUTTON" desc="This button signs the user out and all its data stays on the device. Related to IDS_IOS_SIGNOUT_DIALOG_TITLE [iOS only].">
         Keep Data
       </message>
-      <message name="IDS_IOS_SIGNOUT_DIALOG_TITLE_WITHOUT_SYNC" desc="The signout dialog title. This dialog is used when the user have a gmail account and sync is turned on. Related to IDS_IOS_SIGNOUT_DIALOG_MESSAGE [iOS only].">
-        Sign Out?
-      </message>
       <message name="IDS_IOS_SIGNOUT_DIALOG_SIGN_OUT_BUTTON" desc="This button signs the user out. Related to IDS_IOS_SIGNOUT_DIALOG_TITLE [iOS only].">
         Sign Out
       </message>
       <message name="IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC" desc="The text describes that sync will be off when user signs out [iOS only].">
-        This will turn off sync.
+        Signing out turns off sync.
       </message>
       <message name="IDS_IOS_SPOTLIGHT_KEYWORD_EIGHT" desc="Keyword used in Spotlight that will be linked to the Chrome App. [iOS only]">
         Online
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE.png.sha1
index 9a37aaf3..9345ce0 100644
--- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE.png.sha1
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE.png.sha1
@@ -1 +1 @@
-9dffc92004f80bae7473102c0f5714e0f898166a
\ No newline at end of file
+8c36a76fc84751b1484225cbbc9d8a357dca7ec2
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN.png.sha1
index ef3cdae0..ea99541 100644
--- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN.png.sha1
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN.png.sha1
@@ -1 +1 @@
-1bfe945c3dd5d611e2d86acd15b6116820fc270d
\ No newline at end of file
+ead95f55c7ae20ffb2572c23926b0dd02a8fbd3b
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN.png.sha1
index 6fa7a91..9428ae3 100644
--- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN.png.sha1
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN.png.sha1
@@ -1 +1 @@
-b15e0e1a8c7ab2110b703d50bc645b8ff2e1684a
\ No newline at end of file
+88bb6aa2c6e0faed414d9174c07d692c93b6d691
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC.png.sha1
index 2f76e13..5f498c7 100644
--- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC.png.sha1
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC.png.sha1
@@ -1 +1 @@
-7e222c42f17d90dfa957801bb868f41ac5b22e94
\ No newline at end of file
+2361f55752c3bc020d1c2da3d818eb1d52b0910a
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_TITLE_WITHOUT_SYNC.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_TITLE_WITHOUT_SYNC.png.sha1
deleted file mode 100644
index e9f25b9..0000000
--- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGNOUT_DIALOG_TITLE_WITHOUT_SYNC.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-47b2a8ec1b96d02ba7904a903d533fefef803c9a
\ No newline at end of file
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_kk.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_kk.xtb
index 58cdb79..5e301301 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_kk.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_kk.xtb
@@ -89,7 +89,7 @@
 <translation id="786327964234957808"><ph name="USER_EMAIL1" /> синхрондау есептік жазбаларын <ph name="USER_EMAIL2" /> жазбасына ауыстырудасыз. Қолданыстағы Chromium деректерін <ph name="DOMAIN" /> басқарады. Мұның нәтижесінде деректер құрылғыдан жойылады, бірақ <ph name="USER_EMAIL1" /> жазбасында сақталады.</translation>
 <translation id="7890287942691234100">Chromium сканерін пайдалана бастау</translation>
 <translation id="7928628054454574139">Басқа қолданбалардағы сілтемелерді түрткен сайын Chromium браузерін ашыңыз.</translation>
-<translation id="7931842119211730154">Chromium браузерін жабу кезінде инкогнито қойындыларын құлыптау</translation>
+<translation id="7931842119211730154">Chromium-ді жапқанда инкогнито қойындыларын құлыптау</translation>
 <translation id="7980860476903281594">Chromium геодерегіңізді сіз рұқсат еткен сайттармен бөліседі.</translation>
 <translation id="8013573822802650211">Chromium браузерін кез келген жерде пайдаланғанда, қойындыларды көру үшін барлық құрылғыларда есептік жазбаға кіріңіз.</translation>
 <translation id="8073677936375100957">Chromium деректері осы құрылғыдан жойылсын ба?</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_kk.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_kk.xtb
index b67e32e4..00b5dcd 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_kk.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_kk.xtb
@@ -38,7 +38,7 @@
 <translation id="3533694711092285624">Ешқандай құпия сөз сақталмаған. Құпия сөздер сақталған кезде, Chrome оларды тексере алады.</translation>
 <translation id="3634910711516114487">Chrome-ды барынша пайдалану үшін оған Google есептік жазбаңызбен кіріңіз.</translation>
 <translation id="3706101708757577809">Енді хабарларда, құжаттарда және басқа қолданбаларда сілтемелерді түртіп, Chrome браузерін кез келген уақытта пайдалана аласыз.</translation>
-<translation id="3720541637541300822">Chrome браузерін жабу кезінде инкогнито қойындыларын құлыптау</translation>
+<translation id="3720541637541300822">Chrome-ды жапқанда инкогнито қойындыларын құлыптау</translation>
 <translation id="384394811301901750">Google Chrome дәл қазір камераны пайдалана алмайды</translation>
 <translation id="3980220367029651214"><ph name="USER_EMAIL1" /> синхрондау есептік жазбасын <ph name="USER_EMAIL2" /> жазбасына ауыстырудасыз. Қолданыстағы Chrome деректерін <ph name="DOMAIN" /> басқарады. Мұның нәтижесінде деректер құрылғыдан жойылады, бірақ <ph name="USER_EMAIL1" /> жазбасында сақталады.</translation>
 <translation id="3984746313391923992">Ұйымыңыз Chrome есептік жазбаңыздан шығуыңызды талап етеді.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ca.xtb b/ios/chrome/app/strings/resources/ios_strings_ca.xtb
index e1b2d9b..5e168c0 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ca.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ca.xtb
@@ -793,7 +793,7 @@
 <translation id="8806823403540278281">La teva organització requereix que naveguis de manera privada. Les pestanyes no es desen en mode d'incògnit.
 <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation>
 <translation id="8820817407110198400">Adreces d'interès</translation>
-<translation id="8840513115188359703">No se us tancarà la sessió del compte de Google.</translation>
+<translation id="8840513115188359703">No se't tancarà la sessió del Compte de Google.</translation>
 <translation id="8868471676553493380">{count,plural, =1{{count} pestanya}other{{count} pestanyes}}</translation>
 <translation id="8870413625673593573">Tancades recentment</translation>
 <translation id="8876882697946675716">Mantén els dispositius sincronitzats</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 4250784c..38973ff 100644
--- a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
@@ -56,6 +56,7 @@
 <translation id="1430915738399379752">Print</translation>
 <translation id="1449835205994625556">Hide password</translation>
 <translation id="145015347812617860"><ph name="COUNT" /> items</translation>
+<translation id="149095475893949513">This website is trying to download a configuration profile.</translation>
 <translation id="1491277525950327607">Double tap to toggle setting</translation>
 <translation id="1492417797159476138">You already saved this username for this site</translation>
 <translation id="1509486075633541495">Sign in to website</translation>
@@ -271,6 +272,7 @@
 <translation id="3607167657931203000">Auto-fill Data</translation>
 <translation id="3609785682760573515">Syncing...</translation>
 <translation id="3638472932233958418">Pre-load Web Pages</translation>
+<translation id="3661160521073045932">Configuration profile available</translation>
 <translation id="3670030362669914947">Number</translation>
 <translation id="3691593122358196899">Bookmarked to <ph name="FOLDER_TITLE" /></translation>
 <translation id="3709582977625132201">Mark as unread</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ta.xtb b/ios/chrome/app/strings/resources/ios_strings_ta.xtb
index a8a718f..33df17f 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ta.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ta.xtb
@@ -218,7 +218,7 @@
 <translation id="3178650076442119961">இன்று பயன்படுத்தியுள்ளார்</translation>
 <translation id="3181825792072797598">ஒத்திசைவை இயக்கு</translation>
 <translation id="3181954750937456830">பாதுகாப்பு உலாவல் (ஆபத்தான தளங்களிலிருந்து உங்களையும் சாதனத்தையும் பாதுகாக்கும்)</translation>
-<translation id="3184767182050912705"><ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> மூலம் திற</translation>
+<translation id="3184767182050912705"><ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> மூலம் அன்லாக் செய்</translation>
 <translation id="3207960819495026254">புக்மார்க் செய்யப்பட்டது</translation>
 <translation id="3224641773458703735">கடவுச்சொற்களை ஏற்ற, முதலில் உங்கள் சாதனத்தில் கடவுக்குறியீட்டை அமைக்க வேண்டும்.</translation>
 <translation id="3240426699337459095">இணைப்பு நகலெடுக்கப்பட்டது</translation>
@@ -630,7 +630,7 @@
 <translation id="7136892417564438900">கேமரா இல்லை</translation>
 <translation id="7153999225810839758">படிக்க <ph name="TIME" /> நிமிடம் ஆகும்</translation>
 <translation id="7159472599653637159">மொபைல் தளத்தைக் கோரு</translation>
-<translation id="7162168282402939716"><ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> மூலம் மறைநிலைத் தாவல்களைத் திறக்கும்</translation>
+<translation id="7162168282402939716"><ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> மூலம் மறைநிலைத் தாவல்களை அன்லாக் செய்யும்</translation>
 <translation id="7172852049901402487">பாதுகாப்புச் சிக்கல்களிலிருந்து உங்கள் கடவுச்சொற்களைப் பாதுகாத்திடுங்கள்</translation>
 <translation id="7173114856073700355">ஒத்திசைவு அமைப்புகளைப் பார்க்கவும்</translation>
 <translation id="7189598951263744875">பகிர்...</translation>
@@ -674,7 +674,7 @@
 <translation id="7537586195939242955">வருந்துகிறோம், இந்த நேரத்தில் உங்கள் பாஸை பாஸ்புக்கில் நிறுவ முடியாது.</translation>
 <translation id="7554791636758816595">புதிய தாவல்</translation>
 <translation id="7561196759112975576">எப்போதும்</translation>
-<translation id="7583004045319035904">மறைநிலைத் தாவல்களைத் திறக்க <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> ஐப் பயன்படுத்தவும்.</translation>
+<translation id="7583004045319035904">மறைநிலைத் தாவல்களை அன்லாக் செய்ய <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> ஐப் பயன்படுத்தவும்.</translation>
 <translation id="7600965453749440009"><ph name="LANGUAGE" /> ஐ எப்போதும் மொழிபெயர்க்க வேண்டாம்</translation>
 <translation id="7603852183842204213">பாப்-அப்கள் தடுக்கப்பட்டன (<ph name="NUMBER_OF_BLOCKED_POPUPS" />)</translation>
 <translation id="7607521702806708809">கடவுச்சொல்லை நீக்கு</translation>
diff --git a/ios/chrome/browser/app_launcher/app_launcher_browser_agent.mm b/ios/chrome/browser/app_launcher/app_launcher_browser_agent.mm
index fd06e802..74067bc 100644
--- a/ios/chrome/browser/app_launcher/app_launcher_browser_agent.mm
+++ b/ios/chrome/browser/app_launcher/app_launcher_browser_agent.mm
@@ -101,7 +101,7 @@
   // Uses a Mailto Handler to open the appropriate app.
   if (url.SchemeIs(url::kMailToScheme)) {
     MailtoHandlerProvider* provider =
-        ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+        ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
     provider->HandleMailtoURL(net::NSURLWithGURL(url));
     return;
   }
diff --git a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
index 6e465c6..185ee57f 100644
--- a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
@@ -4,8 +4,8 @@
 
 #import <UIKit/UIKit.h>
 
+#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
 #include "components/autofill/core/common/autofill_constants.h"
diff --git a/ios/chrome/browser/bookmarks/managed_bookmark_service_factory.mm b/ios/chrome/browser/bookmarks/managed_bookmark_service_factory.mm
index 7db037ec..b5e16df 100644
--- a/ios/chrome/browser/bookmarks/managed_bookmark_service_factory.mm
+++ b/ios/chrome/browser/bookmarks/managed_bookmark_service_factory.mm
@@ -31,7 +31,7 @@
     return std::string();
 
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   if (!identity_service)
     return std::string();
 
diff --git a/ios/chrome/browser/browser_about_rewriter.cc b/ios/chrome/browser/browser_about_rewriter.cc
index 5cfc700..4e5eeaa 100644
--- a/ios/chrome/browser/browser_about_rewriter.cc
+++ b/ios/chrome/browser/browser_about_rewriter.cc
@@ -7,8 +7,8 @@
 #include <string>
 
 #include "base/check.h"
+#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
-#include "base/stl_util.h"
 #include "components/url_formatter/url_fixer.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
diff --git a/ios/chrome/browser/chrome_browser_provider_observer_bridge.mm b/ios/chrome/browser/chrome_browser_provider_observer_bridge.mm
index c2a0798..fa1df0a 100644
--- a/ios/chrome/browser/chrome_browser_provider_observer_bridge.mm
+++ b/ios/chrome/browser/chrome_browser_provider_observer_bridge.mm
@@ -12,7 +12,7 @@
     id<ChromeBrowserProviderObserver> observer)
     : observer_(observer) {
   DCHECK(observer_);
-  scoped_observation_.Observe(ios::GetChromeBrowserProvider());
+  scoped_observation_.Observe(&ios::GetChromeBrowserProvider());
 }
 
 ChromeBrowserProviderObserverBridge::~ChromeBrowserProviderObserverBridge() {}
diff --git a/ios/chrome/browser/chrome_url_constants.cc b/ios/chrome/browser/chrome_url_constants.cc
index 0b87200..db9d645 100644
--- a/ios/chrome/browser/chrome_url_constants.cc
+++ b/ios/chrome/browser/chrome_url_constants.cc
@@ -6,7 +6,7 @@
 
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "ios/components/webui/web_ui_url_constants.h"
 
 const char kChromeUIChromeURLsURL[] = "chrome://chrome-urls/";
@@ -107,8 +107,11 @@
 const char kClearBrowsingDataMyActivityUrlInFooterURL[] =
     "https://history.google.com/history/?utm_source=chrome_cbd";
 
-const char kClearBrowsingDataSearchMyActivityUrlInFooterURL[] =
-    "https://myactivity.google.com/myactivity?product=19";
+const char kClearBrowsingDataDSEMyActivityUrlInFooterURL[] =
+    "https://myactivity.google.com/myactivity?utm_source=chrome_cbd";
+
+const char kClearBrowsingDataDSESearchUrlInFooterURL[] =
+    "https://myactivity.google.com/product/search?utm_source=chrome_cbd";
 
 const char kClearBrowsingDataMyActivityUrlInDialogURL[] =
     "https://history.google.com/history/?utm_source=chrome_n";
diff --git a/ios/chrome/browser/chrome_url_constants.h b/ios/chrome/browser/chrome_url_constants.h
index 58a40bd..081dd352 100644
--- a/ios/chrome/browser/chrome_url_constants.h
+++ b/ios/chrome/browser/chrome_url_constants.h
@@ -91,9 +91,13 @@
 // Options.
 extern const char kClearBrowsingDataMyActivityUrlInFooterURL[];
 
+// Google MyActivity URL for the footer in Clear Browsing Data in the
+// Privacy section post link update.
+extern const char kClearBrowsingDataDSEMyActivityUrlInFooterURL[];
+
 // Google search history URL for the footer in Clear Browsing Data in the
-// Privacy Section
-extern const char kClearBrowsingDataSearchMyActivityUrlInFooterURL[];
+// Privacy section post link update.
+extern const char kClearBrowsingDataDSESearchUrlInFooterURL[];
 
 // Google history URL for the dialog that informs the user that the history data
 // in the Clear Browsing Data under Privacy Options.
diff --git a/ios/chrome/browser/chrome_url_util_unittest.mm b/ios/chrome/browser/chrome_url_util_unittest.mm
index 7e8095f8..6a9dc63 100644
--- a/ios/chrome/browser/chrome_url_util_unittest.mm
+++ b/ios/chrome/browser/chrome_url_util_unittest.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/chrome_url_util.h"
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #include "ios/components/webui/web_ui_url_constants.h"
diff --git a/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm b/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm
index fc8f0e0..89c148c 100644
--- a/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm
+++ b/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/discover_feed/BUILD.gn b/ios/chrome/browser/discover_feed/BUILD.gn
index 89fd0117..3b31524 100644
--- a/ios/chrome/browser/discover_feed/BUILD.gn
+++ b/ios/chrome/browser/discover_feed/BUILD.gn
@@ -18,6 +18,7 @@
     "//components/signin/public/identity_manager",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/signin",
+    "//ios/chrome/browser/ui/content_suggestions:feature_flags",
     "//ios/chrome/browser/ui/content_suggestions:metrics",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/discover_feed",
diff --git a/ios/chrome/browser/discover_feed/discover_feed_service.h b/ios/chrome/browser/discover_feed/discover_feed_service.h
index f8ad395..f801c36 100644
--- a/ios/chrome/browser/discover_feed/discover_feed_service.h
+++ b/ios/chrome/browser/discover_feed/discover_feed_service.h
@@ -10,6 +10,7 @@
 #include "components/signin/public/identity_manager/identity_manager.h"
 
 class AuthenticationService;
+@class ContentSuggestionsMetricsRecorder;
 @class DiscoverFeedMetricsRecorder;
 class PrefService;
 
@@ -24,10 +25,15 @@
                       signin::IdentityManager* identity_manager);
   ~DiscoverFeedService() override;
 
-  // Returns the FeedMetricsRecorder to be used by the Feed, a single instance
-  // of DiscoverFeedMetricsRecorder needs to be used per BrowserState.
+  // Returns the DiscoverFeedMetricsRecorder to be used by the Discover Feed, a
+  // single instance needs to be used per BrowserState.
   DiscoverFeedMetricsRecorder* GetDiscoverFeedMetricsRecorder();
 
+  // Returns the ContentSuggestionsMetricsRecorder to be used by the Zine Feed,
+  // a single instance needs to be used per BrowserState.
+  // TODO(crbug.com/1200303): Remove this when we launch the Discover feed.
+  ContentSuggestionsMetricsRecorder* GetContentSuggestionsMetricsRecorder();
+
   // KeyedService:
   void Shutdown() override;
 
@@ -44,6 +50,10 @@
   // Metrics recorder for the DiscoverFeed.
   __strong DiscoverFeedMetricsRecorder* discover_feed_metrics_recorder_ = nil;
 
+  // Metrics recorder for the Zine feed.
+  __strong ContentSuggestionsMetricsRecorder*
+      content_suggestions_metrics_recorder_ = nil;
+
   DISALLOW_COPY_AND_ASSIGN(DiscoverFeedService);
 };
 
diff --git a/ios/chrome/browser/discover_feed/discover_feed_service.mm b/ios/chrome/browser/discover_feed/discover_feed_service.mm
index e5f1f6ac..45dba54b 100644
--- a/ios/chrome/browser/discover_feed/discover_feed_service.mm
+++ b/ios/chrome/browser/discover_feed/discover_feed_service.mm
@@ -5,6 +5,8 @@
 #include "ios/chrome/browser/discover_feed/discover_feed_service.h"
 
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h"
 #import "ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h"
 #import "ios/public/provider/chrome/browser/chrome_browser_provider.h"
 #import "ios/public/provider/chrome/browser/discover_feed/discover_feed_configuration.h"
@@ -21,6 +23,12 @@
   if (identity_manager)
     identity_manager_observation_.Observe(identity_manager);
 
+  if (!IsDiscoverFeedEnabled()) {
+    content_suggestions_metrics_recorder_ =
+        [[ContentSuggestionsMetricsRecorder alloc] init];
+    return;
+  }
+
   discover_feed_metrics_recorder_ = [[DiscoverFeedMetricsRecorder alloc] init];
 
   DiscoverFeedConfiguration* discover_config =
@@ -28,7 +36,7 @@
   discover_config.authService = authentication_service;
   discover_config.prefService = pref_service;
   discover_config.metricsRecorder = discover_feed_metrics_recorder_;
-  ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->StartFeed(
+  ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->StartFeed(
       discover_config);
 }
 
@@ -39,18 +47,24 @@
   return discover_feed_metrics_recorder_;
 }
 
+ContentSuggestionsMetricsRecorder*
+DiscoverFeedService::GetContentSuggestionsMetricsRecorder() {
+  return content_suggestions_metrics_recorder_;
+}
+
 void DiscoverFeedService::Shutdown() {
   identity_manager_observation_.Reset();
 
   // Stop the Discover feed to disconnects its services.
-  ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->StopFeed();
+  ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->StopFeed();
 
   discover_feed_metrics_recorder_ = nil;
+  content_suggestions_metrics_recorder_ = nil;
 }
 
 void DiscoverFeedService::OnPrimaryAccountChanged(
     const signin::PrimaryAccountChangeEvent& event) {
   ios::GetChromeBrowserProvider()
-      ->GetDiscoverFeedProvider()
+      .GetDiscoverFeedProvider()
       ->UpdateFeedForAccountChange();
 }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index e110495..143ec3d 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -16,8 +16,8 @@
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
+#include "base/cxx17_backports.h"
 #include "base/no_destructor.h"
-#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/system/sys_info.h"
@@ -650,12 +650,6 @@
      flag_descriptions::kIOSPersistCrashRestoreName,
      flag_descriptions::kIOSPersistCrashRestoreDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kIOSPersistCrashRestore)},
-    {"change-password-affiliation",
-     flag_descriptions::kChangePasswordAffiliationInfoName,
-     flag_descriptions::kChangePasswordAffiliationInfoDescription,
-     flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(
-         password_manager::features::kChangePasswordAffiliationInfo)},
     {"use-of-hash-affiliation-fetcher",
      flag_descriptions::kUseOfHashAffiliationFetcherName,
      flag_descriptions::kUseOfHashAffiliationFetcherDescription,
@@ -985,7 +979,7 @@
     command_line->AppendSwitch(switches::kDisableThirdPartyKeyboardWorkaround);
   }
 
-  ios::GetChromeBrowserProvider()->AppendSwitchesFromExperimentalSettings(
+  ios::GetChromeBrowserProvider().AppendSwitchesFromExperimentalSettings(
       defaults, command_line);
 }
 
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 4fc6d988..c7fcb61 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -73,12 +73,6 @@
     "disabled, initial upload is delayed until deferred initialization. This "
     "does not affect recovery mode.";
 
-const char kChangePasswordAffiliationInfoName[] =
-    "Using Affiliation Service for Change Password URLs";
-const char kChangePasswordAffiliationInfoDescription[] =
-    "In case site doesn't support /.well-known/change-password Chrome will try "
-    "to obtain it using Affiliation Service.";
-
 const char kCollectionsCardPresentationStyleName[] =
     "Card style presentation for Collections.";
 const char kCollectionsCardPresentationStyleDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 1dc9b46..3d39e1b 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -68,11 +68,6 @@
 extern const char kBreakpadNoDelayInitialUploadName[];
 extern const char kBreakpadNoDelayInitialUploadDescription[];
 
-// Title and description for the flag to control if change password url should
-// be obtained by affiliation service.
-extern const char kChangePasswordAffiliationInfoName[];
-extern const char kChangePasswordAffiliationInfoDescription[];
-
 // Title and description for the flag to control which crash generation tool
 // is used.
 extern const char kCrashpadIOSName[];
diff --git a/ios/chrome/browser/google/google_brand.mm b/ios/chrome/browser/google/google_brand.mm
index 1405fe5..dd346fa 100644
--- a/ios/chrome/browser/google/google_brand.mm
+++ b/ios/chrome/browser/google/google_brand.mm
@@ -15,11 +15,8 @@
 namespace google_brand {
 
 bool GetBrand(std::string* brand) {
-  if (!ios::GetChromeBrowserProvider())
-    return false;
-
   brand->assign(ios::GetChromeBrowserProvider()
-                    ->GetAppDistributionProvider()
+                    .GetAppDistributionProvider()
                     ->GetDistributionBrandCode());
   return true;
 }
diff --git a/ios/chrome/browser/main/browser_agent_util.mm b/ios/chrome/browser/main/browser_agent_util.mm
index 0c9b474..28859804 100644
--- a/ios/chrome/browser/main/browser_agent_util.mm
+++ b/ios/chrome/browser/main/browser_agent_util.mm
@@ -78,5 +78,5 @@
 
   // This needs to be called last in case any downstream browser agents need to
   // access upstream agents created earlier in this function.
-  ios::GetChromeBrowserProvider()->AttachBrowserAgents(browser);
+  ios::GetChromeBrowserProvider().AttachBrowserAgents(browser);
 }
diff --git a/ios/chrome/browser/metrics/first_user_action_recorder.cc b/ios/chrome/browser/metrics/first_user_action_recorder.cc
index 2e4b9276..a9d0b62 100644
--- a/ios/chrome/browser/metrics/first_user_action_recorder.cc
+++ b/ios/chrome/browser/metrics/first_user_action_recorder.cc
@@ -5,10 +5,10 @@
 #include "ios/chrome/browser/metrics/first_user_action_recorder.h"
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/ios/chrome/browser/omaha/omaha_service.mm b/ios/chrome/browser/omaha/omaha_service.mm
index c53fdb6..0840fde2 100644
--- a/ios/chrome/browser/omaha/omaha_service.mm
+++ b/ios/chrome/browser/omaha/omaha_service.mm
@@ -400,7 +400,7 @@
   started_ = true;
 
   // Start the provider at the same time as the rest of the service.
-  ios::GetChromeBrowserProvider()->GetOmahaServiceProvider()->Start();
+  ios::GetChromeBrowserProvider().GetOmahaServiceProvider()->Start();
 
   NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
   next_tries_time_ = base::Time::FromCFAbsoluteTime(
@@ -465,7 +465,7 @@
     return;
   }
 
-  ios::GetChromeBrowserProvider()->GetOmahaServiceProvider()->Stop();
+  ios::GetChromeBrowserProvider().GetOmahaServiceProvider()->Stop();
 }
 
 // static
@@ -515,7 +515,7 @@
                                          const base::Time& installationTime,
                                          PingContent pingContent) {
   OmahaServiceProvider* provider =
-      ios::GetChromeBrowserProvider()->GetOmahaServiceProvider();
+      ios::GetChromeBrowserProvider().GetOmahaServiceProvider();
 
   XmlWrapper xml_wrapper;
   xml_wrapper.StartElement("request");
@@ -631,7 +631,7 @@
   DCHECK(!url_loader_);
 
   GURL url(ios::GetChromeBrowserProvider()
-               ->GetOmahaServiceProvider()
+               .GetOmahaServiceProvider()
                ->GetUpdateServerURL());
   if (!url.is_valid()) {
     return;
@@ -723,7 +723,7 @@
                                length:response_body->length()];
   NSXMLParser* parser = [[NSXMLParser alloc] initWithData:xml];
   const std::string application_id = ios::GetChromeBrowserProvider()
-                                         ->GetOmahaServiceProvider()
+                                         .GetOmahaServiceProvider()
                                          ->GetApplicationID();
   ResponseParser* delegate = [[ResponseParser alloc]
       initWithAppId:base::SysUTF8ToNSString(application_id)];
diff --git a/ios/chrome/browser/omaha/omaha_service_unittest.mm b/ios/chrome/browser/omaha/omaha_service_unittest.mm
index 222c6a7..7a22d104 100644
--- a/ios/chrome/browser/omaha/omaha_service_unittest.mm
+++ b/ios/chrome/browser/omaha/omaha_service_unittest.mm
@@ -9,8 +9,8 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -112,7 +112,7 @@
 
   std::string test_application_id() const {
     return ios::GetChromeBrowserProvider()
-        ->GetOmahaServiceProvider()
+        .GetOmahaServiceProvider()
         ->GetApplicationID();
   }
 
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index a2c5af3..d3e879c 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -9,9 +9,9 @@
 #include <memory>
 #include <utility>
 
+#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/memory/ref_counted.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #import "base/test/ios/wait_util.h"
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h
index 82d99d0..cadd8d6 100644
--- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h
+++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.h
@@ -4,7 +4,6 @@
 #ifndef IOS_CHROME_BROWSER_PASSWORDS_WELL_KNOWN_CHANGE_PASSWORD_TAB_HELPER_H_
 #define IOS_CHROME_BROWSER_PASSWORDS_WELL_KNOWN_CHANGE_PASSWORD_TAB_HELPER_H_
 
-#include "components/password_manager/core/browser/change_password_url_service.h"
 #include "components/password_manager/core/browser/well_known_change_password_state.h"
 #include "components/password_manager/core/browser/well_known_change_password_util.h"
 #include "ios/web/public/navigation/web_state_policy_decider.h"
@@ -85,7 +84,6 @@
   web::WebStatePolicyDecider::PolicyDecisionCallback response_policy_callback_;
   password_manager::WellKnownChangePasswordState
       well_known_change_password_state_{this};
-  ChangePasswordUrlService* change_password_url_service_ = nullptr;
   password_manager::AffiliationService* affiliation_service_ = nullptr;
   WEB_STATE_USER_DATA_KEY_DECL();
 };
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
index 6e1aad3..ed6badc 100644
--- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
+++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper.mm
@@ -12,7 +12,6 @@
 #import "components/ukm/ios/ukm_url_recorder.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.h"
-#include "ios/chrome/browser/passwords/ios_chrome_change_password_url_service_factory.h"
 #import "ios/web/public/navigation/navigation_context.h"
 #import "net/base/mac/url_conversions.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
@@ -29,16 +28,8 @@
 WellKnownChangePasswordTabHelper::WellKnownChangePasswordTabHelper(
     web::WebState* web_state)
     : web::WebStatePolicyDecider(web_state), web_state_(web_state) {
-  if (base::FeatureList::IsEnabled(
-          password_manager::features::kChangePasswordAffiliationInfo)) {
-    affiliation_service_ =
-        IOSChromeAffiliationServiceFactory::GetForBrowserState(
-            web_state->GetBrowserState());
-  } else {
-    change_password_url_service_ =
-        IOSChromeChangePasswordUrlServiceFactory::GetForBrowserState(
-            web_state->GetBrowserState());
-  }
+  affiliation_service_ = IOSChromeAffiliationServiceFactory::GetForBrowserState(
+      web_state->GetBrowserState());
   web_state->AddObserver(this);
 }
 
@@ -71,15 +62,9 @@
         web_state_->GetLastCommittedURL().is_empty() &&  // empty tab history
         IsWellKnownChangePasswordUrl(request_url)) {
       request_url_ = request_url;
-      if (base::FeatureList::IsEnabled(
-              password_manager::features::kChangePasswordAffiliationInfo)) {
-        if (affiliation_service_->GetChangePasswordURL(request_url_)
-                .is_empty()) {
-          well_known_change_password_state_.PrefetchChangePasswordURLs(
-              affiliation_service_, {request_url_});
-        }
-      } else {
-        change_password_url_service_->PrefetchURLs();
+      if (affiliation_service_->GetChangePasswordURL(request_url_).is_empty()) {
+        well_known_change_password_state_.PrefetchChangePasswordURLs(
+            affiliation_service_, {request_url_});
       }
       auto url_loader_factory =
           web_state_->GetBrowserState()->GetSharedURLLoaderFactory();
@@ -144,14 +129,8 @@
   } else {
     std::move(response_policy_callback_)
         .Run(web::WebStatePolicyDecider::PolicyDecision::Cancel());
-    GURL redirect_url;
-    if (base::FeatureList::IsEnabled(
-            password_manager::features::kChangePasswordAffiliationInfo)) {
-      redirect_url = affiliation_service_->GetChangePasswordURL(request_url_);
-    } else {
-      redirect_url =
-          change_password_url_service_->GetChangePasswordUrl(request_url_);
-    }
+    GURL redirect_url =
+        affiliation_service_->GetChangePasswordURL(request_url_);
     if (redirect_url.is_valid()) {
       RecordMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
       Redirect(redirect_url);
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
index e025bbf..8221ac16 100644
--- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
+++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
@@ -15,7 +15,6 @@
 #include "components/ukm/test_ukm_recorder.h"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/passwords/ios_chrome_affiliation_service_factory.h"
-#include "ios/chrome/browser/passwords/ios_chrome_change_password_url_service_factory.h"
 #include "ios/chrome/browser/web/chrome_web_test.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/test/fakes/fake_web_client.h"
@@ -92,31 +91,9 @@
 
 }  // namespace
 
-class TestChangePasswordUrlService
-    : public password_manager::ChangePasswordUrlService {
- public:
-  void PrefetchURLs() override {}
-
-  GURL GetChangePasswordUrl(const GURL& url) override {
-    if (override_available_) {
-      GURL::Replacements replacement;
-      replacement.SetPathStr(kMockChangePasswordPath);
-      return url.ReplaceComponents(replacement);
-    }
-    return GURL();
-  }
-
-  void SetOverrideAvailable(bool available) { override_available_ = available; }
-
- private:
-  bool override_available_ = false;
-};
-
 // This test uses a mockserver to simulate different response. To handle the
 // url_loader requests we also mock the response for the url_loader_factory.
-class WellKnownChangePasswordTabHelperTest
-    : public ChromeWebTest,
-      public ::testing::WithParamInterface<bool> {
+class WellKnownChangePasswordTabHelperTest : public ChromeWebTest {
  public:
   using UkmBuilder =
       ukm::builders::PasswordManager_WellKnownChangePasswordResult;
@@ -126,14 +103,6 @@
     test_server_->RegisterRequestHandler(base::BindRepeating(
         &WellKnownChangePasswordTabHelperTest::HandleRequest,
         base::Unretained(this)));
-
-    if (GetParam()) {
-      feature_list_.InitAndEnableFeature(
-          password_manager::features::kChangePasswordAffiliationInfo);
-    } else {
-      feature_list_.InitAndDisableFeature(
-          password_manager::features::kChangePasswordAffiliationInfo);
-    }
   }
 
   void SetUp() override {
@@ -141,25 +110,14 @@
     EXPECT_TRUE(test_server_->InitializeAndListen());
     test_server_->StartAcceptingConnections();
 
-    if (GetParam()) {
-      affiliation_service_ = static_cast<TestAffiliationService*>(
-          IOSChromeAffiliationServiceFactory::GetInstance()
-              ->SetTestingFactoryAndUse(
-                  web_state()->GetBrowserState(),
-                  base::BindRepeating([](web::BrowserState* browser_state) {
-                    return std::unique_ptr<KeyedService>(
-                        std::make_unique<TestAffiliationService>());
-                  })));
-    } else {
-      url_service_ = static_cast<TestChangePasswordUrlService*>(
-          IOSChromeChangePasswordUrlServiceFactory::GetInstance()
-              ->SetTestingFactoryAndUse(
-                  web_state()->GetBrowserState(),
-                  base::BindRepeating([](web::BrowserState* browser_state) {
-                    return std::unique_ptr<KeyedService>(
-                        std::make_unique<TestChangePasswordUrlService>());
-                  })));
-    }
+    affiliation_service_ = static_cast<TestAffiliationService*>(
+        IOSChromeAffiliationServiceFactory::GetInstance()
+            ->SetTestingFactoryAndUse(
+                web_state()->GetBrowserState(),
+                base::BindRepeating([](web::BrowserState* browser_state) {
+                  return std::unique_ptr<KeyedService>(
+                      std::make_unique<TestAffiliationService>());
+                })));
 
     web_state()->SetDelegate(&delegate_);
     password_manager::WellKnownChangePasswordTabHelper::CreateForWebState(
@@ -191,11 +149,7 @@
 
   // Sets if change passwords URL can be obtained.
   void SetOverrideAvailable(bool available) {
-    if (GetParam()) {
-      affiliation_service_->SetOverrideAvailable(available);
-    } else {
-      url_service_->SetOverrideAvailable(available);
-    }
+    affiliation_service_->SetOverrideAvailable(available);
   }
 
   // Maps a path to a ServerResponse config object.
@@ -213,7 +167,6 @@
   base::test::ScopedFeatureList feature_list_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   web::FakeWebStateDelegate delegate_;
-  TestChangePasswordUrlService* url_service_ = nullptr;
   TestAffiliationService* affiliation_service_ = nullptr;
 };
 
@@ -249,7 +202,7 @@
   return http_response;
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest, SupportForChangePassword) {
+TEST_F(WellKnownChangePasswordTabHelperTest, SupportForChangePassword) {
   path_response_map_[kWellKnownChangePasswordPath] = {net::HTTP_OK, {}};
 
   SetUrlLoaderResponse(kWellKnownNotExistingResourcePath, net::HTTP_NOT_FOUND);
@@ -261,7 +214,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kUsedWellKnownChangePassword);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest,
+TEST_F(WellKnownChangePasswordTabHelperTest,
        SupportForChangePassword_WithRedirect) {
   path_response_map_[kWellKnownChangePasswordPath] = {
       net::HTTP_PERMANENT_REDIRECT,
@@ -277,7 +230,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kUsedWellKnownChangePassword);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest,
+TEST_F(WellKnownChangePasswordTabHelperTest,
        NoSupportForChangePassword_NotFound) {
   path_response_map_[kWellKnownChangePasswordPath] = {net::HTTP_NOT_FOUND, {}};
   path_response_map_["/"] = {net::HTTP_OK, {}};
@@ -290,7 +243,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest, NoSupportForChangePassword_Ok) {
+TEST_F(WellKnownChangePasswordTabHelperTest, NoSupportForChangePassword_Ok) {
   path_response_map_[kWellKnownChangePasswordPath] = {net::HTTP_OK, {}};
   path_response_map_["/"] = {net::HTTP_OK, {}};
   SetUrlLoaderResponse(kWellKnownNotExistingResourcePath, net::HTTP_OK);
@@ -302,7 +255,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest,
+TEST_F(WellKnownChangePasswordTabHelperTest,
        NoSupportForChangePassword_WithRedirect) {
   path_response_map_[kWellKnownChangePasswordPath] = {
       net::HTTP_PERMANENT_REDIRECT, {std::make_pair("Location", "/not-found")}};
@@ -315,7 +268,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOriginUrl);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest,
+TEST_F(WellKnownChangePasswordTabHelperTest,
        NoSupportForChangePassword_WithOverride) {
   SetOverrideAvailable(true);
   path_response_map_[kWellKnownChangePasswordPath] = {
@@ -329,7 +282,7 @@
   ExpectUkmMetric(WellKnownChangePasswordResult::kFallbackToOverrideUrl);
 }
 
-TEST_P(WellKnownChangePasswordTabHelperTest,
+TEST_F(WellKnownChangePasswordTabHelperTest,
        NoSupportForChangePasswordForLinks) {
   path_response_map_[kWellKnownChangePasswordPath] = {net::HTTP_OK, {}};
   LoadUrlWithTransition(web_state(),
@@ -342,7 +295,3 @@
   // no metrics should be recorded.
   EXPECT_TRUE(test_recorder_->GetEntriesByName(UkmBuilder::kEntryName).empty());
 }
-
-INSTANTIATE_TEST_SUITE_P(ChangePasswordWithAffiliationDisabledAndEnabled,
-                         WellKnownChangePasswordTabHelperTest,
-                         ::testing::Bool());
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn
index 6f4f0adc..55521fd 100644
--- a/ios/chrome/browser/policy/BUILD.gn
+++ b/ios/chrome/browser/policy/BUILD.gn
@@ -165,7 +165,7 @@
   testonly = true
   sources = [
     "browser_dm_token_storage_ios_unittest.mm",
-    "browser_signin_policy_handler_unittest.cc",
+    "browser_signin_policy_handler_unittest.mm",
     "policy_unittest.mm",
     "policy_watcher_browser_agent_unittest.mm",
     "reporting/browser_report_generator_ios_unittest.mm",
diff --git a/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm b/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm
index 3faa434b..15a9455 100644
--- a/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm
+++ b/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm
@@ -37,6 +37,18 @@
 }  // namespace
 
 class BrowserDMTokenStorageIOSTest : public PlatformTest {
+ protected:
+  BrowserDMTokenStorageIOSTest() {
+    // Make sure there is no pre-existing policy present.
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+  }
+  ~BrowserDMTokenStorageIOSTest() override {
+    // Cleanup any policies left from the test.
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+  }
+
  private:
   base::test::TaskEnvironment task_environment_;
 };
diff --git a/ios/chrome/browser/policy/browser_signin_policy_handler_unittest.cc b/ios/chrome/browser/policy/browser_signin_policy_handler_unittest.mm
similarity index 85%
rename from ios/chrome/browser/policy/browser_signin_policy_handler_unittest.cc
rename to ios/chrome/browser/policy/browser_signin_policy_handler_unittest.mm
index 1d4ddcf..28b1acd 100644
--- a/ios/chrome/browser/policy/browser_signin_policy_handler_unittest.cc
+++ b/ios/chrome/browser/policy/browser_signin_policy_handler_unittest.mm
@@ -4,7 +4,10 @@
 
 #include "ios/chrome/browser/policy/browser_signin_policy_handler.h"
 
+#import <Foundation/Foundation.h>
+
 #include "components/policy/core/browser/policy_error_map.h"
+#import "components/policy/core/common/policy_loader_ios_constants.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/schema.h"
 #include "components/prefs/pref_value_map.h"
@@ -13,6 +16,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
 namespace policy {
 namespace {
 
@@ -27,7 +34,20 @@
       }
     })";
 
-using BrowserSigninPolicyHandlerTest = PlatformTest;
+class BrowserSigninPolicyHandlerTest : public PlatformTest {
+ protected:
+  BrowserSigninPolicyHandlerTest() {
+    // Make sure there is no pre-existing policy present.
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+  }
+
+  ~BrowserSigninPolicyHandlerTest() override {
+    // Cleanup any policies left from the test.
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+  }
+};
 
 const char* BrowserSigninModeToString(BrowserSigninMode mode) {
   switch (mode) {
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm
index 4b50fe39..b29f8e55 100644
--- a/ios/chrome/browser/signin/authentication_service.mm
+++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -121,7 +121,7 @@
   crash_keys::SetCurrentlySignedIn(IsAuthenticated());
 
   identity_service_observation_.Observe(
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService());
+      ios::GetChromeBrowserProvider().GetChromeIdentityService());
 
   // Reload credentials to ensure the accounts from the token service are
   // up-to-date.
@@ -390,7 +390,7 @@
   }
 
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   identity_service->HandleMDMNotification(identity, cached_info, ^(bool){
                                                     });
   return true;
@@ -399,7 +399,7 @@
 void AuthenticationService::ResetChromeIdentityServiceObserverForTesting() {
   DCHECK(!identity_service_observation_.IsObserving());
   identity_service_observation_.Observe(
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService());
+      ios::GetChromeBrowserProvider().GetChromeIdentityService());
 }
 
 base::WeakPtr<AuthenticationService> AuthenticationService::GetWeakPtr() {
@@ -446,7 +446,7 @@
 bool AuthenticationService::HandleMDMNotification(ChromeIdentity* identity,
                                                   NSDictionary* user_info) {
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   ios::MDMDeviceStatus status = identity_service->GetMDMDeviceStatus(user_info);
   NSDictionary* cached_info = GetCachedMDMInfo(identity);
 
@@ -483,7 +483,7 @@
   }
 
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   if (!identity_service->IsInvalidGrantError(user_info)) {
     // If the failure is not due to an invalid grant, the identity is not
     // invalid and there is nothing to do.
diff --git a/ios/chrome/browser/signin/chrome_account_manager_service.mm b/ios/chrome/browser/signin/chrome_account_manager_service.mm
index af7d94a..c7430aee 100644
--- a/ios/chrome/browser/signin/chrome_account_manager_service.mm
+++ b/ios/chrome/browser/signin/chrome_account_manager_service.mm
@@ -98,7 +98,7 @@
 bool ChromeAccountManagerService::HasIdentities() {
   FunctorHasIdentities helper;
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->IterateOverIdentities(helper.Callback());
   return helper.has_identities;
 }
@@ -115,7 +115,7 @@
 
   FunctorLookupIdentityByGaiaID helper(gaia_id);
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->IterateOverIdentities(helper.Callback());
   return helper.identity;
 }
@@ -134,7 +134,7 @@
 NSArray<ChromeIdentity*>* ChromeAccountManagerService::GetAllIdentities() {
   FunctorCollectIdentities helper;
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->IterateOverIdentities(helper.Callback());
   return [helper.identities copy];
 }
@@ -142,7 +142,7 @@
 ChromeIdentity* ChromeAccountManagerService::GetDefaultIdentity() {
   FunctorGetFirstIdentity helper;
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->IterateOverIdentities(helper.Callback());
   return helper.default_identity;
 }
diff --git a/ios/chrome/browser/signin/chrome_identity_service_observer_bridge.mm b/ios/chrome/browser/signin/chrome_identity_service_observer_bridge.mm
index abcb0d0d..55662a8 100644
--- a/ios/chrome/browser/signin/chrome_identity_service_observer_bridge.mm
+++ b/ios/chrome/browser/signin/chrome_identity_service_observer_bridge.mm
@@ -16,7 +16,7 @@
     : observer_(observer) {
   DCHECK(observer_);
   scoped_observation_.Observe(
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService());
+      ios::GetChromeBrowserProvider().GetChromeIdentityService());
 }
 
 ChromeIdentityServiceObserverBridge::~ChromeIdentityServiceObserverBridge() {}
diff --git a/ios/chrome/browser/signin/device_accounts_provider_impl.mm b/ios/chrome/browser/signin/device_accounts_provider_impl.mm
index a5fa29b..f8feeac7 100644
--- a/ios/chrome/browser/signin/device_accounts_provider_impl.mm
+++ b/ios/chrome/browser/signin/device_accounts_provider_impl.mm
@@ -59,7 +59,7 @@
     AccessTokenCallback callback) {
   DCHECK(!callback.is_null());
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
 
   // AccessTokenCallback is non-copyable. Using __block allocates the memory
   // directly in the block object at compilation time (instead of doing a
@@ -77,7 +77,7 @@
 DeviceAccountsProviderImpl::GetAllAccounts() const {
   std::vector<AccountInfo> accounts;
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   NSArray* identities = account_manager_service_->GetAllIdentities();
   for (ChromeIdentity* identity in identities) {
     accounts.push_back(GetAccountInfo(identity, identity_service));
@@ -96,14 +96,14 @@
   }
 
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   if (identity_service->IsMDMError(
           account_manager_service_->GetIdentityWithGaiaID(gaia_id), error)) {
     return kAuthenticationErrorCategoryAuthorizationErrors;
   }
 
   ios::SigninErrorProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSigninErrorProvider();
+      ios::GetChromeBrowserProvider().GetSigninErrorProvider();
   switch (provider->GetErrorCategory(error)) {
     case ios::SigninErrorCategory::UNKNOWN_ERROR: {
       // Google's OAuth 2 implementation returns a 400 with JSON body
diff --git a/ios/chrome/browser/signin/signin_util.mm b/ios/chrome/browser/signin/signin_util.mm
index 6edd40e..9c3f281 100644
--- a/ios/chrome/browser/signin/signin_util.mm
+++ b/ios/chrome/browser/signin/signin_util.mm
@@ -24,7 +24,7 @@
 
 bool ShouldHandleSigninError(NSError* error) {
   ios::SigninErrorProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSigninErrorProvider();
+      ios::GetChromeBrowserProvider().GetSigninErrorProvider();
   return ![provider->GetSigninErrorDomain() isEqualToString:error.domain] ||
          (error.code != provider->GetCode(ios::SigninError::CANCELED) &&
           error.code !=
diff --git a/ios/chrome/browser/snapshots/snapshots_util.mm b/ios/chrome/browser/snapshots/snapshots_util.mm
index ce609312..9b3094e 100644
--- a/ios/chrome/browser/snapshots/snapshots_util.mm
+++ b/ios/chrome/browser/snapshots/snapshots_util.mm
@@ -7,11 +7,11 @@
 #import <UIKit/UIKit.h>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/mac/foundation_util.h"
 #include "base/path_service.h"
-#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/post_task.h"
 #include "base/task/thread_pool.h"
diff --git a/ios/chrome/browser/sync/ios_trusted_vault_client.mm b/ios/chrome/browser/sync/ios_trusted_vault_client.mm
index 8a66d41..0720915f 100644
--- a/ios/chrome/browser/sync/ios_trusted_vault_client.mm
+++ b/ios/chrome/browser/sync/ios_trusted_vault_client.mm
@@ -22,20 +22,16 @@
 IOSTrustedVaultClient::~IOSTrustedVaultClient() = default;
 
 void IOSTrustedVaultClient::AddObserver(Observer* observer) {
-  ios::ChromeBrowserProvider* browser_provider =
-      ios::GetChromeBrowserProvider();
   ios::ChromeTrustedVaultService* trusted_vault_service =
-      browser_provider->GetChromeTrustedVaultService();
+      ios::GetChromeBrowserProvider().GetChromeTrustedVaultService();
   if (trusted_vault_service) {
     trusted_vault_service->AddObserver(observer);
   }
 }
 
 void IOSTrustedVaultClient::RemoveObserver(Observer* observer) {
-  ios::ChromeBrowserProvider* browser_provider =
-      ios::GetChromeBrowserProvider();
   ios::ChromeTrustedVaultService* trusted_vault_service =
-      browser_provider->GetChromeTrustedVaultService();
+      ios::GetChromeBrowserProvider().GetChromeTrustedVaultService();
   if (trusted_vault_service) {
     trusted_vault_service->RemoveObserver(observer);
   }
@@ -48,9 +44,7 @@
   ChromeIdentity* identity =
       account_manager_service_->GetIdentityWithGaiaID(account_info.gaia);
 
-  ios::ChromeBrowserProvider* browser_provider =
-      ios::GetChromeBrowserProvider();
-  browser_provider->GetChromeTrustedVaultService()->FetchKeys(
+  ios::GetChromeBrowserProvider().GetChromeTrustedVaultService()->FetchKeys(
       identity, std::move(callback));
 }
 
@@ -68,10 +62,9 @@
   ChromeIdentity* identity =
       account_manager_service_->GetIdentityWithGaiaID(account_info.gaia);
 
-  ios::ChromeBrowserProvider* browser_provider =
-      ios::GetChromeBrowserProvider();
-  browser_provider->GetChromeTrustedVaultService()->MarkLocalKeysAsStale(
-      identity, std::move(callback));
+  ios::GetChromeBrowserProvider()
+      .GetChromeTrustedVaultService()
+      ->MarkLocalKeysAsStale(identity, std::move(callback));
 }
 
 void IOSTrustedVaultClient::GetIsRecoverabilityDegraded(
@@ -81,7 +74,7 @@
       account_manager_service_->GetIdentityWithGaiaID(account_info.gaia);
 
   ios::GetChromeBrowserProvider()
-      ->GetChromeTrustedVaultService()
+      .GetChromeTrustedVaultService()
       ->GetDegradedRecoverabilityStatus(identity, std::move(callback));
 }
 
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc
index ba2a089..2b5c813 100644
--- a/ios/chrome/browser/sync/sync_setup_service.cc
+++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -6,8 +6,8 @@
 
 #include <stdio.h>
 
+#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
 #include "components/signin/public/base/account_consistency_method.h"
 #include "components/sync/base/stop_source.h"
 #include "components/sync/base/user_selectable_type.h"
diff --git a/ios/chrome/browser/translate/fake_translate_infobar_delegate.h b/ios/chrome/browser/translate/fake_translate_infobar_delegate.h
index 283fc3f1..552a7cc2 100644
--- a/ios/chrome/browser/translate/fake_translate_infobar_delegate.h
+++ b/ios/chrome/browser/translate/fake_translate_infobar_delegate.h
@@ -63,10 +63,15 @@
   ~FakeTranslateInfoBarDelegateFactory();
 
   // Create a FakeTranslateInfoBarDelegate unique_ptr with
-  // |source_language|and |target_language|.
+  // |source_language|, |target_language|, |translate_step| and |error_type|.
   std::unique_ptr<FakeTranslateInfoBarDelegate>
-  CreateFakeTranslateInfoBarDelegate(const std::string& source_language,
-                                     const std::string& target_language);
+  CreateFakeTranslateInfoBarDelegate(
+      const std::string& source_language,
+      const std::string& target_language,
+      translate::TranslateStep translate_step =
+          translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE,
+      translate::TranslateErrors::Type error_type =
+          translate::TranslateErrors::Type::NONE);
 
  private:
   translate::testing::MockTranslateDriver driver_;
diff --git a/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm b/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm
index 4b522bd4..5d28b211 100644
--- a/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm
+++ b/ios/chrome/browser/translate/fake_translate_infobar_delegate.mm
@@ -85,10 +85,10 @@
 std::unique_ptr<FakeTranslateInfoBarDelegate>
 FakeTranslateInfoBarDelegateFactory::CreateFakeTranslateInfoBarDelegate(
     const std::string& source_language,
-    const std::string& target_language) {
+    const std::string& target_language,
+    translate::TranslateStep translate_step,
+    translate::TranslateErrors::Type error_type) {
   return std::make_unique<FakeTranslateInfoBarDelegate>(
-      manager_->GetWeakPtr(), false,
-      translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE,
-      source_language, target_language, translate::TranslateErrors::Type::NONE,
-      false);
+      manager_->GetWeakPtr(), false, translate_step, source_language,
+      target_language, error_type, false);
 }
diff --git a/ios/chrome/browser/ui/alert_view/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view/alert_view_controller.mm
index fd34467..2fa58b3 100644
--- a/ios/chrome/browser/ui/alert_view/alert_view_controller.mm
+++ b/ios/chrome/browser/ui/alert_view/alert_view_controller.mm
@@ -230,8 +230,7 @@
   [scrollView addSubview:stackView];
 
   NSLayoutConstraint* heightConstraint = [scrollView.heightAnchor
-      constraintEqualToAnchor:scrollView.contentLayoutGuide.heightAnchor
-                   multiplier:1];
+      constraintEqualToAnchor:scrollView.contentLayoutGuide.heightAnchor];
   // UILayoutPriorityDefaultHigh is the default priority for content
   // compression. Setting this lower avoids compressing the content of the
   // scroll view.
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow.mm b/ios/chrome/browser/ui/authentication/authentication_flow.mm
index 48782b90..cb0b12d 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow.mm
@@ -48,7 +48,7 @@
 
 NSError* IdentityMissingError() {
   ios::SigninErrorProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSigninErrorProvider();
+      ios::GetChromeBrowserProvider().GetSigninErrorProvider();
   return [NSError
       errorWithDomain:provider->GetSigninErrorDomain()
                  code:provider->GetCode(ios::SigninError::MISSING_IDENTITY)
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index 05d0a37..ae39df4 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -138,7 +138,7 @@
 - (void)fetchManagedStatus:(ChromeBrowserState*)browserState
                forIdentity:(ChromeIdentity*)identity {
   ios::ChromeIdentityService* identityService =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   NSString* hostedDomain =
       identityService->GetCachedHostedDomainForIdentity(identity);
   if (hostedDomain) {
@@ -149,7 +149,7 @@
   [self startWatchdogTimerForManagedStatus];
   __weak AuthenticationFlowPerformer* weakSelf = self;
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->GetHostedDomainForIdentity(
           identity, ^(NSString* hosted_domain, NSError* error) {
             [weakSelf handleGetHostedDomain:hosted_domain
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
index 8e2b6c6..5fdff7b 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
@@ -38,7 +38,7 @@
 // Spacing within stackView.
 const CGFloat kStackViewSubViewSpacing = 13.0;
 // Horizontal Inset between button contents and edge.
-const CGFloat kButtonTitleHorizontalContentInset = 40.0;
+const CGFloat kButtonTitleHorizontalContentInset = 12.0;
 // Vertical Inset between button contents and edge.
 const CGFloat kButtonTitleVerticalContentInset = 8.0;
 // Button corner radius.
@@ -96,6 +96,9 @@
     primaryButton.backgroundColor = [UIColor colorNamed:kBlueColor];
     [primaryButton.titleLabel
         setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]];
+    primaryButton.titleLabel.adjustsFontSizeToFitWidth = YES;
+    primaryButton.titleLabel.minimumScaleFactor = 0.7;
+
     primaryButton.layer.cornerRadius = kButtonCornerRadius;
     primaryButton.clipsToBounds = YES;
     primaryButtonInsets = UIEdgeInsetsMake(
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
index 4a46284..5314bde 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.mm
@@ -105,7 +105,7 @@
   UIImage* image = self.userImage;
   if (!image) {
     image = ios::GetChromeBrowserProvider()
-                ->GetSigninResourcesProvider()
+                .GetSigninResourcesProvider()
                 ->GetDefaultAvatar();
   }
   [signinPromoView setProfileImage:image];
diff --git a/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm b/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
index 1e03eff..b41ab28 100644
--- a/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
+++ b/ios/chrome/browser/ui/authentication/resized_avatar_cache.mm
@@ -49,15 +49,15 @@
 
 - (UIImage*)resizedAvatarForIdentity:(ChromeIdentity*)identity {
   UIImage* image = ios::GetChromeBrowserProvider()
-                       ->GetChromeIdentityService()
+                       .GetChromeIdentityService()
                        ->GetCachedAvatarForIdentity(identity);
   if (!image) {
     image = ios::GetChromeBrowserProvider()
-                ->GetSigninResourcesProvider()
+                .GetSigninResourcesProvider()
                 ->GetDefaultAvatar();
     // No cached image, trigger a fetch, which will notify all observers.
     ios::GetChromeBrowserProvider()
-        ->GetChromeIdentityService()
+        .GetChromeIdentityService()
         ->GetAvatarForIdentity(identity, nil);
   }
 
diff --git a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
index 52fcc7d2..1ce2b0e 100644
--- a/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.mm
@@ -117,7 +117,7 @@
       IdentityManagerFactory::GetForBrowserState(_browserState);
   for (const auto& account : identityManager->GetAccountsWithRefreshTokens()) {
     ChromeIdentity* identity = ios::GetChromeBrowserProvider()
-                                   ->GetChromeIdentityService()
+                                   .GetChromeIdentityService()
                                    ->GetIdentityWithGaiaID(account.gaia);
 
     // If the account with a refresh token is invalidated during this operation
diff --git a/ios/chrome/browser/ui/authentication/signin/add_account_signin/add_account_signin_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/add_account_signin/add_account_signin_coordinator.mm
index bf0f17b..b9aa5d74 100644
--- a/ios/chrome/browser/ui/authentication/signin/add_account_signin/add_account_signin_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/add_account_signin/add_account_signin_coordinator.mm
@@ -115,7 +115,7 @@
   [super start];
   self.identityInteractionManager =
       ios::GetChromeBrowserProvider()
-          ->GetChromeIdentityService()
+          .GetChromeIdentityService()
           ->CreateChromeIdentityInteractionManager(self);
 
   signin::IdentityManager* identityManager =
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_mediator.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_mediator.mm
index 2e5e457..1934680 100644
--- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_account_chooser/consistency_account_chooser_mediator.mm
@@ -64,7 +64,7 @@
 #pragma mark - Properties
 
 - (ios::ChromeIdentityService*)chromeIdentityService {
-  return ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+  return ios::GetChromeBrowserProvider().GetChromeIdentityService();
 }
 
 - (void)setSelectedIdentity:(ChromeIdentity*)identity {
@@ -115,7 +115,7 @@
 - (void)updateIdentityItemConfigurator:(IdentityItemConfigurator*)configurator
                     withChromeIdentity:(ChromeIdentity*)identity {
   configurator.gaiaID = identity.gaiaID;
-  configurator.name = identity.userGivenName;
+  configurator.name = identity.userFullName;
   configurator.email = identity.userEmail;
   configurator.avatar = [self.avatarCache resizedAvatarForIdentity:identity];
   configurator.selected = [identity isEqual:self.selectedIdentity];
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
index ca164ac54..fd3e389b 100644
--- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
@@ -169,8 +169,7 @@
   [self.contentView addArrangedSubview:self.identityButtonControl];
   [NSLayoutConstraint activateConstraints:@[
     [self.identityButtonControl.widthAnchor
-        constraintEqualToAnchor:self.contentView.widthAnchor
-                       constant:0]
+        constraintEqualToAnchor:self.contentView.widthAnchor]
   ]];
   // Add primary button.
   self.continueAsButton =
@@ -184,8 +183,7 @@
   [self.contentView addArrangedSubview:self.continueAsButton];
   [NSLayoutConstraint activateConstraints:@[
     [self.continueAsButton.widthAnchor
-        constraintEqualToAnchor:self.contentView.widthAnchor
-                       constant:0]
+        constraintEqualToAnchor:self.contentView.widthAnchor]
   ]];
   // Adjust the identity button control rounded corners to the same value than
   // the "continue as" button.
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
index cbfec8c4..044b795c 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
@@ -105,7 +105,6 @@
 
 - (AppLaunchConfiguration)appConfigurationForTestCase {
   AppLaunchConfiguration config;
-  config.features_disabled.push_back(kDiscoverFeedInNtp);
   config.features_disabled.push_back(signin::kMobileIdentityConsistency);
   config.features_enabled.push_back(signin::kSimplifySignOutIOS);
   return config;
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm
index c1b92c5..60c41d6 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_mice_egtest.mm
@@ -45,7 +45,6 @@
 - (AppLaunchConfiguration)appConfigurationForTestCase {
   AppLaunchConfiguration config;
   config.features_enabled.push_back(signin::kMobileIdentityConsistency);
-  config.features_disabled.push_back(kDiscoverFeedInNtp);
   return config;
 }
 
diff --git a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
index 5021f38..780412c1 100644
--- a/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/trusted_vault_reauthentication/trusted_vault_reauthentication_coordinator.mm
@@ -52,9 +52,8 @@
 
 - (void)interruptWithAction:(SigninCoordinatorInterruptAction)action
                  completion:(ProceduralBlock)completion {
-  ios::ChromeBrowserProvider* browserProvider = ios::GetChromeBrowserProvider();
   ios::ChromeTrustedVaultService* trustedVaultService =
-      browserProvider->GetChromeTrustedVaultService();
+      ios::GetChromeBrowserProvider().GetChromeTrustedVaultService();
   BOOL animated;
   switch (action) {
     case SigninCoordinatorInterruptActionNoDismiss:
@@ -96,9 +95,8 @@
   // If not, the coordinator can be closed successfuly, by calling
   // -[TrustedVaultReauthenticationCoordinator
   // reauthentificationCompletedWithSuccess:]
-  ios::ChromeBrowserProvider* browserProvider = ios::GetChromeBrowserProvider();
   ios::ChromeTrustedVaultService* trustedVaultService =
-      browserProvider->GetChromeTrustedVaultService();
+      ios::GetChromeBrowserProvider().GetChromeTrustedVaultService();
   self.identity = AuthenticationServiceFactory::GetForBrowserState(
                       self.browser->GetBrowserState())
                       ->GetAuthenticatedIdentity();
diff --git a/ios/chrome/browser/ui/authentication/signin_notification_infobar_delegate.mm b/ios/chrome/browser/ui/authentication/signin_notification_infobar_delegate.mm
index 788112d0..077ff25 100644
--- a/ios/chrome/browser/ui/authentication/signin_notification_infobar_delegate.mm
+++ b/ios/chrome/browser/ui/authentication/signin_notification_infobar_delegate.mm
@@ -69,7 +69,7 @@
   ChromeIdentity* identity = auth_service->GetAuthenticatedIdentity();
 
   UIImage* image = ios::GetChromeBrowserProvider()
-                       ->GetChromeIdentityService()
+                       .GetChromeIdentityService()
                        ->GetCachedAvatarForIdentity(identity);
   if (!image) {
     image = [UIImage imageNamed:@"ios_default_avatar"];
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
index b2bace2..65e4bcf2 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -527,8 +527,13 @@
 
 #pragma mark - Private
 
-// Returns the first ChromeIdentity object.
+// Returns the identity for the sync promo. This should be the signed in promo,
+// if the user is signed in. If not signed in, the default identity from
+// AccountManagerService.
 - (ChromeIdentity*)defaultIdentity {
+  if (self.authService->IsAuthenticated()) {
+    return self.authService->GetAuthenticatedIdentity();
+  }
   DCHECK(self.accountManagerService);
   return self.accountManagerService->GetDefaultIdentity();
 }
@@ -541,7 +546,7 @@
   } else {
     __weak SigninPromoViewMediator* weakSelf = self;
     ios::GetChromeBrowserProvider()
-        ->GetChromeIdentityService()
+        .GetChromeIdentityService()
         ->GetAvatarForIdentity(identity, ^(UIImage* identityAvatar) {
           if (weakSelf.identity != identity) {
             return;
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
index 327347b..4fc9c83 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator_unittest.mm
@@ -97,9 +97,7 @@
         initWithAccountManagerService:ChromeAccountManagerServiceFactory::
                                           GetForBrowserState(
                                               chrome_browser_state_.get())
-                          authService:AuthenticationServiceFactory::
-                                          GetForBrowserState(
-                                              chrome_browser_state_.get())
+                          authService:GetAuthenticationService()
                           prefService:chrome_browser_state_.get()->GetPrefs()
                           accessPoint:accessPoint
                             presenter:nil];
@@ -123,6 +121,11 @@
     return prefs;
   }
 
+  AuthenticationService* GetAuthenticationService() {
+    return AuthenticationServiceFactory::GetForBrowserState(
+        chrome_browser_state_.get());
+  }
+
   // Creates the default identity and adds it into the ChromeIdentityService.
   void AddDefaultIdentity() {
     expected_default_identity_ =
@@ -436,4 +439,20 @@
                                       prefService:browser_state->GetPrefs()]);
 }
 
+// Tests that the default identity is the primary account, when the user is
+// signed in.
+TEST_F(SigninPromoViewMediatorTest, SigninPromoWhileSignedIn) {
+  AddDefaultIdentity();
+  ChromeIdentity* signed_in_identity =
+      [FakeChromeIdentity identityWithEmail:@"johndoe2@example.com"
+                                     gaiaID:@"2"
+                                       name:@"johndoe2"];
+  GetAuthenticationService()->SignIn(signed_in_identity);
+  CreateMediator(signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS);
+  OCMStub([consumer_ configureSigninPromoWithConfigurator:[OCMArg any]
+                                          identityChanged:NO]);
+  [mediator_ signinPromoViewIsVisible];
+  EXPECT_EQ(signed_in_identity, mediator_.identity);
+}
+
 }  // namespace
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
index c8540b9..a328a23 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/identity_chooser/identity_chooser_mediator.mm
@@ -128,7 +128,7 @@
 
 // Getter for the Chrome identity service.
 - (ios::ChromeIdentityService*)chromeIdentityService {
-  return ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+  return ios::GetChromeBrowserProvider().GetChromeIdentityService();
 }
 
 #pragma mark - ChromeIdentityServiceObserver
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
index 11e33f8..334e517e 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
@@ -71,7 +71,10 @@
 - (void)start {
   DCHECK(self.accountManagerService);
 
-  self.selectedIdentity = [self findDefaultSelectedIdentity];
+  if (!self.selectedIdentity) {
+    // Select an identity if not selected yet.
+    self.selectedIdentity = [self findDefaultSelectedIdentity];
+  }
 
   // Make sure the view is loaded so the mediator can set it up.
   [self.unifiedConsentViewController loadViewIfNeeded];
@@ -122,7 +125,7 @@
     ChromeIdentity* selectedIdentity = self.selectedIdentity;
     __weak UnifiedConsentMediator* weakSelf = self;
     ios::GetChromeBrowserProvider()
-        ->GetChromeIdentityService()
+        .GetChromeIdentityService()
         ->GetAvatarForIdentity(selectedIdentity, ^(UIImage* identityAvatar) {
           if (weakSelf.selectedIdentity != selectedIdentity)
             return;
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator_unittest.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator_unittest.mm
index ea6edef..0bff60c 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator_unittest.mm
@@ -38,6 +38,9 @@
     identity2_ = [FakeChromeIdentity identityWithEmail:@"foo2@gmail.com"
                                                 gaiaID:@"foo2ID"
                                                   name:@"Fake Foo 2"];
+    identity3_ = [FakeChromeIdentity identityWithEmail:@"foo3@gmail.com"
+                                                gaiaID:@"foo3ID"
+                                                  name:@"Fake Foo 3"];
 
     TestChromeBrowserState::Builder builder;
     builder.AddTestingFactory(
@@ -51,13 +54,6 @@
 
     mediator_delegate_mock_ =
         OCMProtocolMock(@protocol(UnifiedConsentMediatorDelegate));
-    mediator_ = [[UnifiedConsentMediator alloc]
-        initWithUnifiedConsentViewController:view_controller_
-                       authenticationService:authentication_service()
-                       accountManagerService:
-                           ChromeAccountManagerServiceFactory::
-                               GetForBrowserState(browser_state_.get())];
-    mediator_.delegate = mediator_delegate_mock_;
   }
 
   void TearDown() override {
@@ -68,22 +64,39 @@
     PlatformTest::TearDown();
   }
   // Identity services.
-  AuthenticationService* authentication_service() {
+  AuthenticationService* GetAuthenticationService() {
     return AuthenticationServiceFactory::GetForBrowserState(
         browser_state_.get());
   }
 
-  ios::FakeChromeIdentityService* identity_service() {
+  ios::FakeChromeIdentityService* GetIdentityService() {
     return ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
   }
 
+  void AddIdentities() {
+    GetIdentityService()->AddIdentity(identity1_);
+    GetIdentityService()->AddIdentity(identity2_);
+    GetIdentityService()->AddIdentity(identity3_);
+  }
+
+  void CreateMediator() {
+    mediator_ = [[UnifiedConsentMediator alloc]
+        initWithUnifiedConsentViewController:view_controller_
+                       authenticationService:GetAuthenticationService()
+                       accountManagerService:
+                           ChromeAccountManagerServiceFactory::
+                               GetForBrowserState(browser_state_.get())];
+    mediator_.delegate = mediator_delegate_mock_;
+  }
+
  protected:
   // Needed for test browser state created by TestChromeBrowserState().
   web::WebTaskEnvironment task_environment_;
+  std::unique_ptr<TestChromeBrowserState> browser_state_;
+
   FakeChromeIdentity* identity1_ = nullptr;
   FakeChromeIdentity* identity2_ = nullptr;
-
-  std::unique_ptr<TestChromeBrowserState> browser_state_;
+  FakeChromeIdentity* identity3_ = nullptr;
 
   UnifiedConsentMediator* mediator_ = nullptr;
   PrefService* pref_service_ = nullptr;
@@ -96,6 +109,7 @@
 // no accounts on the device.
 TEST_F(UnifiedConsentMediatorTest,
        SelectDefaultIdentityForSignedOutUserWithNoAccounts) {
+  CreateMediator();
   [mediator_ start];
 
   ASSERT_EQ(nil, mediator_.selectedIdentity);
@@ -105,35 +119,76 @@
 // on the device is the first option.
 TEST_F(UnifiedConsentMediatorTest,
        SelectDefaultIdentityForSignedOutUserWithAccounts) {
-  identity_service()->AddIdentity(identity2_);
-  identity_service()->AddIdentity(identity1_);
+  AddIdentities();
+  CreateMediator();
 
   [mediator_ start];
 
+  ASSERT_EQ(identity1_, mediator_.selectedIdentity);
+}
+
+// Tests that the default identity becomes the next identity on the device after
+// forgetting the default identity.
+TEST_F(UnifiedConsentMediatorTest, SelectDefaultIdentityAfterForgetIdentity) {
+  AddIdentities();
+  CreateMediator();
+
+  [mediator_ start];
+  ASSERT_EQ(identity1_, mediator_.selectedIdentity);
+  GetIdentityService()->ForgetIdentity(identity1_, nil);
+
   ASSERT_EQ(identity2_, mediator_.selectedIdentity);
 }
 
 // Tests that the default identity selected for a signed-in user is the
 // authenticated identity.
 TEST_F(UnifiedConsentMediatorTest, SelectDefaultIdentityForSignedInUser) {
-  identity_service()->AddIdentity(identity2_);
-  identity_service()->AddIdentity(identity1_);
+  AddIdentities();
+  CreateMediator();
 
-  authentication_service()->SignIn(identity1_);
+  GetAuthenticationService()->SignIn(identity2_);
   [mediator_ start];
 
+  ASSERT_EQ(identity2_, mediator_.selectedIdentity);
+}
+
+// Tests that the default identity is the next identity on the device after
+// sign-out and forgetting the authenticated identity.
+TEST_F(UnifiedConsentMediatorTest,
+       SelectDefaultIdentityAfterSignOutAndForgetIdentity) {
+  AddIdentities();
+  CreateMediator();
+
+  GetAuthenticationService()->SignIn(identity3_);
+  [mediator_ start];
+  ASSERT_EQ(identity3_, mediator_.selectedIdentity);
+  GetAuthenticationService()->SignOut(signin_metrics::SIGNOUT_TEST, false, nil);
+  GetIdentityService()->ForgetIdentity(identity3_, nil);
+
   ASSERT_EQ(identity1_, mediator_.selectedIdentity);
 }
 
-// Tests that |start| will override the selected identity with a pre-determined
-// default identity based on the accounts on the device and user sign-in state.
-TEST_F(UnifiedConsentMediatorTest, OverrideIdentityForSignedInUser) {
-  identity_service()->AddIdentity(identity2_);
-  identity_service()->AddIdentity(identity1_);
+// Tests that the selected identity before start is kept.
+TEST_F(UnifiedConsentMediatorTest, SelectIdentity) {
+  AddIdentities();
+  CreateMediator();
 
-  authentication_service()->SignIn(identity1_);
   mediator_.selectedIdentity = identity2_;
   [mediator_ start];
 
-  ASSERT_EQ(identity1_, mediator_.selectedIdentity);
+  ASSERT_EQ(identity2_, mediator_.selectedIdentity);
+}
+
+// Tests that |start| will not override the selected identity with a
+// pre-determined default identity based on the accounts on the device and user
+// sign-in state.
+TEST_F(UnifiedConsentMediatorTest, DontOverrideIdentityForSignedInUser) {
+  AddIdentities();
+  CreateMediator();
+
+  GetAuthenticationService()->SignIn(identity1_);
+  mediator_.selectedIdentity = identity2_;
+  [mediator_ start];
+
+  ASSERT_EQ(identity2_, mediator_.selectedIdentity);
 }
diff --git a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
index eacf9d6..edd083d 100644
--- a/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
+++ b/ios/chrome/browser/ui/autofill/autofill_app_interface.mm
@@ -110,6 +110,12 @@
   // When we retrieve the form from the store, |in_store| should be set.
   password_manager::PasswordForm expected_form = form;
   expected_form.in_store = password_manager::PasswordForm::Store::kProfileStore;
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  expected_form.password_issues =
+      base::flat_map<password_manager::InsecureType,
+                     password_manager::InsecurityMetadata>();
   // Check the result and ensure PasswordStore processed this.
   TestStoreConsumer consumer;
   for (const auto& result : consumer.GetStoreResults()) {
@@ -461,8 +467,7 @@
 }
 
 + (NSString*)paymentsRiskData {
-  return base::SysUTF8ToNSString(
-      ios::GetChromeBrowserProvider()->GetRiskData());
+  return base::SysUTF8ToNSString(ios::GetChromeBrowserProvider().GetRiskData());
 }
 
 #pragma mark - Private
diff --git a/ios/chrome/browser/ui/autofill/cells/cvc_item.mm b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
index 1c9140f..4cd9822 100644
--- a/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
+++ b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
@@ -150,7 +150,7 @@
     _dateContainerView.translatesAutoresizingMaskIntoConstraints = NO;
     [contentView addSubview:_dateContainerView];
 
-    _monthInput = ios::GetChromeBrowserProvider()->CreateStyledTextField();
+    _monthInput = ios::GetChromeBrowserProvider().CreateStyledTextField();
     _monthInput.placeholder = l10n_util::GetNSString(
         IDS_IOS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH);
     _monthInput.accessibilityIdentifier = @"month_textField";
@@ -165,7 +165,7 @@
     _dateSeparator.translatesAutoresizingMaskIntoConstraints = NO;
     [_dateContainerView addSubview:_dateSeparator];
 
-    _yearInput = ios::GetChromeBrowserProvider()->CreateStyledTextField();
+    _yearInput = ios::GetChromeBrowserProvider().CreateStyledTextField();
     _yearInput.placeholder =
         l10n_util::GetNSString(IDS_IOS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR);
     _yearInput.accessibilityIdentifier = @"year_textField";
@@ -178,7 +178,7 @@
     _CVCContainerView.translatesAutoresizingMaskIntoConstraints = NO;
     [contentView addSubview:_CVCContainerView];
 
-    _CVCInput = ios::GetChromeBrowserProvider()->CreateStyledTextField();
+    _CVCInput = ios::GetChromeBrowserProvider().CreateStyledTextField();
     _CVCInput.textColor = [UIColor colorNamed:kTextPrimaryColor];
     _CVCInput.placeholder =
         l10n_util::GetNSString(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC);
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
index 7963f93..dd0d263f 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -450,7 +450,7 @@
 
 void ChromeAutofillClientIOS::LoadRiskData(
     base::OnceCallback<void(const std::string&)> callback) {
-  std::move(callback).Run(ios::GetChromeBrowserProvider()->GetRiskData());
+  std::move(callback).Run(ios::GetChromeBrowserProvider().GetRiskData());
 }
 
 LogManager* ChromeAutofillClientIOS::GetLogManager() const {
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
index 9ccc6df..079afcade 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
@@ -290,9 +290,17 @@
   [[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
       assertWithMatcher:grey_notVisible()];
 
+  // TODO(crbug.com/1220724): iOS 15 phones seem to act more like iPads now,
+  // dismissing the keyboard when tapping on the option above. Confirm that this
+  // is expected and either fix, or remove this comment.
+  BOOL isIOS15 = NO;
+  if (@available(iOS 15, *)) {
+    isIOS15 = YES;
+  }
+
   // On iPad the picker is a table view in a popover, we need to dismiss that
   // first.
-  if ([ChromeEarlGrey isIPadIdiom]) {
+  if ([ChromeEarlGrey isIPadIdiom] || isIOS15) {
     // Tap in the web view so the popover dismisses.
     [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
         performAction:grey_tapAtPoint(CGPointMake(0, 0))];
@@ -319,6 +327,16 @@
   // Verify the status of the icons.
   [[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
       assertWithMatcher:grey_sufficientlyVisible()];
+
+  // TODO(crbug.com/1227392): This doesn't appear to work on iOS15 phone. It
+  // appears the profiles icon is visible and selected (so interaction
+  // disabled), but the keyboard itself is visible. As a workaround, tap the
+  // keyboard icon and continue the test.
+  if (![ChromeEarlGrey isIPadIdiom] && isIOS15) {
+    [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
+        performAction:grey_tap()];
+  }
+
   [[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
       assertWithMatcher:grey_userInteractionEnabled()];
   [[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
@@ -446,7 +464,8 @@
 }
 
 // Tests that the manual fallback view is present in incognito.
-- (void)testIncognitoManualFallbackMenu {
+// Disabled due to flakiness. See crbug.com/1115321.
+- (void)DISABLED_testIncognitoManualFallbackMenu {
   // Add the profile to use for verification.
   [AutofillAppInterface saveExampleProfile];
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm
index d375666d9..686947e 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/full_card_requester_unittest.mm
@@ -100,6 +100,14 @@
   }
 
   void TearDown() override {
+    // Remove the frame in order to destroy the AutofillDriver before the
+    // AutofillClient.
+    web::FakeWebFramesManager* frames_manager =
+        static_cast<web::FakeWebFramesManager*>(
+            web_state()->GetWebFramesManager());
+    std::string frame_id = frames_manager->GetMainWebFrame()->GetFrameId();
+    frames_manager->RemoveWebFrame(frame_id);
+
     personal_data_manager_.SetPrefService(nullptr);
     PlatformTest::TearDown();
   }
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 0534159..2fcc1f3 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -219,6 +219,9 @@
     "//ios/chrome/browser/bookmarks",
     "//ios/chrome/browser/browser_state:test_support",
     "//ios/chrome/browser/main:test_support",
+    "//ios/chrome/browser/signin",
+    "//ios/chrome/browser/signin:test_support",
+    "//ios/public/provider/chrome/browser/signin:test_support",
     "//ios/web/public/test",
   ]
 }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm b/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm
index fb7f21a..575fb620 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.mm
@@ -12,6 +12,8 @@
 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
 #import "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/main/test_browser.h"
+#import "ios/chrome/browser/signin/authentication_service_factory.h"
+#import "ios/chrome/browser/signin/authentication_service_fake.h"
 #include "ios/web/public/test/test_web_thread.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -27,6 +29,10 @@
   // Get a BookmarkModel from the test ChromeBrowserState.
   TestChromeBrowserState::Builder test_cbs_builder;
 
+  test_cbs_builder.AddTestingFactory(
+      AuthenticationServiceFactory::GetInstance(),
+      base::BindRepeating(
+          &AuthenticationServiceFake::CreateAuthenticationService));
   state_dir_ = std::make_unique<base::ScopedTempDir>();
   ASSERT_TRUE(state_dir_->CreateUniqueTempDir());
   test_cbs_builder.SetPath(state_dir_->GetPath());
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index c6401aa..24f82a6 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2852,7 +2852,7 @@
 - (void)ensureVoiceSearchControllerCreated {
   if (!_voiceSearchController) {
     VoiceSearchProvider* provider =
-        ios::GetChromeBrowserProvider()->GetVoiceSearchProvider();
+        ios::GetChromeBrowserProvider().GetVoiceSearchProvider();
     if (provider) {
       _voiceSearchController =
           provider->CreateVoiceSearchController(self.browser);
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 4a257bc..faabc32 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -7,8 +7,6 @@
     "content_suggestions_action_handler.h",
     "content_suggestions_alert_factory.h",
     "content_suggestions_alert_factory.mm",
-    "content_suggestions_category_wrapper.h",
-    "content_suggestions_category_wrapper.mm",
     "content_suggestions_consumer.h",
     "content_suggestions_coordinator.h",
     "content_suggestions_coordinator.mm",
@@ -18,8 +16,6 @@
     "content_suggestions_header_view_controller.mm",
     "content_suggestions_mediator.h",
     "content_suggestions_mediator.mm",
-    "content_suggestions_metrics_recorder.h",
-    "content_suggestions_metrics_recorder.mm",
     "content_suggestions_service_bridge_observer.h",
     "content_suggestions_service_bridge_observer.mm",
     "discover_feed_delegate.h",
@@ -33,6 +29,7 @@
   ]
   deps = [
     ":constants",
+    ":content_suggestions_util",
     ":feature_flags",
     ":metrics",
     "//base",
@@ -115,6 +112,18 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+source_set("content_suggestions_util") {
+  sources = [
+    "content_suggestions_category_wrapper.h",
+    "content_suggestions_category_wrapper.mm",
+  ]
+  deps = [
+    "//base",
+    "//components/ntp_snippets",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 source_set("constants") {
   sources = [
     "content_suggestions_constants.h",
@@ -146,7 +155,6 @@
     "content_suggestions_layout.h",
     "content_suggestions_layout.mm",
     "content_suggestions_menu_provider.h",
-    "content_suggestions_metrics_recording.h",
     "content_suggestions_view_controller.h",
     "content_suggestions_view_controller.mm",
     "content_suggestions_view_controller_audience.h",
@@ -202,13 +210,22 @@
 
 source_set("metrics") {
   sources = [
+    "content_suggestions_metrics_recorder.h",
+    "content_suggestions_metrics_recorder.mm",
+    "content_suggestions_metrics_recording.h",
     "discover_feed_metrics_recorder.h",
     "discover_feed_metrics_recorder.mm",
   ]
   deps = [
+    ":content_suggestions_util",
     ":feature_flags",
     "//base",
     "//components/feed/core/v2/public:common",
+    "//components/ntp_snippets",
+    "//ios/chrome/browser/ui/content_suggestions/cells",
+    "//ios/chrome/browser/ui/content_suggestions/cells:cells_ui",
+    "//ios/chrome/browser/ui/content_suggestions/identifier",
+    "//ui/base",
   ]
   configs += [ "//build/config/compiler:enable_arc" ]
 }
@@ -265,6 +282,7 @@
     ":content_suggestions",
     ":content_suggestions_ui",
     ":content_suggestions_ui_util",
+    ":content_suggestions_util",
     "//base",
     "//base/test:test_support",
     "//components/ntp_snippets",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h
index b5175e4..7988127c 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.h
@@ -13,6 +13,7 @@
 
 @class BubblePresenter;
 @class ContentSuggestionsHeaderViewController;
+@class ContentSuggestionsMetricsRecorder;
 @class DiscoverFeedMetricsRecorder;
 @protocol NewTabPageCommands;
 @protocol NewTabPageControllerDelegate;
@@ -65,6 +66,10 @@
 @property(nonatomic, strong)
     DiscoverFeedMetricsRecorder* discoverFeedMetricsRecorder;
 
+// Metrics recorder for the Zine feed events related to ContentSuggestions.
+@property(nonatomic, strong)
+    ContentSuggestionsMetricsRecorder* contentSuggestionsMetricsRecorder;
+
 // Dismisses all modals owned by the NTP mediator.
 - (void)dismissModals;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
index 2728fd6..729c10a 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -118,7 +118,6 @@
     ContentSuggestionsMediator* contentSuggestionsMediator;
 @property(nonatomic, strong)
     ContentSuggestionsHeaderSynchronizer* headerCollectionInteractionHandler;
-@property(nonatomic, strong) ContentSuggestionsMetricsRecorder* metricsRecorder;
 @property(nonatomic, strong) UIViewController* discoverFeedViewController;
 @property(nonatomic, strong) UIView* discoverFeedHeaderMenuButton;
 @property(nonatomic, strong) URLDragDropHandler* dragDropHandler;
@@ -255,9 +254,8 @@
   self.headerController.promoCanShow =
       [self.contentSuggestionsMediator notificationPromo]->CanShow();
 
-  self.metricsRecorder = [[ContentSuggestionsMetricsRecorder alloc] init];
-  self.metricsRecorder.delegate = self.contentSuggestionsMediator;
-
+  self.contentSuggestionsMetricsRecorder.delegate =
+      self.contentSuggestionsMediator;
 
   // Offset to maintain Discover feed scroll position.
   CGFloat offset = 0;
@@ -284,7 +282,8 @@
   self.suggestionsViewController.audience = self;
   self.suggestionsViewController.overscrollDelegate = self;
   self.suggestionsViewController.themeChangeDelegate = self;
-  self.suggestionsViewController.metricsRecorder = self.metricsRecorder;
+  self.suggestionsViewController.metricsRecorder =
+      self.contentSuggestionsMetricsRecorder;
   id<SnackbarCommands> dispatcher =
       static_cast<id<SnackbarCommands>>(self.browser->GetCommandDispatcher());
   self.suggestionsViewController.dispatcher = dispatcher;
@@ -317,7 +316,7 @@
   self.ntpMediator.NTPMetrics = [[NTPHomeMetrics alloc]
       initWithBrowserState:self.browser->GetBrowserState()
                   webState:self.webState];
-  self.ntpMediator.metricsRecorder = self.metricsRecorder;
+  self.ntpMediator.metricsRecorder = self.contentSuggestionsMetricsRecorder;
   self.ntpMediator.suggestionsViewController = self.suggestionsViewController;
   self.ntpMediator.suggestionsMediator = self.contentSuggestionsMediator;
   self.ntpMediator.suggestionsService = contentSuggestionsService;
@@ -376,7 +375,7 @@
   self.headerController = nil;
   if (IsDiscoverFeedEnabled() && !IsRefactoredNTP()) {
     ios::GetChromeBrowserProvider()
-        ->GetDiscoverFeedProvider()
+        .GetDiscoverFeedProvider()
         ->RemoveFeedViewController(self.discoverFeedViewController);
   }
   self.contentSuggestionsExpanded = nil;
@@ -414,7 +413,7 @@
 
 - (void)discoverFeedShown {
   if (IsDiscoverFeedEnabled() && !self.feedShownWasCalled) {
-    ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->FeedWasShown();
+    ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->FeedWasShown();
     self.feedShownWasCalled = YES;
   }
 }
@@ -490,7 +489,7 @@
 
 - (void)handleThemeChange {
   if (IsDiscoverFeedEnabled()) {
-    ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->UpdateTheme();
+    ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->UpdateTheme();
   }
 }
 
@@ -630,7 +629,7 @@
 
 - (void)loadMoreFeedArticles {
   ios::GetChromeBrowserProvider()
-      ->GetDiscoverFeedProvider()
+      .GetDiscoverFeedProvider()
       ->LoadMoreFeedArticles();
   [self.discoverFeedMetricsRecorder recordInfiniteFeedTriggered];
 }
@@ -668,7 +667,7 @@
 
 - (void)reload {
   if (IsDiscoverFeedEnabled() && !IsRefactoredNTP() && [self isFeedVisible]) {
-    ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->RefreshFeed();
+    ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->RefreshFeed();
   }
   [self.contentSuggestionsMediator.dataSink reloadAllData];
 }
@@ -809,7 +808,7 @@
     return nil;
 
   UIViewController* discoverFeed = ios::GetChromeBrowserProvider()
-                                       ->GetDiscoverFeedProvider()
+                                       .GetDiscoverFeedProvider()
                                        ->NewFeedViewController(self.browser);
   // TODO(crbug.com/1085419): Once the CollectionView is cleanly exposed, remove
   // this loop.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
index a2e35e14..0c5e68a5 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
@@ -182,8 +182,7 @@
     ntp_tiles::NTPTile& ntpTile = _mostVisitedDataForLogging[i];
     if (ntpTile.url == item.URL) {
       RecordNTPTileImpression(i, ntpTile.source, ntpTile.title_source,
-                              item.attributes, ntpTile.data_generation_time,
-                              ntpTile.url);
+                              item.attributes, ntpTile.url);
       // Reset the URL to be sure to log the impression only once.
       ntpTile.url = GURL();
       break;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
index 14b8744..36c7c40 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -410,7 +410,7 @@
       ContentSuggestionsWhatsNewItem* item =
           [[ContentSuggestionsWhatsNewItem alloc] initWithType:0];
       item.icon = ios::GetChromeBrowserProvider()
-                      ->GetBrandedImageProvider()
+                      .GetBrandedImageProvider()
                       ->GetWhatsNewIconImage(_notificationPromo->icon());
       item.text = base::SysUTF8ToNSString(_notificationPromo->promo_text());
       [convertedSuggestions addObject:item];
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 e0df37d..33a73840 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -489,7 +489,15 @@
 // Tests that when navigating back to the NTP while having the omnibox focused
 // and moved up, the scroll position restored is the position before the omnibox
 // is selected.
-- (void)testPositionRestoredWithOmniboxFocused {
+// TODO(crbug.com/1227139): Test is flaky on simulator.
+#if TARGET_IPHONE_SIMULATOR
+#define MAYBE_testPositionRestoredWithOmniboxFocused \
+  DISABLED_testPositionRestoredWithOmniboxFocused
+#else
+#define MAYBE_testPositionRestoredWithOmniboxFocused \
+  testPositionRestoredWithOmniboxFocused
+#endif
+- (void)MAYBE_testPositionRestoredWithOmniboxFocused {
   [self addMostVisitedTile];
 
   // Add suggestions to be able to scroll on iPad.
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
index 90c638a..0498c3e 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -639,9 +639,8 @@
       recordAction:new_tab_page_uma::ACTION_OPENED_MOST_VISITED_ENTRY];
   base::RecordAction(base::UserMetricsAction("MobileNTPMostVisited"));
 
-  // TODO(crbug.com/763946): Plumb generation time.
   RecordNTPTileClick(mostVisitedIndex, item.source, item.titleSource,
-                     item.attributes, base::Time(), GURL());
+                     item.attributes, GURL());
 }
 
 // Shows a snackbar with an action to undo the removal of the most visited item
@@ -744,7 +743,7 @@
     // in the background. When background fetch completes, all observers will
     // be notified to refresh the user's avatar.
     ios::ChromeIdentityService* identityService =
-        ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+        ios::GetChromeBrowserProvider().GetChromeIdentityService();
     image = identityService->GetCachedAvatarForIdentity(identity);
     if (!image) {
       image = [self defaultAvatar];
@@ -769,7 +768,7 @@
 // in but avatar image is not available yet.
 - (UIImage*)defaultAvatar {
   return ios::GetChromeBrowserProvider()
-      ->GetSigninResourcesProvider()
+      .GetSigninResourcesProvider()
       ->GetDefaultAvatar();
 }
 
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
index 744149e..f9217e6c 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
+++ b/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
@@ -66,7 +66,7 @@
         setButtonText:l10n_util::GetNSString(
                           IDS_IOS_DEFAULT_NON_MODAL_PRIMARY_BUTTON_TEXT)];
     UIImage* image = ios::GetChromeBrowserProvider()
-                         ->GetBrandedImageProvider()
+                         .GetBrandedImageProvider()
                          ->GetNonModalPromoImage();
     [self.bannerViewController setIconImage:image];
     [self.bannerViewController setUseIconBackgroundTint:NO];
diff --git a/ios/chrome/browser/ui/default_promo/tailored_promo_util.mm b/ios/chrome/browser/ui/default_promo/tailored_promo_util.mm
index db5445a..1565bf1 100644
--- a/ios/chrome/browser/ui/default_promo/tailored_promo_util.mm
+++ b/ios/chrome/browser/ui/default_promo/tailored_promo_util.mm
@@ -39,7 +39,7 @@
       subtitle =
           GetNSString(IDS_IOS_DEFAULT_BROWSER_TAILORED_STAY_SAFE_DESCRIPTION);
       image = ios::GetChromeBrowserProvider()
-                  ->GetBrandedImageProvider()
+                  .GetBrandedImageProvider()
                   ->GetStaySafePromoImage();
       break;
     case DefaultPromoTypeMadeForIOS:
@@ -47,13 +47,13 @@
         title = GetNSString(
             IDS_IOS_DEFAULT_BROWSER_TAILORED_BUILT_FOR_IPADOS_TITLE);
         image = ios::GetChromeBrowserProvider()
-                    ->GetBrandedImageProvider()
+                    .GetBrandedImageProvider()
                     ->GetMadeForIPadOSPromoImage();
       } else {
         title =
             GetNSString(IDS_IOS_DEFAULT_BROWSER_TAILORED_BUILT_FOR_IOS_TITLE);
         image = ios::GetChromeBrowserProvider()
-                    ->GetBrandedImageProvider()
+                    .GetBrandedImageProvider()
                     ->GetMadeForIOSPromoImage();
       }
       subtitle = GetNSString(
diff --git a/ios/chrome/browser/ui/download/download_manager_view_controller.mm b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
index 4fea429..016a231d 100644
--- a/ios/chrome/browser/ui/download/download_manager_view_controller.mm
+++ b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
@@ -506,7 +506,7 @@
     _installDriveIcon = [[UIImageView alloc] initWithFrame:CGRectZero];
     _installDriveIcon.translatesAutoresizingMaskIntoConstraints = NO;
     _installDriveIcon.image = ios::GetChromeBrowserProvider()
-                                  ->GetBrandedImageProvider()
+                                  .GetBrandedImageProvider()
                                   ->GetDownloadGoogleDriveImage();
   }
   return _installDriveIcon;
diff --git a/ios/chrome/browser/ui/elements/chrome_activity_overlay_view_controller.mm b/ios/chrome/browser/ui/elements/chrome_activity_overlay_view_controller.mm
index 6d721ff..d62f6f45 100644
--- a/ios/chrome/browser/ui/elements/chrome_activity_overlay_view_controller.mm
+++ b/ios/chrome/browser/ui/elements/chrome_activity_overlay_view_controller.mm
@@ -55,8 +55,7 @@
     [activityView.bottomAnchor
         constraintEqualToAnchor:containerView.bottomAnchor
                        constant:-kContainerViewSpacing],
-    [activityView.centerXAnchor constraintEqualToAnchor:label.centerXAnchor
-                                               constant:0],
+    [activityView.centerXAnchor constraintEqualToAnchor:label.centerXAnchor],
     [activityView.heightAnchor
         constraintEqualToConstant:kActivityIndicatorViewSize],
     [activityView.widthAnchor
diff --git a/ios/chrome/browser/ui/first_run/BUILD.gn b/ios/chrome/browser/ui/first_run/BUILD.gn
index e0131c9..5363bd6 100644
--- a/ios/chrome/browser/ui/first_run/BUILD.gn
+++ b/ios/chrome/browser/ui/first_run/BUILD.gn
@@ -208,7 +208,10 @@
     "//build/config/ios:xctest_config",
   ]
   testonly = true
-  sources = [ "first_run_egtest.mm" ]
+  sources = [
+    "first_run_egtest.mm",
+    "legacy_first_run_egtest.mm",
+  ]
   deps = [
     ":constants",
     ":eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/first_run/first_run_constants.h b/ios/chrome/browser/ui/first_run/first_run_constants.h
index cd17e04..1589e06 100644
--- a/ios/chrome/browser/ui/first_run/first_run_constants.h
+++ b/ios/chrome/browser/ui/first_run/first_run_constants.h
@@ -13,6 +13,15 @@
 // run.
 extern NSString* const kUMAMetricsButtonAccessibilityIdentifier;
 
+// The accessibility identifier for the Welcome screen shown in first run.
+extern NSString* const kFirstRunWelcomeScreenAccessibilityIdentifier;
+
+// The accessibility identifier for the Sign in screen shown in first run.
+extern NSString* const kFirstRunSignInScreenAccessibilityIdentifier;
+
+// The accessibility identifier for the Sync screen shown in first run.
+extern NSString* const kFirstRunSyncScreenAccessibilityIdentifier;
+
 }  // first_run
 
 #endif  // IOS_CHROME_BROWSER_UI_FIRST_RUN_FIRST_RUN_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/first_run/first_run_constants.mm b/ios/chrome/browser/ui/first_run/first_run_constants.mm
index 40276c9..1269639a 100644
--- a/ios/chrome/browser/ui/first_run/first_run_constants.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_constants.mm
@@ -13,4 +13,13 @@
 NSString* const kUMAMetricsButtonAccessibilityIdentifier =
     @"UMAMetricsButtonAccessibilityIdentifier";
 
+NSString* const kFirstRunWelcomeScreenAccessibilityIdentifier =
+    @"firstRunWelcomeScreenAccessibilityIdentifier";
+
+NSString* const kFirstRunSignInScreenAccessibilityIdentifier =
+    @"firstRunSignInScreenAccessibilityIdentifier";
+
+NSString* const kFirstRunSyncScreenAccessibilityIdentifier =
+    @"firstRunSyncScreenAccessibilityIdentifier";
+
 }  // first_run
diff --git a/ios/chrome/browser/ui/first_run/first_run_egtest.mm b/ios/chrome/browser/ui/first_run/first_run_egtest.mm
index 609d0ca..efbccca 100644
--- a/ios/chrome/browser/ui/first_run/first_run_egtest.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_egtest.mm
@@ -1,18 +1,15 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/strings/sys_string_conversions.h"
-#import "base/test/ios/wait_util.h"
-#import "ios/chrome/browser/ui/authentication/signin/signin_constants.h"
-#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
-#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
 #import "ios/chrome/browser/ui/first_run/first_run_app_interface.h"
 #import "ios/chrome/browser/ui/first_run/first_run_constants.h"
 #include "ios/chrome/browser/ui/ui_feature_flags.h"
 #include "ios/chrome/grit/ios_chromium_strings.h"
 #include "ios/chrome/grit/ios_strings.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_test_case.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
@@ -22,27 +19,7 @@
 #error "This file requires ARC support."
 #endif
 
-using chrome_test_util::ButtonWithAccessibilityLabel;
-using chrome_test_util::SyncSettingsConfirmButton;
-using chrome_test_util::MatchInWindowWithNumber;
-using chrome_test_util::MatchInBlockerWindowWithNumber;
-using chrome_test_util::FakeOmnibox;
-
-namespace {
-
-// Returns matcher for the opt in accept button.
-id<GREYMatcher> FirstRunOptInAcceptButton() {
-  return ButtonWithAccessibilityLabel(
-      l10n_util::GetNSString(IDS_IOS_FIRSTRUN_OPT_IN_ACCEPT_BUTTON));
-}
-
-// Returns matcher for the skip sign in button.
-id<GREYMatcher> SkipSigninButton() {
-  return grey_accessibilityID(kSkipSigninAccessibilityIdentifier);
-}
-}
-
-// Tests first run settings and navigation.
+// Test first run stages
 @interface FirstRunTestCase : ChromeTestCase
 @end
 
@@ -65,7 +42,8 @@
 - (AppLaunchConfiguration)appConfigurationForTestCase {
   AppLaunchConfiguration config;
   config.features_disabled.push_back(kLocationPermissionsPrompt);
-  config.features_disabled.push_back(kEnableFREUIModuleIOS);
+
+  config.features_enabled.push_back(kEnableFREUIModuleIOS);
 
   // Show the First Run UI at startup.
   config.additional_args.push_back("-FirstRunForceEnabled");
@@ -77,8 +55,82 @@
   return config;
 }
 
-// Navigates to the terms of service and back.
+#pragma mark - Helpers
+
+// Checks that the welcome screen is displayed.
+- (void)verifyWelcomeScreenIsDisplayed {
+  [[EarlGrey selectElementWithMatcher:
+                 grey_accessibilityID(
+                     first_run::kFirstRunWelcomeScreenAccessibilityIdentifier)]
+      assertWithMatcher:grey_notNil()];
+}
+
+// Checks that the sign in screen is displayed.
+- (void)verifySignInScreenIsDisplayed {
+  [[EarlGrey selectElementWithMatcher:
+                 grey_accessibilityID(
+                     first_run::kFirstRunSignInScreenAccessibilityIdentifier)]
+      assertWithMatcher:grey_notNil()];
+}
+
+// Checks that the sync screen is displayed.
+- (void)verifySyncScreenIsDisplayed {
+  [[EarlGrey selectElementWithMatcher:
+                 grey_accessibilityID(
+                     first_run::kFirstRunSyncScreenAccessibilityIdentifier)]
+      assertWithMatcher:grey_notNil()];
+}
+
+#pragma mark - Tests
+
+// Checks that the Welcome screen is displayed correctly.
+- (void)testWelcomeScreenUI {
+  [self verifyWelcomeScreenIsDisplayed];
+
+  NSString* expectedTitle =
+      [ChromeEarlGrey isIPadIdiom]
+          ? l10n_util::GetNSString(IDS_IOS_FIRST_RUN_WELCOME_SCREEN_TITLE_IPAD)
+          : l10n_util::GetNSString(
+                IDS_IOS_FIRST_RUN_WELCOME_SCREEN_TITLE_IPHONE);
+  [[EarlGrey selectElementWithMatcher:grey_text(expectedTitle)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  [[EarlGrey
+      selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                   IDS_IOS_FIRST_RUN_WELCOME_SCREEN_SUBTITLE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_FIRST_RUN_WELCOME_SCREEN_METRICS_CONSENT))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_FIRST_RUN_WELCOME_SCREEN_ACCEPT_BUTTON))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Checks that the Sign In screen is displayed correctly.
+- (void)testSignInScreenUI {
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_FIRST_RUN_WELCOME_SCREEN_ACCEPT_BUTTON))]
+      performAction:grey_tap()];
+
+  [self verifySignInScreenIsDisplayed];
+
+  [[EarlGrey selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                          IDS_IOS_FIRST_RUN_SIGNIN_TITLE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  [[EarlGrey selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                          IDS_IOS_FIRST_RUN_SIGNIN_SUBTITLE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Navigates to the Terms of Service and back.
 - (void)testTermsAndConditions {
+  // Tap on “Terms of Service” on the first screen
+  [self verifyWelcomeScreenIsDisplayed];
   id<GREYMatcher> termsOfServiceLink =
       grey_accessibilityLabel(@"Terms of Service");
   [[EarlGrey selectElementWithMatcher:termsOfServiceLink]
@@ -88,129 +140,21 @@
                                           IDS_IOS_FIRSTRUN_TERMS_TITLE))]
       assertWithMatcher:grey_sufficientlyVisible()];
 
+  // Tap on “Done” on the ToS screen
   [[EarlGrey
-      selectElementWithMatcher:grey_allOf(
-                                   grey_accessibilityID(@"ic_arrow_back"),
-                                   grey_accessibilityTrait(
-                                       UIAccessibilityTraitButton),
-                                   nil)] performAction:grey_tap()];
+      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
+      performAction:grey_tap()];
 
   // Ensure we went back to the First Run screen.
-  [[EarlGrey selectElementWithMatcher:termsOfServiceLink]
-      assertWithMatcher:grey_sufficientlyVisible()];
+  [self verifyWelcomeScreenIsDisplayed];
 
-  // Ensure that we have completed First Runs.
-  // Accept the FRE.
-  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
-      performAction:grey_tap()];
-  // Dismiss sign-in.
-  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
-      performAction:grey_tap()];
-}
-
-// Toggle the UMA checkbox.
-- (void)testToggleMetricsOn {
-  id<GREYMatcher> metrics =
-      grey_accessibilityID(first_run::kUMAMetricsButtonAccessibilityIdentifier);
-  [[EarlGrey selectElementWithMatcher:metrics] performAction:grey_tap()];
-
-  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
+  // And that the button is working.
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_FIRST_RUN_WELCOME_SCREEN_ACCEPT_BUTTON))]
       performAction:grey_tap()];
 
-  GREYAssertNotEqual([FirstRunAppInterface isUMACollectionEnabled],
-                     [FirstRunAppInterface isUMACollectionEnabledByDefault],
-                     @"Metrics reporting pref is incorrect.");
-
-  // Ensure that we have completed First Run, otherwise Earl Grey test crashes
-  // on check that the sign-in coordinator is no longer running.
-  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
-      performAction:grey_tap()];
-}
-
-// Dismisses the first run screens.
-- (void)testDismissFirstRun {
-  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
-      performAction:grey_tap()];
-
-  GREYAssertEqual([FirstRunAppInterface isUMACollectionEnabled],
-                  [FirstRunAppInterface isUMACollectionEnabledByDefault],
-                  @"Metrics reporting does not match.");
-
-  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
-      performAction:grey_tap()];
-
-  [[EarlGrey selectElementWithMatcher:FakeOmnibox()]
-      assertWithMatcher:grey_sufficientlyVisible()];
-}
-
-// Signs in to an account and then taps the Advanced link to go to settings.
-- (void)testSignInAndTapSettingsLink {
-  FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
-  [SigninEarlGrey addFakeIdentity:fakeIdentity];
-
-  // Launch First Run and accept tems of services.
-  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
-      performAction:grey_tap()];
-
-  // Tap Settings link.
-  [SigninEarlGreyUI tapSettingsLink];
-
-  // Check Sync hasn't started yet, allowing the user to change some settings.
-  GREYAssertFalse([FirstRunAppInterface isSyncFirstSetupComplete],
-                  @"Sync shouldn't have finished its original setup yet");
-
-  // Close Settings, user is still signed in and sync is now starting.
-  [[EarlGrey selectElementWithMatcher:SyncSettingsConfirmButton()]
-      performAction:grey_tap()];
-
-  [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
-
-  GREYAssertTrue([FirstRunAppInterface isSyncFirstSetupComplete],
-                 @"Sync should have finished its original setup");
-}
-
-// Checks FRE shows in only one window.
-- (void)testFirstRunInMultiWindow {
-  if (![ChromeEarlGrey areMultipleWindowsSupported])
-    EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
-
-  [ChromeEarlGrey openNewWindow];
-  [ChromeEarlGrey waitForForegroundWindowCount:2];
-
-  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(
-                                          0, grey_accessibilityLabel(
-                                                 @"Terms of Service"))]
-      assertWithMatcher:grey_notNil()];
-
-  // Check UI Blocked in second window and that message is a button.
-  [[EarlGrey
-      selectElementWithMatcher:
-          MatchInBlockerWindowWithNumber(
-              1,
-              grey_text(l10n_util::GetNSString(
-                  IDS_IOS_UI_BLOCKED_USE_OTHER_WINDOW_SWITCH_WINDOW_ACTION)))]
-      assertWithMatcher:grey_allOf(
-                            grey_sufficientlyVisible(),
-                            grey_ancestor(grey_kindOfClassName(@"UIButton")),
-                            nil)];
-
-  // Finish FRE.
-  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(
-                                          0, FirstRunOptInAcceptButton())]
-      performAction:grey_tap()];
-  [[EarlGrey
-      selectElementWithMatcher:MatchInWindowWithNumber(0, SkipSigninButton())]
-      performAction:grey_tap()];
-
-  // Check for both fake omniboxes visibility.
-  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(0, FakeOmnibox())]
-      assertWithMatcher:grey_sufficientlyVisible()];
-
-  // TODO(crbug.com/1169687) enable following test once EG2 bug for multiwindow
-  //    grey_sufficientlyVisible is fixed.
-  // [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(1,
-  // FakeOmnibox())]
-  //  assertWithMatcher:grey_sufficientlyVisible()];
+  [self verifySignInScreenIsDisplayed];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/first_run/legacy_first_run_egtest.mm b/ios/chrome/browser/ui/first_run/legacy_first_run_egtest.mm
new file mode 100644
index 0000000..67cbcb0
--- /dev/null
+++ b/ios/chrome/browser/ui/first_run/legacy_first_run_egtest.mm
@@ -0,0 +1,216 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/sys_string_conversions.h"
+#import "base/test/ios/wait_util.h"
+#import "ios/chrome/browser/ui/authentication/signin/signin_constants.h"
+#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
+#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h"
+#import "ios/chrome/browser/ui/first_run/first_run_app_interface.h"
+#import "ios/chrome/browser/ui/first_run/first_run_constants.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
+#include "ios/chrome/grit/ios_chromium_strings.h"
+#include "ios/chrome/grit/ios_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+#include "ui/base/l10n/l10n_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using chrome_test_util::ButtonWithAccessibilityLabel;
+using chrome_test_util::SyncSettingsConfirmButton;
+using chrome_test_util::MatchInWindowWithNumber;
+using chrome_test_util::MatchInBlockerWindowWithNumber;
+using chrome_test_util::FakeOmnibox;
+
+namespace {
+
+// Returns matcher for the opt in accept button.
+id<GREYMatcher> FirstRunOptInAcceptButton() {
+  return ButtonWithAccessibilityLabel(
+      l10n_util::GetNSString(IDS_IOS_FIRSTRUN_OPT_IN_ACCEPT_BUTTON));
+}
+
+// Returns matcher for the skip sign in button.
+id<GREYMatcher> SkipSigninButton() {
+  return grey_accessibilityID(kSkipSigninAccessibilityIdentifier);
+}
+}
+
+// Tests legacy first run settings and navigation.
+@interface LegacyFirstRunTestCase : ChromeTestCase
+@end
+
+@implementation LegacyFirstRunTestCase
+
+- (void)setUp {
+  [[self class] testForStartup];
+
+  [super setUp];
+  [FirstRunAppInterface setUMACollectionEnabled:NO];
+  [FirstRunAppInterface resetUMACollectionEnabledByDefault];
+}
+
+- (void)tearDown {
+  [super tearDown];
+  [FirstRunAppInterface setUMACollectionEnabled:NO];
+  [FirstRunAppInterface resetUMACollectionEnabledByDefault];
+}
+
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+  config.features_disabled.push_back(kLocationPermissionsPrompt);
+  config.features_disabled.push_back(kEnableFREUIModuleIOS);
+
+  // Show the First Run UI at startup.
+  config.additional_args.push_back("-FirstRunForceEnabled");
+  config.additional_args.push_back("true");
+
+  // Relaunch app at each test to rewind the startup state.
+  config.relaunch_policy = ForceRelaunchByKilling;
+
+  return config;
+}
+
+// Navigates to the terms of service and back.
+- (void)testTermsAndConditions {
+  id<GREYMatcher> termsOfServiceLink =
+      grey_accessibilityLabel(@"Terms of Service");
+  [[EarlGrey selectElementWithMatcher:termsOfServiceLink]
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                          IDS_IOS_FIRSTRUN_TERMS_TITLE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(
+                                   grey_accessibilityID(@"ic_arrow_back"),
+                                   grey_accessibilityTrait(
+                                       UIAccessibilityTraitButton),
+                                   nil)] performAction:grey_tap()];
+
+  // Ensure we went back to the First Run screen.
+  [[EarlGrey selectElementWithMatcher:termsOfServiceLink]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Ensure that we have completed First Runs.
+  // Accept the FRE.
+  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
+      performAction:grey_tap()];
+  // Dismiss sign-in.
+  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
+      performAction:grey_tap()];
+}
+
+// Toggle the UMA checkbox.
+- (void)testToggleMetricsOn {
+  id<GREYMatcher> metrics =
+      grey_accessibilityID(first_run::kUMAMetricsButtonAccessibilityIdentifier);
+  [[EarlGrey selectElementWithMatcher:metrics] performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
+      performAction:grey_tap()];
+
+  GREYAssertNotEqual([FirstRunAppInterface isUMACollectionEnabled],
+                     [FirstRunAppInterface isUMACollectionEnabledByDefault],
+                     @"Metrics reporting pref is incorrect.");
+
+  // Ensure that we have completed First Run, otherwise Earl Grey test crashes
+  // on check that the sign-in coordinator is no longer running.
+  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
+      performAction:grey_tap()];
+}
+
+// Dismisses the first run screens.
+- (void)testDismissFirstRun {
+  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
+      performAction:grey_tap()];
+
+  GREYAssertEqual([FirstRunAppInterface isUMACollectionEnabled],
+                  [FirstRunAppInterface isUMACollectionEnabledByDefault],
+                  @"Metrics reporting does not match.");
+
+  [[EarlGrey selectElementWithMatcher:SkipSigninButton()]
+      performAction:grey_tap()];
+
+  [[EarlGrey selectElementWithMatcher:FakeOmnibox()]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Signs in to an account and then taps the Advanced link to go to settings.
+- (void)testSignInAndTapSettingsLink {
+  FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1];
+  [SigninEarlGrey addFakeIdentity:fakeIdentity];
+
+  // Launch First Run and accept tems of services.
+  [[EarlGrey selectElementWithMatcher:FirstRunOptInAcceptButton()]
+      performAction:grey_tap()];
+
+  // Tap Settings link.
+  [SigninEarlGreyUI tapSettingsLink];
+
+  // Check Sync hasn't started yet, allowing the user to change some settings.
+  GREYAssertFalse([FirstRunAppInterface isSyncFirstSetupComplete],
+                  @"Sync shouldn't have finished its original setup yet");
+
+  // Close Settings, user is still signed in and sync is now starting.
+  [[EarlGrey selectElementWithMatcher:SyncSettingsConfirmButton()]
+      performAction:grey_tap()];
+
+  [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
+
+  GREYAssertTrue([FirstRunAppInterface isSyncFirstSetupComplete],
+                 @"Sync should have finished its original setup");
+}
+
+// Checks FRE shows in only one window.
+- (void)testFirstRunInMultiWindow {
+  if (![ChromeEarlGrey areMultipleWindowsSupported])
+    EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
+
+  [ChromeEarlGrey openNewWindow];
+  [ChromeEarlGrey waitForForegroundWindowCount:2];
+
+  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(
+                                          0, grey_accessibilityLabel(
+                                                 @"Terms of Service"))]
+      assertWithMatcher:grey_notNil()];
+
+  // Check UI Blocked in second window and that message is a button.
+  [[EarlGrey
+      selectElementWithMatcher:
+          MatchInBlockerWindowWithNumber(
+              1,
+              grey_text(l10n_util::GetNSString(
+                  IDS_IOS_UI_BLOCKED_USE_OTHER_WINDOW_SWITCH_WINDOW_ACTION)))]
+      assertWithMatcher:grey_allOf(
+                            grey_sufficientlyVisible(),
+                            grey_ancestor(grey_kindOfClassName(@"UIButton")),
+                            nil)];
+
+  // Finish FRE.
+  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(
+                                          0, FirstRunOptInAcceptButton())]
+      performAction:grey_tap()];
+  [[EarlGrey
+      selectElementWithMatcher:MatchInWindowWithNumber(0, SkipSigninButton())]
+      performAction:grey_tap()];
+
+  // Check for both fake omniboxes visibility.
+  [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(0, FakeOmnibox())]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // TODO(crbug.com/1169687) enable following test once EG2 bug for multiwindow
+  //    grey_sufficientlyVisible is fixed.
+  // [[EarlGrey selectElementWithMatcher:MatchInWindowWithNumber(1,
+  // FakeOmnibox())]
+  //  assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/first_run/signin/BUILD.gn b/ios/chrome/browser/ui/first_run/signin/BUILD.gn
index 892c8e4..41d7e81 100644
--- a/ios/chrome/browser/ui/first_run/signin/BUILD.gn
+++ b/ios/chrome/browser/ui/first_run/signin/BUILD.gn
@@ -47,6 +47,7 @@
     "//ios/chrome/browser/ui/authentication",
     "//ios/chrome/browser/ui/authentication/views",
     "//ios/chrome/browser/ui/elements:elements_internal",
+    "//ios/chrome/browser/ui/first_run:constants",
     "//ios/chrome/browser/ui/first_run:first_run_ui",
     "//ios/chrome/browser/ui/first_run/resources:signin_screen_banner",
     "//ios/chrome/common/ui/util",
diff --git a/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator.mm b/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator.mm
index 7d68bd66..12d45e3 100644
--- a/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator.mm
+++ b/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator.mm
@@ -114,7 +114,7 @@
 }
 
 - (ios::ChromeIdentityService*)identityService {
-  return ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+  return ios::GetChromeBrowserProvider().GetChromeIdentityService();
 }
 
 #pragma mark - ChromeBrowserProviderObserver
diff --git a/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator_unittest.mm b/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator_unittest.mm
index c6888f3..653f2bc 100644
--- a/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/first_run/signin/signin_screen_mediator_unittest.mm
@@ -66,7 +66,6 @@
  protected:
   void SetUp() override {
     PlatformTest::SetUp();
-    browser_provider_ = ios::TestChromeBrowserProvider::GetTestProvider();
     identity_service_ =
         ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
     browser_state_ = TestChromeBrowserState::Builder().Build();
@@ -97,12 +96,12 @@
 
     // Update the service in the browser provider.
     identity_service_ = service.get();
-    browser_provider_->SetChromeIdentityServiceForTesting(std::move(service));
+    ios::TestChromeBrowserProvider::GetTestProvider()
+        .SetChromeIdentityServiceForTesting(std::move(service));
   }
 
   web::WebTaskEnvironment task_environment_;
   SigninScreenMediator* mediator_;
-  ios::TestChromeBrowserProvider* browser_provider_;
   std::unique_ptr<ChromeBrowserState> browser_state_;
   ios::FakeChromeIdentityService* identity_service_;
   FakeSigninScreenConsumer* consumer_;
diff --git a/ios/chrome/browser/ui/first_run/signin/signin_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/signin/signin_screen_view_controller.mm
index abb31ecb..d66debe 100644
--- a/ios/chrome/browser/ui/first_run/signin/signin_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/signin/signin_screen_view_controller.mm
@@ -7,6 +7,7 @@
 #include "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/ui/authentication/views/identity_button_control.h"
 #import "ios/chrome/browser/ui/elements/activity_overlay_view.h"
+#import "ios/chrome/browser/ui/first_run/first_run_constants.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
 #include "ios/chrome/grit/ios_google_chrome_strings.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -41,6 +42,8 @@
 #pragma mark - Public
 
 - (void)viewDidLoad {
+  self.view.accessibilityIdentifier =
+      first_run::kFirstRunSignInScreenAccessibilityIdentifier;
   self.bannerImage = [UIImage imageNamed:@"signin_screen_banner"];
   self.isTallBanner = NO;
   self.scrollToEndMandatory = YES;
diff --git a/ios/chrome/browser/ui/first_run/sync/BUILD.gn b/ios/chrome/browser/ui/first_run/sync/BUILD.gn
index 2dc88231..be99fca1 100644
--- a/ios/chrome/browser/ui/first_run/sync/BUILD.gn
+++ b/ios/chrome/browser/ui/first_run/sync/BUILD.gn
@@ -37,6 +37,7 @@
   ]
   deps = [
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/ui/first_run:constants",
     "//ios/chrome/browser/ui/first_run:first_run_ui",
     "//ios/chrome/browser/ui/first_run/resources:sync_screen_banner",
     "//ios/chrome/common/ui/colors",
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
index 7d1963a..e98d48a 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_coordinator.mm
@@ -117,9 +117,10 @@
 - (void)didTapPrimaryActionButton {
   base::UmaHistogramEnumeration("FirstRun.Stage",
                                 first_run::kSyncScreenCompletionWithSync);
-  [self.mediator
-      startSyncWithConfirmationID:IDS_IOS_FIRST_RUN_SYNC_SCREEN_PRIMARY_ACTION
-                       consentIDs:self.consentStringIDs];
+  [self.mediator startSyncWithConfirmationID:
+                     IDS_IOS_FIRST_RUN_SYNC_SCREEN_PRIMARY_ACTION
+                                  consentIDs:self.consentStringIDs
+           advancedSyncSettingsLinkWasTapped:NO];
   [self.delegate willFinishPresenting];
 }
 
@@ -132,6 +133,10 @@
 - (void)showSyncSettings {
   base::UmaHistogramEnumeration(
       "FirstRun.Stage", first_run::kSyncScreenCompletionWithSyncSettings);
+  [self.mediator startSyncWithConfirmationID:
+                     IDS_IOS_FIRST_RUN_SYNC_SCREEN_ADVANCE_SETTINGS
+                                  consentIDs:self.consentStringIDs
+           advancedSyncSettingsLinkWasTapped:YES];
   [self.delegate skipAllAndShowSyncSettings];
 }
 
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.h b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.h
index fe1d4f0..16273e51 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.h
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.h
@@ -40,7 +40,8 @@
 // @param confirmationID: The confirmation string ID of sync.
 // @param consentIDs: The consent string IDs of sync screen.
 - (void)startSyncWithConfirmationID:(const int)confirmationID
-                         consentIDs:(NSArray<NSNumber*>*)consentIDs;
+                           consentIDs:(NSArray<NSNumber*>*)consentIDs
+    advancedSyncSettingsLinkWasTapped:(BOOL)advancedSyncSettingsLinkWasTapped;
 
 @end
 
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.mm
index 9ed1ab3..9329349 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator.mm
@@ -48,7 +48,8 @@
 }
 
 - (void)startSyncWithConfirmationID:(const int)confirmationID
-                         consentIDs:(NSArray<NSNumber*>*)consentIDs {
+                           consentIDs:(NSArray<NSNumber*>*)consentIDs
+    advancedSyncSettingsLinkWasTapped:(BOOL)advancedSyncSettingsLinkWasTapped {
   ChromeIdentity* identity =
       self.authenticationService->GetAuthenticatedIdentity();
   DCHECK(identity);
@@ -69,12 +70,14 @@
   self.consentAuditor->RecordSyncConsent(coreAccountId, syncConsent);
   self.authenticationService->GrantSyncConsent(identity);
 
-  // Turn on FirstSetupComplete flag after the authentication service has
-  // granted user consent to start Sync.
-  self.syncSetupService->SetFirstSetupComplete(
-      syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
+  if (!advancedSyncSettingsLinkWasTapped) {
+    // Turn on FirstSetupComplete flag after the authentication service has
+    // granted user consent to start Sync.
+    self.syncSetupService->SetFirstSetupComplete(
+        syncer::SyncFirstSetupCompleteSource::BASIC_FLOW);
 
-  self.syncSetupService->CommitSyncChanges();
+    self.syncSetupService->CommitSyncChanges();
+  }
 }
 
 @end
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator_unittest.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator_unittest.mm
index 195fc83f..e70240b5 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_mediator_unittest.mm
@@ -104,5 +104,7 @@
   EXPECT_CALL(
       *sync_setup_service_mock_,
       SetFirstSetupComplete(syncer::SyncFirstSetupCompleteSource::BASIC_FLOW));
-  [mediator_ startSyncWithConfirmationID:0 consentIDs:consentStringIDs];
+  [mediator_ startSyncWithConfirmationID:0
+                              consentIDs:consentStringIDs
+       advancedSyncSettingsLinkWasTapped:NO];
 }
diff --git a/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
index f8a5400..19c22dd 100644
--- a/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/first_run/sync/sync_screen_view_controller.h"
 
+#import "ios/chrome/browser/ui/first_run/first_run_constants.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -21,6 +22,8 @@
 @dynamic delegate;
 
 - (void)viewDidLoad {
+  self.view.accessibilityIdentifier =
+      first_run::kFirstRunSyncScreenAccessibilityIdentifier;
   self.titleText =
       [self contentTextWithStringID:IDS_IOS_FIRST_RUN_SYNC_SCREEN_TITLE];
   self.subtitleText =
diff --git a/ios/chrome/browser/ui/first_run/welcome/BUILD.gn b/ios/chrome/browser/ui/first_run/welcome/BUILD.gn
index dcba3a20..f1f7b21 100644
--- a/ios/chrome/browser/ui/first_run/welcome/BUILD.gn
+++ b/ios/chrome/browser/ui/first_run/welcome/BUILD.gn
@@ -47,6 +47,7 @@
     "//components/prefs",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
+    "//ios/chrome/browser/ui/first_run:constants",
     "//ios/chrome/browser/ui/first_run:first_run_ui",
     "//ios/chrome/browser/ui/first_run/resources:welcome_metrics_checkmark",
     "//ios/chrome/browser/ui/first_run/resources:welcome_screen_banner",
diff --git a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
index ff3a99b..88cbe48c 100644
--- a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.h"
 
 #import "components/policy/core/common/policy_loader_ios_constants.h"
+#import "ios/chrome/browser/ui/first_run/first_run_constants.h"
 #import "ios/chrome/browser/ui/first_run/welcome/checkbox_button.h"
 #import "ios/chrome/browser/ui/first_run/welcome/tos_commands.h"
 #import "ios/chrome/browser/ui/util/ui_util.h"
@@ -53,7 +54,8 @@
 
 - (void)viewDidLoad {
   [self configureLabels];
-
+  self.view.accessibilityIdentifier =
+      first_run::kFirstRunWelcomeScreenAccessibilityIdentifier;
   self.bannerImage = [UIImage imageNamed:@"welcome_screen_banner"];
   self.isTallBanner = YES;
   self.scrollToEndMandatory = YES;
diff --git a/ios/chrome/browser/ui/fullscreen/test/fullscreen_app_interface.mm b/ios/chrome/browser/ui/fullscreen/test/fullscreen_app_interface.mm
index e45d286..762a0b40 100644
--- a/ios/chrome/browser/ui/fullscreen/test/fullscreen_app_interface.mm
+++ b/ios/chrome/browser/ui/fullscreen/test/fullscreen_app_interface.mm
@@ -22,7 +22,7 @@
 
 + (BOOL)isFullscreenInitialized {
   return ios::GetChromeBrowserProvider()
-      ->GetFullscreenProvider()
+      .GetFullscreenProvider()
       ->IsInitialized();
 }
 
diff --git a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm
index 3f1868136..2b3e608 100644
--- a/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.mm
@@ -188,6 +188,15 @@
   [model addItem:self.expirationYearItem
       toSectionWithIdentifier:SectionIdentifierContent];
 
+  // The extra legal line and account info should only be shown together.
+  bool shouldShowExtraLegalLineAndAccountInfo =
+      [self.displayedTargetAccountEmail length] > 0 &&
+      self.displayedTargetAccountAvatar != nil;
+
+  // Concatenate legal lines and maybe add the extra one.
+  // TODO(crbug.com/1224680): In reality the server sends a single legal line.
+  // The extra text should be added directly to the server string instead of
+  // here (see b/192290070).
   NSMutableString* joinedMessage = [[NSMutableString alloc] init];
   BOOL shouldAddSpace = NO;
   for (SaveCardMessageWithLinks* message in self.legalMessages) {
@@ -196,21 +205,20 @@
     [joinedMessage appendString:message.messageText];
     shouldAddSpace = YES;
   }
-  if (base::FeatureList::IsEnabled(
-          autofill::features::kAutofillEnableAccountWalletStorage)) {
+  if (shouldShowExtraLegalLineAndAccountInfo) {
     if (shouldAddSpace)
       [joinedMessage appendString:@" "];
     [joinedMessage appendString:l10n_util::GetNSString(
                                     IDS_IOS_CARD_WILL_BE_SAVED_TO_ACCOUNT)];
   }
+
   TableViewTextLinkItem* legalMessageItem =
       [[TableViewTextLinkItem alloc] initWithType:ItemTypeCardLegalMessage];
   legalMessageItem.text = joinedMessage;
   [model addItem:legalMessageItem
       toSectionWithIdentifier:SectionIdentifierContent];
 
-  if ([self.displayedTargetAccountEmail length] &&
-      self.displayedTargetAccountAvatar != nil) {
+  if (shouldShowExtraLegalLineAndAccountInfo) {
     TargetAccountItem* targetTargetAccountItem =
         [[TargetAccountItem alloc] initWithType:ItemTypeTargetAccount];
     targetTargetAccountItem.email = self.displayedTargetAccountEmail;
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
index c061aab..a9723f1 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -154,7 +154,7 @@
                      ApplicationCommands, LoadQueryCommands, OmniboxCommands>>(
           self.browser->GetCommandDispatcher());
   self.viewController.voiceSearchEnabled = ios::GetChromeBrowserProvider()
-                                               ->GetVoiceSearchProvider()
+                                               .GetVoiceSearchProvider()
                                                ->IsVoiceSearchEnabled();
 
   _editController = std::make_unique<WebOmniboxEditControllerImpl>(self);
diff --git a/ios/chrome/browser/ui/main/reading_list_background_session_scene_agent.mm b/ios/chrome/browser/ui/main/reading_list_background_session_scene_agent.mm
index 69d02a1..d2ec415 100644
--- a/ios/chrome/browser/ui/main/reading_list_background_session_scene_agent.mm
+++ b/ios/chrome/browser/ui/main/reading_list_background_session_scene_agent.mm
@@ -33,19 +33,18 @@
   if (!IsReadingListMessagesEnabled()) {
     return;
   }
+  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
   if (level <= SceneActivationLevelBackground) {
     // If the ApplicationState is not active, then that means no other scenes
     // are in the foreground, meaning the app is completely backgrounded.
     if (UIApplication.sharedApplication.applicationState !=
         UIApplicationStateActive) {
       // Save the time when the app is backgrounded.
-      [[NSUserDefaults standardUserDefaults]
-          setObject:[NSDate date]
-             forKey:kReadingListLastBackgroundTime];
+      [defaults setObject:[NSDate date] forKey:kReadingListLastBackgroundTime];
     }
   } else if (level == SceneActivationLevelForegroundInactive) {
-    NSDate* last_background_timestamp = [[NSUserDefaults standardUserDefaults]
-        objectForKey:kReadingListLastBackgroundTime];
+    NSDate* last_background_timestamp =
+        [defaults objectForKey:kReadingListLastBackgroundTime];
     if (!last_background_timestamp) {
       // There may not be a saved time if the app crashes. It's ok that
       // kLastTimeUserShownReadingListMessages is not reset in this situation.
@@ -57,11 +56,19 @@
         NSOrderedAscending) {
       // Reset the last Messages prompt timestamp when it is the start of a new
       // "session".
-      [[NSUserDefaults standardUserDefaults]
-          removeObjectForKey:kLastTimeUserShownReadingListMessages];
+      [defaults removeObjectForKey:kLastTimeUserShownReadingListMessages];
+      if ([defaults boolForKey:kLastReadingListEntryAddedFromMessages]) {
+        // If there was a Reading List entry added in the last session, set
+        // flags to allow for Reading List unread count badges to animate.
+        [defaults removeObjectForKey:kLastReadingListEntryAddedFromMessages];
+        [defaults setBool:YES
+                   forKey:kShouldAnimateReadingListNTPUnreadCountBadge];
+        [defaults
+            setBool:YES
+             forKey:kShouldAnimateReadingListOverflowMenuUnreadCountBadge];
+      }
     }
-    [[NSUserDefaults standardUserDefaults]
-        removeObjectForKey:kReadingListLastBackgroundTime];
+    [defaults removeObjectForKey:kReadingListLastBackgroundTime];
   }
 }
 
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index 96ca551..8373fb4 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -431,22 +431,22 @@
       // Only one can be triggered.
       activityWithCompletion = activity;
     }
-    if (activityWithCompletion) {
-      // This function is called when the scene is activated (or unblocked).
-      // Consider the scene as still not active at this point as the handling
-      // of startup parameters is not yet done (and will be later in this
-      // function).
-      [UserActivityHandler
-           continueUserActivity:activityWithCompletion
-            applicationIsActive:NO
-                      tabOpener:self
-          connectionInformation:self
-             startupInformation:self.sceneState.appState.startupInformation
-                   browserState:self.currentInterface.browserState
-                      initStage:self.sceneState.appState.initStage];
-    }
-    self.sceneState.connectionOptions = nil;
   }
+  if (activityWithCompletion) {
+    // This function is called when the scene is activated (or unblocked).
+    // Consider the scene as still not active at this point as the handling
+    // of startup parameters is not yet done (and will be later in this
+    // function).
+    [UserActivityHandler
+         continueUserActivity:activityWithCompletion
+          applicationIsActive:NO
+                    tabOpener:self
+        connectionInformation:self
+           startupInformation:self.sceneState.appState.startupInformation
+                 browserState:self.currentInterface.browserState
+                    initStage:self.sceneState.appState.initStage];
+  }
+  self.sceneState.connectionOptions = nil;
 
   if (self.startupParameters) {
     if ([self isIncognitoForced]) {
@@ -776,7 +776,7 @@
 
   __weak SceneController* weakSelf = self;
   ios::ChromeIdentityService* identityService =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
 
   // Asynchronously checks whether the default identity can display extended
   // sync promos and displays the sign-in promo if possible.
@@ -2272,16 +2272,16 @@
   // Immediately hide modals from the provider (alert views, action sheets,
   // popovers). They will be ultimately dismissed by their owners, but at least,
   // they are not visible.
-  ios::GetChromeBrowserProvider()->HideModalViewStack();
+  ios::GetChromeBrowserProvider().HideModalViewStack();
 
   // ChromeIdentityService is responsible for the dialogs displayed by the
   // services it wraps.
-  ios::GetChromeBrowserProvider()->GetChromeIdentityService()->DismissDialogs();
+  ios::GetChromeBrowserProvider().GetChromeIdentityService()->DismissDialogs();
 
   // MailtoHandlerProvider is responsible for the dialogs displayed by the
   // services it wraps.
   ios::GetChromeBrowserProvider()
-      ->GetMailtoHandlerProvider()
+      .GetMailtoHandlerProvider()
       ->DismissAllMailtoHandlerInterfaces();
 
   // Then, depending on what the SSO view controller is presented on, dismiss
@@ -2325,7 +2325,7 @@
   }
 
   // Verify that no modal views are left presented.
-  ios::GetChromeBrowserProvider()->LogIfModalViewsArePresented();
+  ios::GetChromeBrowserProvider().LogIfModalViewsArePresented();
 }
 
 - (void)openMultipleTabsInMode:
@@ -2885,7 +2885,7 @@
         [[URLOpenerParams alloc] initWithUIOpenURLContext:context];
     NSSet* URLContextSet = [NSSet setWithObject:context];
     if (!ios::GetChromeBrowserProvider()
-             ->GetChromeIdentityService()
+             .GetChromeIdentityService()
              ->HandleSessionOpenURLContexts(self.sceneState.scene,
                                             URLContextSet)) {
       [URLsToOpen addObject:options];
diff --git a/ios/chrome/browser/ui/ntp/metrics.h b/ios/chrome/browser/ui/ntp/metrics.h
index f6e4b2e..6af16dfa 100644
--- a/ios/chrome/browser/ui/ntp/metrics.h
+++ b/ios/chrome/browser/ui/ntp/metrics.h
@@ -5,7 +5,6 @@
 #ifndef IOS_CHROME_BROWSER_UI_NTP_METRICS_H_
 #define IOS_CHROME_BROWSER_UI_NTP_METRICS_H_
 
-#include "base/time/time.h"
 #include "components/ntp_tiles/tile_source.h"
 #include "components/ntp_tiles/tile_title_source.h"
 #import "ios/chrome/common/ui/favicon/favicon_attributes.h"
@@ -15,14 +14,12 @@
                              ntp_tiles::TileSource source,
                              ntp_tiles::TileTitleSource title_source,
                              const FaviconAttributes* attributes,
-                             base::Time data_generation_time,
                              const GURL& url);
 
 void RecordNTPTileClick(int index,
                         ntp_tiles::TileSource source,
                         ntp_tiles::TileTitleSource title_source,
                         const FaviconAttributes* attributes,
-                        base::Time data_generation_time,
                         const GURL& url);
 
 #endif  // IOS_CHROME_BROWSER_UI_NTP_METRICS_H_
diff --git a/ios/chrome/browser/ui/ntp/metrics.mm b/ios/chrome/browser/ui/ntp/metrics.mm
index 3b5b7bc..a966995 100644
--- a/ios/chrome/browser/ui/ntp/metrics.mm
+++ b/ios/chrome/browser/ui/ntp/metrics.mm
@@ -43,20 +43,18 @@
                              ntp_tiles::TileSource source,
                              ntp_tiles::TileTitleSource title_source,
                              const FaviconAttributes* attributes,
-                             base::Time data_generation_time,
                              const GURL& url) {
   ntp_tiles::metrics::RecordTileImpression(ntp_tiles::NTPTileImpression(
       index, source, title_source, VisualTypeFromAttributes(attributes),
-      IconTypeFromAttributes(attributes), data_generation_time, url));
+      IconTypeFromAttributes(attributes), url));
 }
 
 void RecordNTPTileClick(int index,
                         ntp_tiles::TileSource source,
                         ntp_tiles::TileTitleSource title_source,
                         const FaviconAttributes* attributes,
-                        base::Time data_generation_time,
                         const GURL& url) {
   ntp_tiles::metrics::RecordTileClick(ntp_tiles::NTPTileImpression(
       index, source, title_source, VisualTypeFromAttributes(attributes),
-      IconTypeFromAttributes(attributes), data_generation_time, url));
+      IconTypeFromAttributes(attributes), url));
 }
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 985e433f..e3c1fb9 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -31,6 +31,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.h"
 #import "ios/chrome/browser/ui/content_suggestions/discover_feed_metrics_recorder.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h"
 #import "ios/chrome/browser/ui/main/scene_state.h"
@@ -197,7 +198,7 @@
                                   self.browser->GetBrowserState())
               identityManager:IdentityManagerFactory::GetForBrowserState(
                                   self.browser->GetBrowserState())
-                   logoVendor:ios::GetChromeBrowserProvider()->CreateLogoVendor(
+                   logoVendor:ios::GetChromeBrowserProvider().CreateLogoVendor(
                                   self.browser, self.webState)
       voiceSearchAvailability:&_voiceSearchAvailability];
   self.ntpMediator.browser = self.browser;
@@ -215,16 +216,23 @@
   self.contentSuggestionsCoordinator.bubblePresenter = self.bubblePresenter;
 
   DiscoverFeedMetricsRecorder* discoverFeedMetricsRecorder;
+  ContentSuggestionsMetricsRecorder* contentSuggestionsMetricsRecorder;
+
+  DiscoverFeedService* discoverFeedService =
+      DiscoverFeedServiceFactory::GetForBrowserState(
+          self.browser->GetBrowserState());
 
   if (IsDiscoverFeedEnabled()) {
-    // Creating the DiscoverFeedService will start the DiscoverFeed.
-    DiscoverFeedService* discoverFeedService =
-        DiscoverFeedServiceFactory::GetForBrowserState(
-            self.browser->GetBrowserState());
     discoverFeedMetricsRecorder =
         discoverFeedService->GetDiscoverFeedMetricsRecorder();
     self.contentSuggestionsCoordinator.discoverFeedMetricsRecorder =
         discoverFeedMetricsRecorder;
+  } else {
+    // TODO(crbug.com/1200303): Remove this when we launch the Discover feed.
+    contentSuggestionsMetricsRecorder =
+        discoverFeedService->GetContentSuggestionsMetricsRecorder();
+    self.contentSuggestionsCoordinator.contentSuggestionsMetricsRecorder =
+        contentSuggestionsMetricsRecorder;
   }
 
   // Requests a Discover feed here if the correct flags and prefs are enabled.
@@ -232,7 +240,7 @@
     self.ntpViewController = [[NewTabPageViewController alloc] init];
     self.discoverFeedViewController =
         ios::GetChromeBrowserProvider()
-            ->GetDiscoverFeedProvider()
+            .GetDiscoverFeedProvider()
             ->NewFeedViewControllerWithScrollDelegate(self.browser,
                                                       self.ntpViewController);
   }
@@ -278,7 +286,7 @@
   self.ntpViewController = nil;
   if (IsRefactoredNTP()) {
     ios::GetChromeBrowserProvider()
-        ->GetDiscoverFeedProvider()
+        .GetDiscoverFeedProvider()
         ->RemoveFeedViewController(self.discoverFeedViewController);
   }
   self.discoverFeedWrapperViewController = nil;
@@ -426,7 +434,7 @@
 
 - (void)reload {
   if (self.discoverFeedViewController) {
-    ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider()->RefreshFeed();
+    ios::GetChromeBrowserProvider().GetDiscoverFeedProvider()->RefreshFeed();
   }
   [self reloadContentSuggestions];
 }
diff --git a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
index 8d75a7ce..830651f 100644
--- a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
+++ b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
@@ -9,12 +9,12 @@
 #include <memory>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/ios/ios_util.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
diff --git a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
index 86b7eeb..6be72dc 100644
--- a/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
+++ b/ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_delegate.mm
@@ -28,7 +28,7 @@
 
 - (void)keyboardAccessoryVoiceSearchTouchUpInside:(UIView*)view {
   if (ios::GetChromeBrowserProvider()
-          ->GetVoiceSearchProvider()
+          .GetVoiceSearchProvider()
           ->IsVoiceSearchEnabled()) {
     [self.dispatcher preloadVoiceSearch];
     base::RecordAction(base::UserMetricsAction("MobileCustomRowVoiceSearch"));
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm b/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm
index e7f0011..b4da48c5 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm
@@ -190,7 +190,7 @@
                              self.templateURLService->search_terms_data()) ==
                              SEARCH_ENGINE_GOOGLE) {
     UIImage* bundledLogo = ios::GetChromeBrowserProvider()
-                               ->GetBrandedImageProvider()
+                               .GetBrandedImageProvider()
                                ->GetOmniboxAnswerIcon();
 
     if (bundledLogo) {
diff --git a/ios/chrome/browser/ui/omnibox/popup/simple_omnibox_icon.mm b/ios/chrome/browser/ui/omnibox/popup/simple_omnibox_icon.mm
index 5c29023..fff3483d 100644
--- a/ios/chrome/browser/ui/omnibox/popup/simple_omnibox_icon.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/simple_omnibox_icon.mm
@@ -90,7 +90,7 @@
 
 - (UIImage*)fallbackAnswerBrandedIcon {
   return ios::GetChromeBrowserProvider()
-      ->GetBrandedImageProvider()
+      .GetBrandedImageProvider()
       ->GetOmniboxAnswerIcon();
 }
 
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/translate/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_modal/translate/BUILD.gn
index ab1a2f8..804bdf9 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/translate/BUILD.gn
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/translate/BUILD.gn
@@ -45,6 +45,7 @@
     ":translate",
     "//base/test:test_support",
     "//components/infobars/core",
+    "//components/translate/core/browser:browser",
     "//components/translate/core/browser:test_support",
     "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/infobars/test",
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator.mm
index 72a7ff5a..fc0ccf62 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator.mm
@@ -66,9 +66,14 @@
   self.newSourceLanguageIndex = kInvalidLanguageIndex;
   self.newTargetLanguageIndex = kInvalidLanguageIndex;
 
-  BOOL currentStepBeforeTranslate =
+  // The Translate button should be enabled whenever the page is untranslated,
+  // which may be before any translation has been triggered or after an error
+  // caused translation to fail.
+  BOOL currentStepUntranslated =
       self.config->current_step() ==
-      translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE;
+          translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE ||
+      self.config->current_step() ==
+          translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR;
 
   [self.consumer
       setupModalViewControllerWithPrefs:
@@ -79,8 +84,7 @@
                                          base::SysUTF16ToNSString(
                                              self.config
                                                  ->target_language_name())
-                             translateButtonEnabled:
-                                 currentStepBeforeTranslate]];
+                             translateButtonEnabled:currentStepUntranslated]];
 }
 
 - (void)setSourceLanguageSelectionConsumer:
@@ -361,9 +365,13 @@
                                         targetLanguage:(NSString*)targetLanguage
                                 translateButtonEnabled:
                                     (BOOL)translateButtonEnabled {
-  BOOL currentStepBeforeTranslate =
+  // Modal state following a translate error should be the same as on an
+  // untranslated page.
+  BOOL currentStepUntranslated =
       self.config->current_step() ==
-      translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE;
+          translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE ||
+      self.config->current_step() ==
+          translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR;
   BOOL currentStepAfterTranslate =
       self.config->current_step() ==
       translate::TranslateStep::TRANSLATE_STEP_AFTER_TRANSLATE;
@@ -379,8 +387,8 @@
     kEnableAndDisplayShowOriginalButtonPrefKey : @(currentStepAfterTranslate),
     kShouldAlwaysTranslatePrefKey :
         @(self.config->is_always_translate_enabled()),
-    kDisplayNeverTranslateLanguagePrefKey : @(currentStepBeforeTranslate),
-    kDisplayNeverTranslateSiteButtonPrefKey : @(currentStepBeforeTranslate),
+    kDisplayNeverTranslateLanguagePrefKey : @(currentStepUntranslated),
+    kDisplayNeverTranslateSiteButtonPrefKey : @(currentStepUntranslated),
     kIsTranslatableLanguagePrefKey : @(self.config->is_translatable_language()),
     kIsSiteOnNeverPromptListPrefKey :
         @(self.config->is_site_on_never_prompt_list()),
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator_unittest.mm
index 5f956548..1ecc4ff 100644
--- a/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_modal/translate/translate_infobar_modal_overlay_mediator_unittest.mm
@@ -6,6 +6,7 @@
 
 #include "base/ios/ios_util.h"
 #include "base/strings/sys_string_conversions.h"
+#include "components/translate/core/browser/translate_step.h"
 #include "ios/chrome/browser/infobars/infobar_ios.h"
 #import "ios/chrome/browser/overlays/public/infobar_modal/infobar_modal_overlay_responses.h"
 #import "ios/chrome/browser/overlays/public/infobar_modal/translate_infobar_modal_overlay_request_config.h"
@@ -36,13 +37,20 @@
 using translate_infobar_modal_responses::UpdateLanguageInfo;
 using translate_infobar_modal_responses::UpdateLanguageInfo;
 
-// Test fixture for TranslateInfobarModalOverlayMediator.
+// Base test fixture for TranslateInfobarModalOverlayMediator. The state of the
+// mediator's consumer is expected to vary based on the current TranslateStep.
+// Derived test fixtures are used to verify this behaviour.
 class TranslateInfobarModalOverlayMediatorTest : public PlatformTest {
  public:
-  TranslateInfobarModalOverlayMediatorTest()
+  TranslateInfobarModalOverlayMediatorTest(
+      translate::TranslateStep step,
+      translate::TranslateErrors::Type error_type)
       : infobar_(
             [[FakeInfobarUIDelegate alloc] init],
-            delegate_factory_.CreateFakeTranslateInfoBarDelegate("fr", "en")),
+            delegate_factory_.CreateFakeTranslateInfoBarDelegate("fr",
+                                                                 "en",
+                                                                 step,
+                                                                 error_type)),
         callback_installer_(
             &callback_receiver_,
             {InfobarModalMainActionResponse::ResponseSupport(),
@@ -60,6 +68,13 @@
     mediator_.delegate = delegate_;
   }
 
+  // Default constructor using TRANSLATE_STEP_BEFORE_TRANSLATE as the
+  // translate step.
+  TranslateInfobarModalOverlayMediatorTest()
+      : TranslateInfobarModalOverlayMediatorTest(
+            translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE,
+            translate::TranslateErrors::Type::NONE) {}
+
   ~TranslateInfobarModalOverlayMediatorTest() override {
     EXPECT_CALL(callback_receiver_, CompletionCallback(request_.get()));
     EXPECT_OCMOCK_VERIFY(delegate_);
@@ -80,7 +95,7 @@
 };
 
 // Tests that a TranslateInfobarModalOverlayMediator correctly sets up its
-// consumer.
+// consumer while in a "before translate" step.
 TEST_F(TranslateInfobarModalOverlayMediatorTest, SetUpConsumer) {
   FakeInfobarTranslateModalConsumer* consumer =
       [[FakeInfobarTranslateModalConsumer alloc] init];
@@ -184,3 +199,68 @@
   OCMExpect([delegate_ stopOverlayForMediator:mediator_]);
   [mediator_ neverTranslateSite];
 }
+
+// Test fixture for TranslateInfobarModalOverlayMediator using the
+// TRANSLATE_STEP_AFTER_TRANSLATE translate step.
+class TranslateInfobarModalOverlayMediatorAfterTranslateTest
+    : public TranslateInfobarModalOverlayMediatorTest {
+ public:
+  TranslateInfobarModalOverlayMediatorAfterTranslateTest()
+      : TranslateInfobarModalOverlayMediatorTest(
+            translate::TranslateStep::TRANSLATE_STEP_AFTER_TRANSLATE,
+            translate::TranslateErrors::Type::NONE) {}
+};
+
+// Tests that a TranslateInfobarModalOverlayMediator correctly sets up its
+// consumer while in an "after translate" step.
+TEST_F(TranslateInfobarModalOverlayMediatorAfterTranslateTest, SetUpConsumer) {
+  FakeInfobarTranslateModalConsumer* consumer =
+      [[FakeInfobarTranslateModalConsumer alloc] init];
+  mediator_.consumer = consumer;
+
+  EXPECT_NSEQ(base::SysUTF16ToNSString(delegate().source_language_name()),
+              consumer.sourceLanguage);
+  EXPECT_NSEQ(base::SysUTF16ToNSString(delegate().target_language_name()),
+              consumer.targetLanguage);
+  EXPECT_FALSE(consumer.enableTranslateActionButton);
+  EXPECT_FALSE(consumer.updateLanguageBeforeTranslate);
+  EXPECT_TRUE(consumer.displayShowOriginalButton);
+  EXPECT_FALSE(consumer.shouldAlwaysTranslate);
+  EXPECT_FALSE(consumer.shouldDisplayNeverTranslateLanguageButton);
+  EXPECT_TRUE(consumer.isTranslatableLanguage);
+  EXPECT_FALSE(consumer.shouldDisplayNeverTranslateSiteButton);
+  EXPECT_FALSE(consumer.isSiteOnNeverPromptList);
+}
+
+// Test fixture for TranslateInfobarModalOverlayMediator using the
+// TRANSLATE_STEP_TRANSLATE_ERROR translate step.
+class TranslateInfobarModalOverlayMediatorTranslateErrorTest
+    : public TranslateInfobarModalOverlayMediatorTest {
+ public:
+  TranslateInfobarModalOverlayMediatorTranslateErrorTest()
+      : TranslateInfobarModalOverlayMediatorTest(
+            translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR,
+            translate::TranslateErrors::Type::TRANSLATION_ERROR) {}
+};
+
+// Tests that a TranslateInfobarModalOverlayMediator correctly sets up its
+// consumer while in a "translate error" step. This is expected to behave the
+// same as in the "before translate" step.
+TEST_F(TranslateInfobarModalOverlayMediatorTranslateErrorTest, SetUpConsumer) {
+  FakeInfobarTranslateModalConsumer* consumer =
+      [[FakeInfobarTranslateModalConsumer alloc] init];
+  mediator_.consumer = consumer;
+
+  EXPECT_NSEQ(base::SysUTF16ToNSString(delegate().source_language_name()),
+              consumer.sourceLanguage);
+  EXPECT_NSEQ(base::SysUTF16ToNSString(delegate().target_language_name()),
+              consumer.targetLanguage);
+  EXPECT_TRUE(consumer.enableTranslateActionButton);
+  EXPECT_FALSE(consumer.updateLanguageBeforeTranslate);
+  EXPECT_FALSE(consumer.displayShowOriginalButton);
+  EXPECT_FALSE(consumer.shouldAlwaysTranslate);
+  EXPECT_TRUE(consumer.shouldDisplayNeverTranslateLanguageButton);
+  EXPECT_TRUE(consumer.isTranslatableLanguage);
+  EXPECT_TRUE(consumer.shouldDisplayNeverTranslateSiteButton);
+  EXPECT_FALSE(consumer.isSiteOnNeverPromptList);
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h
index 8925446c..fae7014 100644
--- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h
+++ b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h
@@ -41,6 +41,9 @@
 // Title label for the cell.
 @property(nonatomic, strong, readonly) UILabel* titleLabel;
 
+// Badge displaying a number.
+@property(nonatomic, strong, readonly) UIView* numberBadgeView;
+
 // Whether the cell is associated with a destructive action. If |YES|, then a
 // specific styling is applied.
 @property(nonatomic, assign) BOOL destructiveAction;
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
index 13795d6..fead73d 100644
--- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
+++ b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
@@ -84,8 +84,8 @@
 @property(nonatomic, strong, readwrite) UILabel* titleLabel;
 // Image view for the cell, redefined as readwrite.
 @property(nonatomic, strong, readwrite) UIImageView* imageView;
-// Badge displaying a number.
-@property(nonatomic, strong) NumberBadgeView* numberBadgeView;
+// Internal implementation of |numberBadgeView|.
+@property(nonatomic, strong) NumberBadgeView* numberBadgeViewImpl;
 // Badge displaying text.
 @property(nonatomic, strong) TextBadgeView* textBadgeView;
 // Constraints between the trailing of the label and the badges.
@@ -129,8 +129,8 @@
     _imageView = [[UIImageView alloc] init];
     _imageView.translatesAutoresizingMaskIntoConstraints = NO;
 
-    _numberBadgeView = [[NumberBadgeView alloc] init];
-    _numberBadgeView.translatesAutoresizingMaskIntoConstraints = NO;
+    _numberBadgeViewImpl = [[NumberBadgeView alloc] init];
+    _numberBadgeViewImpl.translatesAutoresizingMaskIntoConstraints = NO;
 
     _textBadgeView = [[TextBadgeView alloc] initWithText:nil];
     _textBadgeView.translatesAutoresizingMaskIntoConstraints = NO;
@@ -140,7 +140,7 @@
 
     [self.contentView addSubview:_titleLabel];
     [self.contentView addSubview:_imageView];
-    [self.contentView addSubview:_numberBadgeView];
+    [self.contentView addSubview:_numberBadgeViewImpl];
     [self.contentView addSubview:_textBadgeView];
 
     [NSLayoutConstraint activateConstraints:@[
@@ -151,7 +151,7 @@
       [_imageView.centerYAnchor
           constraintEqualToAnchor:_titleLabel.firstBaselineAnchor
                          constant:-[self titleFont].capHeight / 2.0],
-      [_numberBadgeView.centerYAnchor
+      [_numberBadgeViewImpl.centerYAnchor
           constraintEqualToAnchor:_imageView.centerYAnchor],
       [_textBadgeView.centerYAnchor
           constraintEqualToAnchor:_imageView.centerYAnchor],
@@ -167,7 +167,7 @@
         @{
           @"image" : _imageView,
           @"label" : _titleLabel,
-          @"numberBadge" : _numberBadgeView,
+          @"numberBadge" : _numberBadgeViewImpl,
           @"textBadge" : _textBadgeView
         },
         @{
@@ -195,27 +195,31 @@
   return self;
 }
 
+- (UIView*)numberBadgeView {
+  return _numberBadgeViewImpl;
+}
+
 - (void)setBadgeNumber:(NSInteger)badgeNumber {
-  BOOL wasHidden = self.numberBadgeView.hidden;
-  [self.numberBadgeView setNumber:badgeNumber animated:NO];
+  BOOL wasHidden = self.numberBadgeViewImpl.hidden;
+  [self.numberBadgeViewImpl setNumber:badgeNumber animated:NO];
   // If the number badge is shown, then the text badge must be hidden.
-  if (!self.numberBadgeView.hidden && !self.textBadgeView.hidden) {
+  if (!self.numberBadgeViewImpl.hidden && !self.textBadgeView.hidden) {
     [self setBadgeText:nil];
   }
-  if (!self.numberBadgeView.hidden && wasHidden) {
+  if (!self.numberBadgeViewImpl.hidden && wasHidden) {
     self.titleToBadgeConstraint.active = NO;
-    self.titleToBadgeConstraint = [self.numberBadgeView.leadingAnchor
+    self.titleToBadgeConstraint = [self.numberBadgeViewImpl.leadingAnchor
         constraintGreaterThanOrEqualToAnchor:self.titleLabel.trailingAnchor
                                     constant:kInnerMargin];
     self.titleToBadgeConstraint.active = YES;
-  } else if (self.numberBadgeView.hidden && !wasHidden) {
+  } else if (self.numberBadgeViewImpl.hidden && !wasHidden) {
     self.titleToBadgeConstraint.active = NO;
   }
 }
 
 - (void)setBadgeText:(NSString*)badgeText {
   // Only 1 badge can be visible at a time, and the number badge takes priority.
-  if (badgeText && !self.numberBadgeView.isHidden) {
+  if (badgeText && !self.numberBadgeViewImpl.isHidden) {
     return;
   }
 
@@ -270,8 +274,8 @@
   CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
 
   CGFloat trailingMargin = kMargin;
-  if (!self.numberBadgeView.hidden) {
-    trailingMargin += self.numberBadgeView.bounds.size.width + kInnerMargin;
+  if (!self.numberBadgeViewImpl.hidden) {
+    trailingMargin += self.numberBadgeViewImpl.bounds.size.width + kInnerMargin;
   } else if (!self.textBadgeView.hidden) {
     trailingMargin += self.textBadgeView.bounds.size.width + kInnerMargin;
   }
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
index 7aeceea..87be6b9c 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -1014,7 +1014,7 @@
 
   // Text Zoom
   if (ios::GetChromeBrowserProvider()
-          ->GetTextZoomProvider()
+          .GetTextZoomProvider()
           ->IsTextZoomEnabled()) {
     self.textZoomItem = CreateTableViewItem(
         IDS_IOS_TOOLS_MENU_TEXT_ZOOM, PopupMenuActionTextZoom,
@@ -1047,7 +1047,7 @@
 
   // Report an Issue.
   if (ios::GetChromeBrowserProvider()
-          ->GetUserFeedbackProvider()
+          .GetUserFeedbackProvider()
           ->IsUserFeedbackEnabled()) {
     TableViewItem* reportIssue = CreateTableViewItem(
         IDS_IOS_OPTIONS_REPORT_AN_ISSUE, PopupMenuActionReportIssue,
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
index ba02c134..2826eac0 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator_unittest.mm
@@ -302,13 +302,13 @@
                  /*trigger_incognito_hint=*/NO);
   NSUInteger number_of_action_items = 7;
   if (ios::GetChromeBrowserProvider()
-          ->GetUserFeedbackProvider()
+          .GetUserFeedbackProvider()
           ->IsUserFeedbackEnabled()) {
     number_of_action_items++;
   }
 
   if (ios::GetChromeBrowserProvider()
-          ->GetTextZoomProvider()
+          .GetTextZoomProvider()
           ->IsTextZoomEnabled()) {
     number_of_action_items++;
   }
diff --git a/ios/chrome/browser/ui/popup_menu/public/BUILD.gn b/ios/chrome/browser/ui/popup_menu/public/BUILD.gn
index 49a67df5..2cc323d 100644
--- a/ios/chrome/browser/ui/popup_menu/public/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/public/BUILD.gn
@@ -32,9 +32,12 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/image_util",
+    "//ios/chrome/browser/ui/popup_menu/cells",
     "//ios/chrome/browser/ui/popup_menu/public/",
     "//ios/chrome/browser/ui/popup_menu/public/cells",
     "//ios/chrome/browser/ui/presenters",
+    "//ios/chrome/browser/ui/reading_list:features",
+    "//ios/chrome/browser/ui/reading_list:reading_list_constants",
     "//ios/chrome/browser/ui/resources:menu_shadow",
     "//ios/chrome/browser/ui/table_view",
     "//ios/chrome/browser/ui/table_view:styler",
diff --git a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm
index 40713ed..5243e51 100644
--- a/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm
+++ b/ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.mm
@@ -5,12 +5,16 @@
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller.h"
 
 #include "base/ios/ios_util.h"
+#include "base/mac/foundation_util.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
+#import "ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.h"
 #import "ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_footer_item.h"
 #import "ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller_delegate.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_constants.h"
+#import "ios/chrome/browser/ui/reading_list/reading_list_constants.h"
+#import "ios/chrome/browser/ui/reading_list/reading_list_features.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #import "ios/chrome/browser/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
@@ -191,6 +195,51 @@
 #pragma mark - UITableViewDelegate
 
 - (void)tableView:(UITableView*)tableView
+      willDisplayCell:(UITableViewCell*)cell
+    forRowAtIndexPath:(NSIndexPath*)indexPath {
+  TableViewItem<PopupMenuItem>* item =
+      [self.tableViewModel itemAtIndexPath:indexPath];
+  PopupMenuToolsItem* popupToolsItem =
+      base::mac::ObjCCast<PopupMenuToolsItem>(item);
+  // Only consider doing animation if the Reading List badge is visible.
+  if (item.actionIdentifier != PopupMenuActionReadingList ||
+      popupToolsItem.badgeNumber == 0) {
+    return;
+  }
+  // Show display animation of Reading List Unread Badge if the Reading List
+  // Messages experiment is enabled and a page was added by the Messages
+  // recently.
+  BOOL shouldShowUnreadBadgeAnimation =
+      IsReadingListMessagesEnabled() &&
+      [[NSUserDefaults standardUserDefaults]
+          boolForKey:kShouldAnimateReadingListOverflowMenuUnreadCountBadge];
+  if (shouldShowUnreadBadgeAnimation) {
+    PopupMenuToolsCell* readingListCell =
+        base::mac::ObjCCast<PopupMenuToolsCell>(cell);
+    readingListCell.numberBadgeView.alpha = 0;
+    readingListCell.numberBadgeView.transform =
+        CGAffineTransformMakeScale(0.1, 0.1);
+    __weak PopupMenuToolsCell* weakCell = readingListCell;
+    [UIView animateWithDuration:kReadingListUnreadCountBadgeAnimationDuration
+        delay:0.1
+        options:UIViewAnimationOptionBeginFromCurrentState
+        animations:^{
+          if (weakCell) {
+            weakCell.numberBadgeView.transform = CGAffineTransformIdentity;
+            weakCell.numberBadgeView.alpha = 1;
+          }
+        }
+        completion:^(BOOL finished) {
+          if (finished) {
+            [[NSUserDefaults standardUserDefaults]
+                setBool:NO
+                 forKey:kShouldAnimateReadingListOverflowMenuUnreadCountBadge];
+          }
+        }];
+  }
+}
+
+- (void)tableView:(UITableView*)tableView
     didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
   UIView* cell = [self.tableView cellForRowAtIndexPath:indexPath];
   CGPoint center = [cell convertPoint:cell.center toView:nil];
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn
index 12ba686..b325381 100644
--- a/ios/chrome/browser/ui/reading_list/BUILD.gn
+++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -122,6 +122,7 @@
     "//components/infobars/core",
     "//components/reading_list/core",
     "//components/ukm/ios:ukm_url_recorder",
+    "//ios/chrome/browser/ui/reading_list:reading_list_constants",
     "//ios/web/public",
     "//services/metrics/public/cpp:ukm_builders",
   ]
diff --git a/ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.mm b/ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.mm
index 9579cf6..73799b7 100644
--- a/ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.mm
+++ b/ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.mm
@@ -4,11 +4,14 @@
 
 #import "ios/chrome/browser/ui/reading_list/ios_add_to_reading_list_infobar_delegate.h"
 
+#import <Foundation/Foundation.h>
+
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/infobars/core/infobar.h"
 #include "components/reading_list/core/reading_list_model.h"
 #include "components/ukm/ios/ukm_url_recorder.h"
+#import "ios/chrome/browser/ui/reading_list/reading_list_constants.h"
 #import "ios/web/public/web_state.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 
@@ -62,5 +65,8 @@
         .SetAddedFromMessages(true)
         .Record(ukm::UkmRecorder::Get());
   }
+  [[NSUserDefaults standardUserDefaults]
+      setBool:YES
+       forKey:kLastReadingListEntryAddedFromMessages];
   return true;
 }
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_constants.h b/ios/chrome/browser/ui/reading_list/reading_list_constants.h
index 94af179..3f4143a 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_constants.h
+++ b/ios/chrome/browser/ui/reading_list/reading_list_constants.h
@@ -5,7 +5,7 @@
 #ifndef IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_CONSTANTS_H_
 #define IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_CONSTANTS_H_
 
-#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
 
 // Accessibility identifier for reading list view.
 extern NSString* const kReadingListViewID;
@@ -22,5 +22,9 @@
 
 // NSUserDefault key to save last time a Messages prompt was shown.
 extern NSString* const kLastTimeUserShownReadingListMessages;
+extern NSString* const kLastReadingListEntryAddedFromMessages;
+extern NSString* const kShouldAnimateReadingListNTPUnreadCountBadge;
+extern NSString* const kShouldAnimateReadingListOverflowMenuUnreadCountBadge;
+extern CGFloat const kReadingListUnreadCountBadgeAnimationDuration;
 
 #endif  // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_constants.mm b/ios/chrome/browser/ui/reading_list/reading_list_constants.mm
index f21afb7..c19ecfe 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_constants.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_constants.mm
@@ -26,3 +26,10 @@
 
 NSString* const kLastTimeUserShownReadingListMessages =
     @"LastTimeUserShownReadingListMessages";
+NSString* const kLastReadingListEntryAddedFromMessages =
+    @"LastReadingListEntryAddedFromMessages";
+NSString* const kShouldAnimateReadingListNTPUnreadCountBadge =
+    @"ShouldAnimateReadingListNTPUnreadCountBadge";
+NSString* const kShouldAnimateReadingListOverflowMenuUnreadCountBadge =
+    @"ShouldAnimateReadingListOverflowMenuUnreadCountBadge";
+CGFloat const kReadingListUnreadCountBadgeAnimationDuration = 0.3;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
index fb2c071e..7185085 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -5,12 +5,12 @@
 #import "ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.h"
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/ios/ios_util.h"
 #include "base/mac/foundation_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
-#include "base/stl_util.h"
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/app/tests_hook.h"
 #import "ios/chrome/browser/drag_and_drop/drag_item_util.h"
@@ -209,6 +209,14 @@
 - (void)viewDidLoad {
   [super viewDidLoad];
 
+  if (IsReadingListMessagesEnabled()) {
+    // Reset the boolean if an entry was added from a Messages prompt since the
+    // user has now seen that new entry in the Reading List.
+    [[NSUserDefaults standardUserDefaults]
+        setBool:NO
+         forKey:kLastReadingListEntryAddedFromMessages];
+  }
+
   self.title = l10n_util::GetNSString(IDS_IOS_TOOLS_MENU_READING_LIST);
 
   self.tableView.accessibilityIdentifier =
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
index 2ab43c5..cb1ff5aa 100644
--- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -132,6 +132,7 @@
     "//ios/chrome/browser/main:test_support",
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/signin",
+    "//ios/chrome/browser/signin:test_support",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/sync:test_support",
     "//ios/chrome/browser/ui:feature_flags",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
index f11255c..ce79b31 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator_unittest.mm
@@ -20,6 +20,8 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/main/test_browser.h"
 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
+#import "ios/chrome/browser/signin/authentication_service_factory.h"
+#import "ios/chrome/browser/signin/authentication_service_fake.h"
 #include "ios/chrome/browser/sync/session_sync_service_factory.h"
 #include "ios/chrome/browser/sync/sync_setup_service.h"
 #include "ios/chrome/browser/sync/sync_setup_service_factory.h"
@@ -127,6 +129,10 @@
     test_cbs_builder.AddTestingFactory(
         IOSChromeTabRestoreServiceFactory::GetInstance(),
         IOSChromeTabRestoreServiceFactory::GetDefaultFactory());
+    test_cbs_builder.AddTestingFactory(
+        AuthenticationServiceFactory::GetInstance(),
+        base::BindRepeating(
+            &AuthenticationServiceFake::CreateAuthenticationService));
     chrome_browser_state_ = test_cbs_builder.Build();
 
     browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get(),
@@ -235,6 +241,7 @@
 };
 
 TEST_F(RecentTabsTableCoordinatorTest, TestConstructorDestructor) {
+  SetupSyncState(NO, NO, NO, NO);
   CreateController();
   EXPECT_TRUE(coordinator_);
 }
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 1f2f215..03ce1d5 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -771,7 +771,7 @@
   [self.contextMenuCoordinator stop];
 
   ios::GetChromeBrowserProvider()
-      ->GetModalsProvider()
+      .GetModalsProvider()
       ->DismissModalsForTableView(self.tableView);
 }
 
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
index 3c43afef..50cd918c 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.mm
@@ -4,8 +4,8 @@
 
 #import "ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_table_view_controller.h"
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/field_types.h"
diff --git a/ios/chrome/browser/ui/settings/cells/account_sign_in_item.mm b/ios/chrome/browser/ui/settings/cells/account_sign_in_item.mm
index 06ac5705..1f853ea 100644
--- a/ios/chrome/browser/ui/settings/cells/account_sign_in_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/account_sign_in_item.mm
@@ -45,7 +45,7 @@
 
   cell.detailTextLabel.text = self.detailText;
   cell.image = CircularImageFromImage(ios::GetChromeBrowserProvider()
-                                          ->GetSigninResourcesProvider()
+                                          .GetSigninResourcesProvider()
                                           ->GetDefaultAvatar(),
                                       kAccountProfilePhotoDimension);
 }
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 9a885b0..ed95b11 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
@@ -502,23 +502,23 @@
           l10n_util::GetNSString(IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_GOOGLE_DSE);
       footerItem.urls = std::vector<GURL>{
           google_util::AppendGoogleLocaleParam(
-              GURL(kClearBrowsingDataSearchMyActivityUrlInFooterURL),
+              GURL(kClearBrowsingDataDSESearchUrlInFooterURL),
               GetApplicationContext()->GetApplicationLocale()),
           google_util::AppendGoogleLocaleParam(
-              GURL(kClearBrowsingDataMyActivityUrlInFooterURL),
+              GURL(kClearBrowsingDataDSEMyActivityUrlInFooterURL),
               GetApplicationContext()->GetApplicationLocale())};
     } else if (defaultSearchEngine->prepopulate_id() > 0) {
       footerItem.text = l10n_util::GetNSStringF(
           IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_KNOWN_DSE_SIGNED_IN,
           defaultSearchEngine->short_name());
       footerItem.urls = std::vector<GURL>{google_util::AppendGoogleLocaleParam(
-          GURL(kClearBrowsingDataMyActivityUrlInFooterURL),
+          GURL(kClearBrowsingDataDSEMyActivityUrlInFooterURL),
           GetApplicationContext()->GetApplicationLocale())};
     } else {
       footerItem.text = l10n_util::GetNSString(
           IDS_IOS_CLEAR_BROWSING_DATA_FOOTER_UNKOWN_DSE_SIGNED_IN);
       footerItem.urls = std::vector<GURL>{google_util::AppendGoogleLocaleParam(
-          GURL(kClearBrowsingDataMyActivityUrlInFooterURL),
+          GURL(kClearBrowsingDataDSEMyActivityUrlInFooterURL),
           GetApplicationContext()->GetApplicationLocale())};
     }
   } else {
@@ -547,7 +547,7 @@
 
 - (TableViewLinkHeaderFooterItem*)footerGoogleAccountAndMyActivityItem {
   UIImage* image = ios::GetChromeBrowserProvider()
-                       ->GetBrandedImageProvider()
+                       .GetBrandedImageProvider()
                        ->GetClearBrowsingDataAccountActivityImage();
   return [self
       footerItemWithType:ItemTypeFooterGoogleAccountAndMyActivity
@@ -558,7 +558,7 @@
 
 - (TableViewLinkHeaderFooterItem*)footerSavedSiteDataItem {
   UIImage* image = ios::GetChromeBrowserProvider()
-                       ->GetBrandedImageProvider()
+                       .GetBrandedImageProvider()
                        ->GetClearBrowsingDataSiteDataImage();
   return [self
       footerItemWithType:ItemTypeFooterSavedSiteData
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm
index 09d8f10..d9342c77 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.mm
@@ -4,8 +4,8 @@
 
 #import "ios/chrome/browser/ui/settings/clear_browsing_data/time_range_selector_table_view_controller.h"
 
+#include "base/cxx17_backports.h"
 #import "base/mac/foundation_util.h"
-#include "base/stl_util.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/prefs/pref_member.h"
diff --git a/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm
index 4415e103..3c8ad286 100644
--- a/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/content_settings_table_view_controller.mm
@@ -127,7 +127,7 @@
   [model addItem:[self blockPopupsItem]
       toSectionWithIdentifier:SectionIdentifierSettings];
   MailtoHandlerProvider* provider =
-      ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+      ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
   NSString* settingsTitle = provider->MailtoHandlerSettingsTitle();
   // Display email settings only on one window at a time, by checking
   // if this is the current owner.
@@ -176,7 +176,7 @@
       initWithType:ItemTypeSettingsComposeEmail];
   // Use the handler's preferred title string for the compose email item.
   MailtoHandlerProvider* provider =
-      ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+      ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
   NSString* settingsTitle = provider->MailtoHandlerSettingsTitle();
   DCHECK([settingsTitle length]);
   // .detailText can display the selected mailto handling app, but the current
@@ -194,7 +194,7 @@
       initWithType:ItemTypeSettingsComposeEmail];
   // Use the handler's preferred title string for the compose email item.
   MailtoHandlerProvider* provider =
-      ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+      ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
   NSString* settingsTitle = provider->MailtoHandlerSettingsTitle();
   DCHECK([settingsTitle length]);
   // .detailText can display the selected mailto handling app, but the current
@@ -231,7 +231,7 @@
         break;
 
       MailtoHandlerProvider* provider =
-          ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+          ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
       UIViewController* controller =
           provider->MailtoHandlerSettingsController();
       if (controller) {
@@ -277,7 +277,7 @@
   // bar stack items.
   NSString* top = self.navigationController.navigationBar.topItem.title;
   MailtoHandlerProvider* provider =
-      ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider();
+      ios::GetChromeBrowserProvider().GetMailtoHandlerProvider();
   NSString* mailToTitle = provider->MailtoHandlerSettingsTitle();
   if ([top isEqualToString:mailToTitle]) {
     openedMailTo = NO;
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
index 514c5d89..8c182c6 100644
--- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -238,7 +238,7 @@
   NSString* authenticatedEmail = [authenticatedIdentity userEmail];
   for (const auto& account : identityManager->GetAccountsWithRefreshTokens()) {
     ios::ChromeIdentityService* identityService =
-        ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+        ios::GetChromeBrowserProvider().GetChromeIdentityService();
     ChromeIdentity* identity =
         identityService->GetIdentityWithGaiaID(account.gaia);
     if (!identity) {
@@ -532,7 +532,7 @@
   _alertCoordinator = nil;
   _dimissAccountDetailsViewControllerBlock =
       ios::GetChromeBrowserProvider()
-          ->GetChromeIdentityService()
+          .GetChromeIdentityService()
           ->PresentAccountDetailsController(identity, self,
                                             /*animated=*/YES);
 }
@@ -575,7 +575,7 @@
   DCHECK(self.removeAccountCoordinator);
   self.removeAccountCoordinator = nil;
   self.uiDisabled = YES;
-  ios::GetChromeBrowserProvider()->GetChromeIdentityService()->ForgetIdentity(
+  ios::GetChromeBrowserProvider().GetChromeIdentityService()->ForgetIdentity(
       identity, ^(NSError* error) {
         self.uiDisabled = NO;
       });
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 6cb799ab..5498564 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
@@ -299,10 +299,6 @@
           self.browser->GetBrowserState());
   BOOL isSyncConsentGiven =
       syncSetupService && syncSetupService->IsFirstSetupComplete();
-  NSString* title =
-      isSyncConsentGiven
-          ? l10n_util::GetNSString(IDS_IOS_SIGNOUT_DIALOG_TITLE_WITHOUT_SYNC)
-          : nil;
   NSString* message =
       isSyncConsentGiven
           ? l10n_util::GetNSString(IDS_IOS_SIGNOUT_DIALOG_MESSAGE_WITH_SYNC)
@@ -310,7 +306,7 @@
   self.signOutCoordinator = [[ActionSheetCoordinator alloc]
       initWithBaseViewController:self.viewController
                          browser:self.browser
-                           title:title
+                           title:nil
                          message:message
                             rect:targetRect
                             view:self.viewController.view];
@@ -412,7 +408,7 @@
 
 - (void)openManageGoogleAccount {
   ios::GetChromeBrowserProvider()
-      ->GetChromeIdentityService()
+      .GetChromeIdentityService()
       ->PresentAccountDetailsController(
           self.authService->GetAuthenticatedIdentity(),
           self.googleServicesSettingsViewController, /*animated=*/YES);
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
index 4aba939..91b6cda0 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -403,7 +403,7 @@
         IDS_IOS_TOGGLE_SETTING_MANAGED_ACCESSIBILITY_HINT);
     signinDisabledItem.image =
         CircularImageFromImage(ios::GetChromeBrowserProvider()
-                                   ->GetSigninResourcesProvider()
+                                   .GetSigninResourcesProvider()
                                    ->GetDefaultAvatar(),
                                kAccountProfilePhotoDimension);
     signinDisabledItem.textColor = [UIColor colorNamed:kTextSecondaryColor];
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
index 77d2ece2..faa854a 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_coordinator.mm
@@ -224,7 +224,7 @@
       "Signin_AccountSettings_GoogleActivityControlsClicked"));
   self.dismissWebAndAppSettingDetailsControllerBlock =
       ios::GetChromeBrowserProvider()
-          ->GetChromeIdentityService()
+          .GetChromeIdentityService()
           ->PresentWebAndAppSettingDetailsController(
               authService->GetAuthenticatedIdentity(), self.viewController,
               YES);
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm
index 880fad8..1bc15b65 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_settings_app_interface.mm
@@ -104,6 +104,12 @@
   // When we retrieve the form from the store, |in_store| should be set.
   password_manager::PasswordForm expected_form = form;
   expected_form.in_store = password_manager::PasswordForm::Store::kProfileStore;
+  // TODO(crbug.com/1223022): Once all places that operate changes on forms
+  // via UpdateLogin properly set |password_issues|, setting them to an empty
+  // map should be part of the default constructor.
+  expected_form.password_issues =
+      base::flat_map<password_manager::InsecureType,
+                     password_manager::InsecurityMetadata>();
   // Check the result and ensure PasswordStore processed this.
   FakeStoreConsumer consumer;
   if (!consumer.FetchStoreResults()) {
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
index 2f11cc5..8f2eb90 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -190,11 +190,11 @@
                              handler:(id<ApplicationCommands>)handler {
   DCHECK(browser);
   DCHECK(ios::GetChromeBrowserProvider()
-             ->GetUserFeedbackProvider()
+             .GetUserFeedbackProvider()
              ->IsUserFeedbackEnabled());
   UIViewController* controller =
       ios::GetChromeBrowserProvider()
-          ->GetUserFeedbackProvider()
+          .GetUserFeedbackProvider()
           ->CreateViewController(dataSource, handler, sender);
   DCHECK(controller);
   SettingsNavigationController* nc = [[SettingsNavigationController alloc]
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index c3aeb054..5f0fbe3 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -725,7 +725,7 @@
       l10n_util::GetNSString(IDS_IOS_NOT_SIGNED_IN_SETTING_TITLE);
   signinDisabledItem.image =
       CircularImageFromImage(ios::GetChromeBrowserProvider()
-                                 ->GetSigninResourcesProvider()
+                                 .GetSigninResourcesProvider()
                                  ->GetDefaultAvatar(),
                              kAccountProfilePhotoDimension);
   signinDisabledItem.enabled = NO;
@@ -1792,16 +1792,16 @@
 // Image used for loggedin user account that supports caching.
 - (UIImage*)userAccountImage {
   UIImage* image = ios::GetChromeBrowserProvider()
-                       ->GetChromeIdentityService()
+                       .GetChromeIdentityService()
                        ->GetCachedAvatarForIdentity(_identity);
   if (!image) {
     image = ios::GetChromeBrowserProvider()
-                ->GetSigninResourcesProvider()
+                .GetSigninResourcesProvider()
                 ->GetDefaultAvatar();
     // No cached image, trigger a fetch, which will notify all observers
     // (including the corresponding AccountViewBase).
     ios::GetChromeBrowserProvider()
-        ->GetChromeIdentityService()
+        .GetChromeIdentityService()
         ->GetAvatarForIdentity(_identity, nil);
   }
 
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
index 6d973df..e639cb6 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller_unittest.mm
@@ -121,6 +121,10 @@
   }
 
   void TearDown() override {
+    // Cleanup any policies left from the test.
+    [[NSUserDefaults standardUserDefaults]
+        removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+
     [static_cast<SettingsTableViewController*>(controller())
         settingsWillBeDismissed];
     ChromeTableViewControllerTest::TearDown();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
index c5223d79..a55bb81 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -181,6 +181,8 @@
     "//ios/chrome/browser/sessions",
     "//ios/chrome/browser/sessions:restoration_agent",
     "//ios/chrome/browser/sessions:test_support",
+    "//ios/chrome/browser/signin",
+    "//ios/chrome/browser/signin:test_support",
     "//ios/chrome/browser/snapshots",
     "//ios/chrome/browser/tabs",
     "//ios/chrome/browser/tabs:tabs_internal",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
index fdc7095..b9e7f1d 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -50,6 +50,8 @@
     "resources:grid_theme_selection_tint_color",
     "resources:plus_sign_grid_cell_background_color",
     "//base",
+    "//components/bookmarks/common",
+    "//components/prefs",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm
index 14debaf1..4dc4cb1 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.mm
@@ -5,6 +5,8 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_context_menu_helper.h"
 
 #include "base/metrics/histogram_functions.h"
+#import "components/bookmarks/common/bookmark_pref_names.h"
+#import "components/prefs/pref_service.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/ui/menu/action_factory.h"
@@ -94,26 +96,34 @@
                 }]];
           }
 
+          UIAction* bookmarkAction;
           bool currentlyBookmarked =
               [weakSelf.actionsDataSource isGridItemBookmarked:item];
           if (currentlyBookmarked) {
             if ([weakSelf.contextMenuDelegate
                     respondsToSelector:@selector(editBookmarkWithURL:)]) {
-              [menuElements
-                  addObject:[actionFactory actionToEditBookmarkWithBlock:^{
-                    [weakSelf.contextMenuDelegate editBookmarkWithURL:item.URL];
-                  }]];
+              bookmarkAction = [actionFactory actionToEditBookmarkWithBlock:^{
+                [weakSelf.contextMenuDelegate editBookmarkWithURL:item.URL];
+              }];
             }
           } else {
             if ([weakSelf.contextMenuDelegate
                     respondsToSelector:@selector(bookmarkURL:title:)]) {
-              [menuElements
-                  addObject:[actionFactory actionToBookmarkWithBlock:^{
-                    [weakSelf.contextMenuDelegate bookmarkURL:item.URL
-                                                        title:item.title];
-                  }]];
+              bookmarkAction = [actionFactory actionToBookmarkWithBlock:^{
+                [weakSelf.contextMenuDelegate bookmarkURL:item.URL
+                                                    title:item.title];
+              }];
             }
           }
+          // Bookmarking can be disabled from prefs (from an enterprise policy),
+          // if that's the case grey out the option in the menu.
+          BOOL isEditBookmarksEnabled =
+              strongSelf.browser->GetBrowserState()->GetPrefs()->GetBoolean(
+                  bookmarks::prefs::kEditBookmarksEnabled);
+          if (!isEditBookmarksEnabled && bookmarkAction)
+            bookmarkAction.attributes = UIMenuElementAttributesDisabled;
+          if (bookmarkAction)
+            [menuElements addObject:bookmarkAction];
         }
 
         if ([weakSelf.contextMenuDelegate
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
index b2f7b701..5034ae78 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -818,7 +818,7 @@
 
 - (void)dismissModals {
   ios::GetChromeBrowserProvider()
-      ->GetModalsProvider()
+      .GetModalsProvider()
       ->DismissModalsForCollectionView(self.collectionView);
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator_unittest.mm
index 9be72c0..b9b4ee8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator_unittest.mm
@@ -13,6 +13,8 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/main/test_browser.h"
 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
+#import "ios/chrome/browser/signin/authentication_service_factory.h"
+#import "ios/chrome/browser/signin/authentication_service_fake.h"
 #import "ios/chrome/browser/snapshots/snapshot_browser_agent.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browsing_data_commands.h"
@@ -77,7 +79,8 @@
 
 class TabGridCoordinatorTest : public BlockCleanupTest {
  public:
-  TabGridCoordinatorTest() {
+  void SetUp() override {
+    BlockCleanupTest::SetUp();
     scene_state_ = [[StubSceneState alloc] initWithAppState:nil];
     scene_state_.window =
         [[UIApplication sharedApplication].windows firstObject];
@@ -86,6 +89,10 @@
     test_cbs_builder.AddTestingFactory(
         IOSChromeTabRestoreServiceFactory::GetInstance(),
         IOSChromeTabRestoreServiceFactory::GetDefaultFactory());
+    test_cbs_builder.AddTestingFactory(
+        AuthenticationServiceFactory::GetInstance(),
+        base::BindRepeating(
+            &AuthenticationServiceFake::CreateAuthenticationService));
     chrome_browser_state_ = test_cbs_builder.Build();
 
     browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get());
@@ -121,8 +128,6 @@
     incognito_tab_view_controller_.view.frame = CGRectMake(40, 40, 10, 10);
   }
 
-  ~TabGridCoordinatorTest() override {}
-
   void TearDown() override {
     if (original_root_view_controller_) {
       GetAnyKeyWindow().rootViewController = original_root_view_controller_;
@@ -132,8 +137,8 @@
   }
 
  protected:
-  std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
   web::WebTaskEnvironment task_environment_;
+  std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
   // Browser for the coordinator.
   std::unique_ptr<Browser> browser_;
 
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
index e801385a..9adf62ef0 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator.mm
@@ -209,7 +209,7 @@
 - (void)setConsumer:(id<ToolbarConsumer>)consumer {
   _consumer = consumer;
   [_consumer setVoiceSearchEnabled:ios::GetChromeBrowserProvider()
-                                       ->GetVoiceSearchProvider()
+                                       .GetVoiceSearchProvider()
                                        ->IsVoiceSearchEnabled()];
   if (self.webState) {
     [self updateConsumer];
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
index 96b6f44..980ec4c 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_mediator_unittest.mm
@@ -183,7 +183,7 @@
 
   void set_voice_search_enabled(bool enabled) {
     static_cast<TestToolbarMediatorVoiceSearchProvider*>(
-        ios::GetChromeBrowserProvider()->GetVoiceSearchProvider())
+        ios::GetChromeBrowserProvider().GetVoiceSearchProvider())
         ->set_voice_search_enabled(enabled);
   }
 
diff --git a/ios/chrome/browser/ui/toolbar_container/toolbar_container_view_controller_unittest.mm b/ios/chrome/browser/ui/toolbar_container/toolbar_container_view_controller_unittest.mm
index 120dc58..abf25c3 100644
--- a/ios/chrome/browser/ui/toolbar_container/toolbar_container_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/toolbar_container/toolbar_container_view_controller_unittest.mm
@@ -7,7 +7,7 @@
 #include <algorithm>
 #include <vector>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/ui/toolbar_container/toolbar_collapsing.h"
 #import "ios/chrome/browser/ui/toolbar_container/toolbar_height_range.h"
diff --git a/ios/chrome/browser/ui/util/ui_util_unittest.mm b/ios/chrome/browser/ui/util/ui_util_unittest.mm
index e3680f6..95f1481 100644
--- a/ios/chrome/browser/ui/util/ui_util_unittest.mm
+++ b/ios/chrome/browser/ui/util/ui_util_unittest.mm
@@ -7,7 +7,7 @@
 #import <UIKit/UIKit.h>
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
diff --git a/ios/chrome/browser/voice/fake_voice_search_availability.mm b/ios/chrome/browser/voice/fake_voice_search_availability.mm
index 3eb6f6b..b549ad5 100644
--- a/ios/chrome/browser/voice/fake_voice_search_availability.mm
+++ b/ios/chrome/browser/voice/fake_voice_search_availability.mm
@@ -28,11 +28,10 @@
 }
 
 void FakeVoiceSearchAvailability::SetVoiceProviderEnabled(bool enabled) {
-  ios::TestChromeBrowserProvider* browser_provider =
-      ios::TestChromeBrowserProvider::GetTestProvider();
   TestVoiceSearchProvider* voice_provider =
       static_cast<TestVoiceSearchProvider*>(
-          browser_provider->GetVoiceSearchProvider());
+          ios::TestChromeBrowserProvider::GetTestProvider()
+              .GetVoiceSearchProvider());
   voice_provider->set_voice_search_enabled(enabled);
 }
 
diff --git a/ios/chrome/browser/voice/speech_input_locale_config.mm b/ios/chrome/browser/voice/speech_input_locale_config.mm
index 1c04ed3c..366fe5b 100644
--- a/ios/chrome/browser/voice/speech_input_locale_config.mm
+++ b/ios/chrome/browser/voice/speech_input_locale_config.mm
@@ -19,7 +19,7 @@
 SpeechInputLocaleConfig* SpeechInputLocaleConfig::GetInstance() {
   static base::NoDestructor<SpeechInputLocaleConfigImpl> instance(
       ios::GetChromeBrowserProvider()
-          ->GetVoiceSearchProvider()
+          .GetVoiceSearchProvider()
           ->GetAvailableLanguages(),
       LoadSpeechInputLocaleMatches());
   return instance.get();
diff --git a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
index a03eb96..ccad85a 100644
--- a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
+++ b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
@@ -55,7 +55,7 @@
 
 SpeechInputLocaleConfigImpl::SpeechInputLocaleConfigImpl()
     : SpeechInputLocaleConfigImpl(ios::GetChromeBrowserProvider()
-                                      ->GetVoiceSearchProvider()
+                                      .GetVoiceSearchProvider()
                                       ->GetAvailableLanguages(),
                                   LoadSpeechInputLocaleMatches()) {}
 
diff --git a/ios/chrome/browser/voice/voice_search_availability.mm b/ios/chrome/browser/voice/voice_search_availability.mm
index ffd2e21..fd643da 100644
--- a/ios/chrome/browser/voice/voice_search_availability.mm
+++ b/ios/chrome/browser/voice/voice_search_availability.mm
@@ -43,7 +43,7 @@
 
 bool VoiceSearchAvailability::IsVoiceSearchAvailable() const {
   return !voice_over_enabled_ && ios::GetChromeBrowserProvider()
-                                     ->GetVoiceSearchProvider()
+                                     .GetVoiceSearchProvider()
                                      ->IsVoiceSearchEnabled();
 }
 
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm
index 70b8ce0962..e23c111 100644
--- a/ios/chrome/browser/web/chrome_web_client.mm
+++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -211,7 +211,7 @@
     // Initialize the audio session to allow a web page's audio to continue
     // playing after the app is backgrounded.
     VoiceSearchProvider* voice_provider =
-        ios::GetChromeBrowserProvider()->GetVoiceSearchProvider();
+        ios::GetChromeBrowserProvider().GetVoiceSearchProvider();
     if (voice_provider) {
       AudioSessionController* audio_controller =
           voice_provider->GetAudioSessionController();
@@ -287,7 +287,7 @@
     web::BrowserURLRewriter* rewriter) {
   rewriter->AddURLRewriter(&WillHandleWebBrowserAboutURL);
   BrowserURLRewriterProvider* provider =
-      ios::GetChromeBrowserProvider()->GetBrowserURLRewriterProvider();
+      ios::GetChromeBrowserProvider().GetBrowserURLRewriterProvider();
   if (provider)
     provider->AddProviderRewriters(rewriter);
 }
diff --git a/ios/chrome/browser/web/font_size/font_size_tab_helper.mm b/ios/chrome/browser/web/font_size/font_size_tab_helper.mm
index 87122cd..265d350 100644
--- a/ios/chrome/browser/web/font_size/font_size_tab_helper.mm
+++ b/ios/chrome/browser/web/font_size/font_size_tab_helper.mm
@@ -139,7 +139,7 @@
   }
   tab_helper_has_zoomed_ = true;
 
-  ios::GetChromeBrowserProvider()->GetTextZoomProvider()->SetPageFontSize(
+  ios::GetChromeBrowserProvider().GetTextZoomProvider()->SetPageFontSize(
       web_state_, size);
 }
 
diff --git a/ios/chrome/common/ui/elements/popover_label_view_controller.mm b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
index 8b7a4be..2f44ccd 100644
--- a/ios/chrome/common/ui/elements/popover_label_view_controller.mm
+++ b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
@@ -179,8 +179,7 @@
   }
 
   NSLayoutConstraint* heightConstraint = [_scrollView.heightAnchor
-      constraintEqualToAnchor:_scrollView.contentLayoutGuide.heightAnchor
-                   multiplier:1];
+      constraintEqualToAnchor:_scrollView.contentLayoutGuide.heightAnchor];
 
   // UILayoutPriorityDefaultHigh is the default priority for content
   // compression. Setting this lower avoids compressing the content of the
diff --git a/ios/chrome/common/x_callback_url_unittest.cc b/ios/chrome/common/x_callback_url_unittest.cc
index 457c7bd..a546071 100644
--- a/ios/chrome/common/x_callback_url_unittest.cc
+++ b/ios/chrome/common/x_callback_url_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "ios/chrome/common/x_callback_url.h"
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
diff --git a/ios/chrome/credential_provider_extension/credential_provider_extension_localize_strings_config.plist b/ios/chrome/credential_provider_extension/credential_provider_extension_localize_strings_config.plist
index 616856b..d56b417 100644
--- a/ios/chrome/credential_provider_extension/credential_provider_extension_localize_strings_config.plist
+++ b/ios/chrome/credential_provider_extension/credential_provider_extension_localize_strings_config.plist
@@ -27,6 +27,7 @@
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_DETAILS_USERNAME</string>
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_EMPTY_CREDENTIALS_SUBTITLE</string>
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_EMPTY_CREDENTIALS_TITLE</string>
+				<string>IDS_IOS_CREDENTIAL_PROVIDER_ENTER</string>
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_EXTENSION_CANCEL</string>
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_HELP_ACCESSIBILITY_LABEL</string>
 				<string>IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS</string>
diff --git a/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings.grd b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings.grd
index f18f565..b4bdb3d 100644
--- a/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings.grd
+++ b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings.grd
@@ -203,6 +203,9 @@
       <message name="IDS_IOS_CREDENTIAL_PROVIDER_EMPTY_CREDENTIALS_TITLE" desc="Title for empty credentials screen." meaning="Title to show when a user has no credentials available [CHAR_LIMIT=25]">
         No Chrome Passwords
       </message>
+      <message name="IDS_IOS_CREDENTIAL_PROVIDER_ENTER" desc="Used for Enter on buttons [CHAR_LIMIT=10]">
+        Enter
+      </message>
       <message name="IDS_IOS_CREDENTIAL_PROVIDER_EXTENSION_CANCEL" desc="Title for cancel buttons" meaning="Title for buttons meant to cancel an action [CHAR_LIMIT=10]">
         Cancel
       </message>
@@ -210,7 +213,7 @@
         Help
       </message>
       <message name="IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS" desc="Text shown when no password search results have been found" meaning="Textual search for passwords returned nothing [CHAR_LIMIT=30]">
-        No search results found
+        No Passwords Found
       </message>
       <message name="IDS_IOS_CREDENTIAL_PROVIDER_STALE_CREDENTIALS_SUBTITLE" desc="Subtitle for stale credentials screen" meaning="Subtitle to show when a user signs out, and the credentials are no longer available.">
         You recently signed out of your Google Account. To see your passwords, sign in to Chrome.
diff --git a/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_ENTER.png.sha1 b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_ENTER.png.sha1
new file mode 100644
index 0000000..9b9d09e
--- /dev/null
+++ b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_ENTER.png.sha1
@@ -0,0 +1 @@
+f7f27eee5eeaa7457d81076f988de9cb7424bd93
\ No newline at end of file
diff --git a/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS.png.sha1 b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS.png.sha1
index 3fcf029..012d403 100644
--- a/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS.png.sha1
+++ b/ios/chrome/credential_provider_extension/strings/ios_credential_provider_extension_strings_grd/IDS_IOS_CREDENTIAL_PROVIDER_NO_SEARCH_RESULTS.png.sha1
@@ -1 +1 @@
-490c9baae1371d00124fe1b4bc13255a8eaea192
\ No newline at end of file
+636d99fb145e4d6cbaabf9a806a614c377e0d6b0
\ No newline at end of file
diff --git a/ios/chrome/credential_provider_extension/ui/credential_details_consumer.h b/ios/chrome/credential_provider_extension/ui/credential_details_consumer.h
index 31d0670..e141435 100644
--- a/ios/chrome/credential_provider_extension/ui/credential_details_consumer.h
+++ b/ios/chrome/credential_provider_extension/ui/credential_details_consumer.h
@@ -14,6 +14,9 @@
 // Called when the user taps the cancel button in the navigation bar.
 - (void)navigationCancelButtonWasPressed:(UIButton*)button;
 
+// Called when the user selects a credential.
+- (void)userSelectedCredential:(id<Credential>)credential;
+
 // Called when the user requests a clear view of the password. The delegate
 // should complete with the clear password or nil in case of failure or
 // deny by user.
diff --git a/ios/chrome/credential_provider_extension/ui/credential_details_view_controller.mm b/ios/chrome/credential_provider_extension/ui/credential_details_view_controller.mm
index 11415ae..efcacda2 100644
--- a/ios/chrome/credential_provider_extension/ui/credential_details_view_controller.mm
+++ b/ios/chrome/credential_provider_extension/ui/credential_details_view_controller.mm
@@ -67,7 +67,9 @@
   self.view.backgroundColor = backgroundColor;
   self.navigationController.navigationBar.translucent = NO;
   self.navigationController.navigationBar.backgroundColor = backgroundColor;
-  self.navigationItem.rightBarButtonItem = [self navigationCancelButton];
+  self.navigationItem.rightBarButtonItem = IsPasswordCreationEnabled()
+                                               ? [self navigationEnterButton]
+                                               : [self navigationCancelButton];
   self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
 
   NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
@@ -212,6 +214,11 @@
   [self passwordIconButtonTapped:nil event:nil];
 }
 
+// Alert the delegate that the user wants to enter this password.
+- (void)enterPassword {
+  [self.delegate userSelectedCredential:self.credential];
+}
+
 // Creates a cancel button for the navigation item.
 - (UIBarButtonItem*)navigationCancelButton {
   UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
@@ -222,6 +229,18 @@
   return cancelButton;
 }
 
+// Creates an enter button for the navigation item
+- (UIBarButtonItem*)navigationEnterButton {
+  UIBarButtonItem* enterButton = [[UIBarButtonItem alloc]
+      initWithTitle:NSLocalizedString(@"IDS_IOS_CREDENTIAL_PROVIDER_ENTER",
+                                      @"Enter")
+              style:UIBarButtonItemStyleDone
+             target:self
+             action:@selector(enterPassword)];
+  enterButton.tintColor = [UIColor colorNamed:kBlueColor];
+  return enterButton;
+}
+
 // Returns the string to display as password.
 - (NSString*)password {
   return self.clearPassword ? self.clearPassword : kMaskedPassword;
diff --git a/ios/chrome/share_extension/share_extension_view.mm b/ios/chrome/share_extension/share_extension_view.mm
index 35b47dcf..dc737f3 100644
--- a/ios/chrome/share_extension/share_extension_view.mm
+++ b/ios/chrome/share_extension/share_extension_view.mm
@@ -211,7 +211,6 @@
         constraintEqualToAnchor:_itemView.centerYAnchor],
     [_itemView.heightAnchor
         constraintGreaterThanOrEqualToAnchor:_titleURLContainer.heightAnchor
-                                  multiplier:1
                                     constant:2 * kShareExtensionPadding],
     [_titleURLContainer.leadingAnchor
         constraintEqualToAnchor:_itemView.leadingAnchor
@@ -221,7 +220,6 @@
                        constant:-kShareExtensionPadding],
     [_itemView.heightAnchor
         constraintGreaterThanOrEqualToAnchor:_screenshotView.heightAnchor
-                                  multiplier:1
                                     constant:2 * kShareExtensionPadding],
     [_screenshotView.centerYAnchor
         constraintEqualToAnchor:_itemView.centerYAnchor],
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm
index 2bfc7db..e50e59b 100644
--- a/ios/chrome/test/app/signin_test_util.mm
+++ b/ios/chrome/test/app/signin_test_util.mm
@@ -39,7 +39,7 @@
       ChromeAccountManagerServiceFactory::GetForBrowserState(browser_state);
   NSArray* identities_to_remove = account_manager_service->GetAllIdentities();
   ios::ChromeIdentityService* identity_service =
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService();
+      ios::GetChromeBrowserProvider().GetChromeIdentityService();
   for (ChromeIdentity* identity in identities_to_remove) {
     identity_service->ForgetIdentity(identity, ^(NSError* error) {
       if (error) {
@@ -53,18 +53,17 @@
 }  // namespace
 
 void SetUpMockAuthentication() {
-  ios::ChromeBrowserProvider* provider = ios::GetChromeBrowserProvider();
   std::unique_ptr<ios::FakeChromeIdentityService> service(
       new ios::FakeChromeIdentityService());
   service->SetUpForIntegrationTests();
-  provider->SetChromeIdentityServiceForTesting(std::move(service));
+  ios::GetChromeBrowserProvider().SetChromeIdentityServiceForTesting(
+      std::move(service));
   AuthenticationServiceFactory::GetForBrowserState(GetOriginalBrowserState())
       ->ResetChromeIdentityServiceObserverForTesting();
 }
 
 void TearDownMockAuthentication() {
-  ios::ChromeBrowserProvider* provider = ios::GetChromeBrowserProvider();
-  provider->SetChromeIdentityServiceForTesting(nullptr);
+  ios::GetChromeBrowserProvider().SetChromeIdentityServiceForTesting(nullptr);
   AuthenticationServiceFactory::GetForBrowserState(GetOriginalBrowserState())
       ->ResetChromeIdentityServiceObserverForTesting();
 }
diff --git a/ios/chrome/test/earl_grey/chrome_egtest_bundle_main.mm b/ios/chrome/test/earl_grey/chrome_egtest_bundle_main.mm
index 5850a77f..c5ddb15 100644
--- a/ios/chrome/test/earl_grey/chrome_egtest_bundle_main.mm
+++ b/ios/chrome/test/earl_grey/chrome_egtest_bundle_main.mm
@@ -71,6 +71,17 @@
 
 }
 
+@class XCTSourceCodeSymbolInfo;
+@protocol XCTSymbolInfoProviding <NSObject>
+- (XCTSourceCodeSymbolInfo*)symbolInfoForAddressInCurrentProcess:(pid_t)pid
+                                                           error:
+                                                               (NSError**)error;
+@end
+
+@interface XCTSymbolicationService
++ (void)setSharedService:(id<XCTSymbolInfoProviding>)arg1;
+@end
+
 @interface ChromeEGTestBundleMain () <XCTestObservation> {
   std::unique_ptr<TestMain> _testMain;
 }
@@ -99,6 +110,17 @@
   CHECK(NSClassFromString(@"CRWWebController") == nil);
   CHECK(NSClassFromString(@"MainController") == nil);
   CHECK(NSClassFromString(@"BrowserViewController") == nil);
+
+  // Disable aggressive symbolication and disable symbolication service to work
+  // around slow XCTest assertion failures. These failures are spending a very
+  // long time attempting to symbolicate.
+  Class symbolicationService = NSClassFromString(@"XCTSymbolicationService");
+  if (symbolicationService != nil) {
+    [symbolicationService setSharedService:nil];
+  }
+  [[NSUserDefaults standardUserDefaults]
+      setBool:YES
+       forKey:@"XCTDisableAggressiveSymbolication"];
 }
 
 - (void)testBundleDidFinish:(NSBundle*)testBundle {
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm
index 447d7ec..45829468 100644
--- a/ios/chrome/test/earl_grey/eg_tests_hook.mm
+++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -71,11 +71,11 @@
           test_switches::kSignInAtStartup)) {
     // Record an identity as "known". If the identity isn't added, the
     // AuthenticationService will log the fake user off.
-    ios::ChromeBrowserProvider* provider = ios::GetChromeBrowserProvider();
     std::unique_ptr<ios::FakeChromeIdentityService> service(
         new ios::FakeChromeIdentityService());
     service->SetUpForIntegrationTests();
-    provider->SetChromeIdentityServiceForTesting(std::move(service));
+    ios::GetChromeBrowserProvider().SetChromeIdentityServiceForTesting(
+        std::move(service));
     ios::FakeChromeIdentityService* identity_service =
         ios::FakeChromeIdentityService::GetInstanceFromChromeProvider();
     identity_service->AddIdentity([SigninEarlGreyAppInterface fakeIdentity1]);
diff --git a/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h b/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h
index 18b57e58..8daa4f80 100644
--- a/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h
+++ b/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h
@@ -23,7 +23,7 @@
 
  private:
   std::unique_ptr<ios::ChromeBrowserProvider> chrome_browser_provider_;
-  ios::ChromeBrowserProvider* original_chrome_browser_provider_;
+  ios::ChromeBrowserProvider* original_chrome_browser_provider_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(IOSChromeScopedTestingChromeBrowserProvider);
 };
diff --git a/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.mm b/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.mm
index 8133d20..da2ab825 100644
--- a/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.mm
+++ b/ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.mm
@@ -14,13 +14,14 @@
 IOSChromeScopedTestingChromeBrowserProvider::
     IOSChromeScopedTestingChromeBrowserProvider(
         std::unique_ptr<ios::ChromeBrowserProvider> chrome_browser_provider)
-    : chrome_browser_provider_(std::move(chrome_browser_provider)),
-      original_chrome_browser_provider_(ios::GetChromeBrowserProvider()) {
-  ios::SetChromeBrowserProvider(chrome_browser_provider_.get());
+    : chrome_browser_provider_(std::move(chrome_browser_provider)) {
+  original_chrome_browser_provider_ =
+      ios::SetChromeBrowserProvider(chrome_browser_provider_.get());
 }
 
 IOSChromeScopedTestingChromeBrowserProvider::
     ~IOSChromeScopedTestingChromeBrowserProvider() {
-  DCHECK_EQ(chrome_browser_provider_.get(), ios::GetChromeBrowserProvider());
-  ios::SetChromeBrowserProvider(original_chrome_browser_provider_);
+  ios::ChromeBrowserProvider* provider =
+      ios::SetChromeBrowserProvider(original_chrome_browser_provider_);
+  DCHECK_EQ(provider, chrome_browser_provider_.get());
 }
diff --git a/ios/chrome/test/ios_chrome_unit_test_suite.mm b/ios/chrome/test/ios_chrome_unit_test_suite.mm
index d298d31..a5c91c5c 100644
--- a/ios/chrome/test/ios_chrome_unit_test_suite.mm
+++ b/ios/chrome/test/ios_chrome_unit_test_suite.mm
@@ -35,7 +35,6 @@
   ~IOSChromeUnitTestSuiteInitializer() override {}
 
   void OnTestStart(const testing::TestInfo& test_info) override {
-    DCHECK(!ios::GetChromeBrowserProvider());
     test_ios_chrome_provider_initializer_.reset(
         new ios::TestChromeProviderInitializer());
 
@@ -48,7 +47,6 @@
     application_context_.reset();
 
     test_ios_chrome_provider_initializer_.reset();
-    DCHECK(!ios::GetChromeBrowserProvider());
   }
 
  private:
diff --git a/ios/components/webui/sync_internals/sync_internals_message_handler.mm b/ios/components/webui/sync_internals/sync_internals_message_handler.mm
index cda2b53..ebac751b 100644
--- a/ios/components/webui/sync_internals/sync_internals_message_handler.mm
+++ b/ios/components/webui/sync_internals/sync_internals_message_handler.mm
@@ -106,7 +106,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestDataAndRegisterForUpdates(
     const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
 
   // is_registered_ flag protects us from double-registering.  This could
   // happen on a page refresh, where the JavaScript gets re-run but the
@@ -123,7 +123,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestListOfTypes(
     const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
   base::DictionaryValue event_details;
   auto type_list = std::make_unique<base::ListValue>();
   syncer::ModelTypeSet protocol_types = syncer::ProtocolTypes();
@@ -136,7 +136,7 @@
 
 void SyncInternalsMessageHandler::HandleRequestIncludeSpecificsInitialState(
     const base::ListValue* args) {
-  DCHECK(args->empty());
+  DCHECK(args->GetList().empty());
 
   base::DictionaryValue value;
   value.SetBoolean(syncer::sync_ui_util::kIncludeSpecifics,
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
index 582be7c..dbda422 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-2943e69504e8073665bb39e97219b720731f0185
\ No newline at end of file
+1d3cbc4b32fba0228b5db707f1f504ae0c2157ea
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
index 4e7511c..2b669c4 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-937c86771ec217272b3a61dd69b4036b09e9ba22
\ No newline at end of file
+86007a1fb3848c1cd552b57518def06d7b3edcfd
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
index 73b99e79..00f0159 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-0320d1292a40fc9195467f4569eb6bb091e626d2
\ No newline at end of file
+9684faeec1d36fef3f2cec3b4f01d24ea3ed6383
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
index 8572264..e780608 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-798061a240dcdfdd2068c7fe0b85c54d376849f7
\ No newline at end of file
+140d0d717bcb692dc9994381354d059d00735389
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
index e4a047c0d..0f3d331 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-a5ecf8b6c8fa89b7f2aabdffe107783519314000
\ No newline at end of file
+1d0763fe119f08b4a93d456cb69df06d94e4788b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
index fd8c1cc..7c4986d5 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-94feb7eea005db289b575e7d0e5c5166458106d1
\ No newline at end of file
+ae6a449db9138ce5a1ee7c8471caac5954558acd
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
index 5353fec..6be5b36 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-0d567b8676388ac0b4968628f59c09b7da4eda2f
\ No newline at end of file
+5e55685a766ef52368dc353112bb3c763e77fcef
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
index 48ed4dd..a247a50 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-cb19e8544dfe8b4bd3c2e276754aac49d755ce06
\ No newline at end of file
+c6ae716784b21494948f3e220f5fa37ff1e2d753
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
index e2e0a80b..6fb68887 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1
@@ -1 +1 @@
-9bf301cbfbce734fdb51fd16bf6095a7bd9fa179
\ No newline at end of file
+5832ef39efd328b552116df636b65d1a1155c2d7
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
index 1b2c03a..338e057 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1
@@ -1 +1 @@
-6f9ce9a41d9bc3bee6822d733cc71e2f6ec9c81c
\ No newline at end of file
+91dbdf47a13d5bb85934a3a165a42a22220e372f
\ No newline at end of file
diff --git a/ios/net/url_scheme_util_unittest.mm b/ios/net/url_scheme_util_unittest.mm
index 9f1c45b..3898f4f 100644
--- a/ios/net/url_scheme_util_unittest.mm
+++ b/ios/net/url_scheme_util_unittest.mm
@@ -6,7 +6,7 @@
 
 #import <Foundation/Foundation.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 #include "url/gurl.h"
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h
index 2688064..a1ddcd8 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.h
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include "base/compiler_specific.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
 
@@ -51,10 +52,12 @@
 class SigninErrorProvider;
 class SigninResourcesProvider;
 
-// Setter and getter for the provider. The provider should be set early, before
-// any browser code is called.
-void SetChromeBrowserProvider(ChromeBrowserProvider* provider);
-ChromeBrowserProvider* GetChromeBrowserProvider();
+// Getter and setter for the provider. The provider should be set early, before
+// any browser code is called (as the getter will fail if the provider has not
+// been set).
+ChromeBrowserProvider& GetChromeBrowserProvider();
+ChromeBrowserProvider* SetChromeBrowserProvider(ChromeBrowserProvider* provider)
+    WARN_UNUSED_RESULT;
 
 // Factory function for the embedder specific provider. This function must be
 // implemented by the embedder and will be selected via linking (i.e. by the
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.mm b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
index c508d35f..7bcb932 100644
--- a/ios/public/provider/chrome/browser/chrome_browser_provider.mm
+++ b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
@@ -6,6 +6,7 @@
 
 #include <cstddef>
 
+#include "base/check.h"
 #include "components/metrics/metrics_provider.h"
 #import "ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h"
 #import "ios/public/provider/chrome/browser/modals/modals_provider.h"
@@ -22,12 +23,17 @@
 ChromeBrowserProvider* g_chrome_browser_provider = nullptr;
 }  // namespace
 
-void SetChromeBrowserProvider(ChromeBrowserProvider* provider) {
+ChromeBrowserProvider* SetChromeBrowserProvider(
+    ChromeBrowserProvider* provider) {
+  ChromeBrowserProvider* previous = g_chrome_browser_provider;
   g_chrome_browser_provider = provider;
+  return previous;
 }
 
-ChromeBrowserProvider* GetChromeBrowserProvider() {
-  return g_chrome_browser_provider;
+ChromeBrowserProvider& GetChromeBrowserProvider() {
+  DCHECK(g_chrome_browser_provider)
+      << "Calling GetChromeBrowserProvider() before SetChromeBrowserProvider()";
+  return *g_chrome_browser_provider;
 }
 
 // A dummy implementation of ChromeBrowserProvider.
diff --git a/ios/public/provider/chrome/browser/discover_feed/discover_feed_observer_bridge.mm b/ios/public/provider/chrome/browser/discover_feed/discover_feed_observer_bridge.mm
index 8fc34da2..76daa81 100644
--- a/ios/public/provider/chrome/browser/discover_feed/discover_feed_observer_bridge.mm
+++ b/ios/public/provider/chrome/browser/discover_feed/discover_feed_observer_bridge.mm
@@ -14,7 +14,7 @@
     id<DiscoverFeedObserverBridgeDelegate> observer)
     : observer_(observer) {
   scoped_observation_.Observe(
-      ios::GetChromeBrowserProvider()->GetDiscoverFeedProvider());
+      ios::GetChromeBrowserProvider().GetDiscoverFeedProvider());
 }
 
 DiscoverFeedObserverBridge::~DiscoverFeedObserverBridge() {}
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
index 2b0272a..33cb6e7 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager.mm
@@ -176,7 +176,7 @@
 
 - (NSError*)canceledError {
   ios::SigninErrorProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSigninErrorProvider();
+      ios::GetChromeBrowserProvider().GetSigninErrorProvider();
   return [NSError errorWithDomain:provider->GetSigninErrorDomain()
                              code:provider->GetCode(ios::SigninError::CANCELED)
                          userInfo:nil];
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm
index f0f5faa1..42e71b58 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.mm
@@ -28,7 +28,7 @@
 
 UIImage* FakeGetCachedAvatarForIdentity(ChromeIdentity*) {
   ios::SigninResourcesProvider* provider =
-      ios::GetChromeBrowserProvider()->GetSigninResourcesProvider();
+      ios::GetChromeBrowserProvider().GetSigninResourcesProvider();
   return provider ? provider->GetDefaultAvatar() : nil;
 }
 
@@ -138,7 +138,7 @@
 FakeChromeIdentityService*
 FakeChromeIdentityService::GetInstanceFromChromeProvider() {
   return static_cast<ios::FakeChromeIdentityService*>(
-      ios::GetChromeBrowserProvider()->GetChromeIdentityService());
+      ios::GetChromeBrowserProvider().GetChromeIdentityService());
 }
 
 DismissASMViewControllerBlock
diff --git a/ios/public/provider/chrome/browser/signin/fake_chrome_trusted_vault_service.mm b/ios/public/provider/chrome/browser/signin/fake_chrome_trusted_vault_service.mm
index 8d172e3..ae4e89d 100644
--- a/ios/public/provider/chrome/browser/signin/fake_chrome_trusted_vault_service.mm
+++ b/ios/public/provider/chrome/browser/signin/fake_chrome_trusted_vault_service.mm
@@ -50,7 +50,7 @@
 FakeChromeTrustedVaultService*
 FakeChromeTrustedVaultService::GetInstanceFromChromeProvider() {
   return static_cast<ios::FakeChromeTrustedVaultService*>(
-      ios::GetChromeBrowserProvider()->GetChromeTrustedVaultService());
+      ios::GetChromeBrowserProvider().GetChromeTrustedVaultService());
 }
 
 void FakeChromeTrustedVaultService::FetchKeys(
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
index 99fb312..0ecb7f8 100644
--- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
+++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
@@ -21,7 +21,7 @@
       delete;
 
   // Returns the current provider as a |TestChromeBrowserProvider|.
-  static TestChromeBrowserProvider* GetTestProvider();
+  static TestChromeBrowserProvider& GetTestProvider();
 
   // ChromeBrowserProvider:
   SigninResourcesProvider* GetSigninResourcesProvider() override;
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
index 8db807d..6db70d7 100644
--- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
+++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
@@ -47,10 +47,9 @@
 TestChromeBrowserProvider::~TestChromeBrowserProvider() {}
 
 // static
-TestChromeBrowserProvider* TestChromeBrowserProvider::GetTestProvider() {
-  ChromeBrowserProvider* provider = GetChromeBrowserProvider();
-  DCHECK(provider);
-  return static_cast<TestChromeBrowserProvider*>(provider);
+TestChromeBrowserProvider& TestChromeBrowserProvider::GetTestProvider() {
+  ChromeBrowserProvider& provider = GetChromeBrowserProvider();
+  return static_cast<TestChromeBrowserProvider&>(provider);
 }
 
 SigninResourcesProvider*
diff --git a/ios/public/provider/chrome/browser/test_chrome_provider_initializer.mm b/ios/public/provider/chrome/browser/test_chrome_provider_initializer.mm
index 1d7c4686..3c5bf29b 100644
--- a/ios/public/provider/chrome/browser/test_chrome_provider_initializer.mm
+++ b/ios/public/provider/chrome/browser/test_chrome_provider_initializer.mm
@@ -15,12 +15,15 @@
 
 TestChromeProviderInitializer::TestChromeProviderInitializer() {
   chrome_browser_provider_.reset(new TestChromeBrowserProvider());
-  ios::SetChromeBrowserProvider(chrome_browser_provider_.get());
+  ChromeBrowserProvider* previous_provider =
+      ios::SetChromeBrowserProvider(chrome_browser_provider_.get());
+  EXPECT_FALSE(previous_provider);
 }
 
 TestChromeProviderInitializer::~TestChromeProviderInitializer() {
-  EXPECT_EQ(chrome_browser_provider_.get(), ios::GetChromeBrowserProvider());
-  ios::SetChromeBrowserProvider(nullptr);
+  ChromeBrowserProvider* previous_provider =
+      ios::SetChromeBrowserProvider(nullptr);
+  EXPECT_EQ(previous_provider, chrome_browser_provider_.get());
 }
 
 }  // namespace ios
diff --git a/ios/showcase/core/showcase_view_controller.mm b/ios/showcase/core/showcase_view_controller.mm
index 3e452c4..063ea03 100644
--- a/ios/showcase/core/showcase_view_controller.mm
+++ b/ios/showcase/core/showcase_view_controller.mm
@@ -67,7 +67,12 @@
   self.searchController.searchResultsUpdater = self;
   self.searchController.obscuresBackgroundDuringPresentation = NO;
   self.tableView.tableHeaderView = self.searchController.searchBar;
-  self.navigationController.navigationBar.translucent = NO;
+
+  UINavigationBarAppearance* appearance =
+      [[UINavigationBarAppearance alloc] init];
+  [appearance configureWithOpaqueBackground];
+  self.navigationController.navigationBar.standardAppearance = appearance;
+  self.navigationController.navigationBar.scrollEdgeAppearance = appearance;
 
   // Presentation of searchController will walk up the view controller hierarchy
   // until it finds the root view controller or one that defines a presentation
diff --git a/ios/web/common/referrer_util_unittest.cc b/ios/web/common/referrer_util_unittest.cc
index 5cdb881..9d0dc979 100644
--- a/ios/web/common/referrer_util_unittest.cc
+++ b/ios/web/common/referrer_util_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "ios/web/common/referrer_util.h"
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "ios/web/public/navigation/referrer.h"
 #include "net/url_request/referrer_policy.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/web/history_state_util_unittest.mm b/ios/web/history_state_util_unittest.mm
index cdb4642..c117f50e 100644
--- a/ios/web/history_state_util_unittest.mm
+++ b/ios/web/history_state_util_unittest.mm
@@ -6,7 +6,7 @@
 
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
diff --git a/ios/web/navigation/nscoder_util_unittest.mm b/ios/web/navigation/nscoder_util_unittest.mm
index 71e2b99..a0cf35ed 100644
--- a/ios/web/navigation/nscoder_util_unittest.mm
+++ b/ios/web/navigation/nscoder_util_unittest.mm
@@ -5,7 +5,7 @@
 #import <Foundation/Foundation.h>
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #import "ios/web/navigation/nscoder_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/ios/web/web_state/js/common_js_unittest.mm b/ios/web/web_state/js/common_js_unittest.mm
index 47c39b7..ab18f3d 100644
--- a/ios/web/web_state/js/common_js_unittest.mm
+++ b/ios/web/web_state/js/common_js_unittest.mm
@@ -5,7 +5,7 @@
 #include <stddef.h>
 #import <Foundation/Foundation.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #import "ios/web/public/test/web_test_with_web_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm
index 3e2e3f71..86f40e8 100644
--- a/ios/web/webui/url_data_manager_ios_backend.mm
+++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -9,12 +9,12 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/task/post_task.h"
 #include "base/trace_event/trace_event.h"
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 6ff7613..d4764b09 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -106,10 +106,8 @@
       break;
     }
     case base::Value::Type::DOUBLE: {
-      double val;
-      result = value->GetAsDouble(&val);
-      DCHECK(result);
-      WriteParam(m, val);
+      DCHECK(value->is_int() || value->is_double());
+      WriteParam(m, value->GetDouble());
       break;
     }
     case base::Value::Type::STRING: {
diff --git a/ipc/message_filter_router.cc b/ipc/message_filter_router.cc
index c7e102a..8e2b0ca 100644
--- a/ipc/message_filter_router.cc
+++ b/ipc/message_filter_router.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_message_start.h"
 #include "ipc/ipc_message_utils.h"
diff --git a/ipc/sync_socket_unittest.cc b/ipc/sync_socket_unittest.cc
index fbe0959..e1521f4 100644
--- a/ipc/sync_socket_unittest.cc
+++ b/ipc/sync_socket_unittest.cc
@@ -11,10 +11,10 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/threading/thread.h"
 #include "build/build_config.h"
 #include "ipc/ipc_test_base.h"
diff --git a/jingle/glue/fake_ssl_client_socket.cc b/jingle/glue/fake_ssl_client_socket.cc
index 2afb2e1..6eb7c66 100644
--- a/jingle/glue/fake_ssl_client_socket.cc
+++ b/jingle/glue/fake_ssl_client_socket.cc
@@ -12,8 +12,8 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 
diff --git a/jingle/glue/fake_ssl_client_socket_unittest.cc b/jingle/glue/fake_ssl_client_socket_unittest.cc
index 8084a9f..0760b5c 100644
--- a/jingle/glue/fake_ssl_client_socket_unittest.cc
+++ b/jingle/glue/fake_ssl_client_socket_unittest.cc
@@ -12,8 +12,8 @@
 #include <utility>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
-#include "base/stl_util.h"
 #include "base/test/task_environment.h"
 #include "net/base/completion_once_callback.h"
 #include "net/base/completion_repeating_callback.h"
diff --git a/jingle/glue/network_service_async_socket_unittest.cc b/jingle/glue/network_service_async_socket_unittest.cc
index 31ae27f..4cae011 100644
--- a/jingle/glue/network_service_async_socket_unittest.cc
+++ b/jingle/glue/network_service_async_socket_unittest.cc
@@ -13,11 +13,11 @@
 #include "base/bind.h"
 #include "base/check_op.h"
 #include "base/containers/circular_deque.h"
+#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_pump_default.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/gtest_util.h"
diff --git a/jingle/glue/thread_wrapper.cc b/jingle/glue/thread_wrapper.cc
index 134a0e54..b7c645a 100644
--- a/jingle/glue/thread_wrapper.cc
+++ b/jingle/glue/thread_wrapper.cc
@@ -10,9 +10,9 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/sequence_checker.h"
-#include "base/stl_util.h"
 #include "base/thread_annotations.h"
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/jingle/notifier/base/weak_xmpp_client_unittest.cc b/jingle/notifier/base/weak_xmpp_client_unittest.cc
index 376cd23..b487f0c 100644
--- a/jingle/notifier/base/weak_xmpp_client_unittest.cc
+++ b/jingle/notifier/base/weak_xmpp_client_unittest.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
 #include "base/test/task_environment.h"
 #include "jingle/glue/task_pump.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
index 4d1466b..2b1f745 100644
--- a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
+++ b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
@@ -429,7 +429,8 @@
 
                 // The following chipsets have been confirmed by MediaTek to work on P+
                 return Build.HARDWARE.startsWith("mt5599") || Build.HARDWARE.startsWith("mt5895")
-                        || Build.HARDWARE.startsWith("m7332");
+                        || Build.HARDWARE.startsWith("m7332")
+                        || Build.HARDWARE.startsWith("mt8768");
             }
         } else if (mime.equals(MimeTypes.VIDEO_VP9)) {
             // Nexus Player VP9 decoder performs poorly at >= 1080p resolution.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 8fc16e1..0cf94eed 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -316,8 +316,8 @@
     "MemoryPressureBasedSourceBufferGC", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enable binding multiple shared images to a single GpuMemoryBuffer.
-const base::Feature kMultiPlaneSharedImageVideo{
-    "MultiPlaneVideoSharedImages", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kMultiPlaneVideoSharedImages {
+  "MultiPlaneVideoSharedImages", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Approach original pre-REC MSE object URL autorevoking behavior, though await
 // actual attempt to use the object URL for attachment to perform revocation.
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 85047ed..0f24d2b6 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -162,7 +162,7 @@
 MEDIA_EXPORT extern const base::Feature kMediaPowerExperiment;
 MEDIA_EXPORT extern const base::Feature kMediaSessionWebRTC;
 MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC;
-MEDIA_EXPORT extern const base::Feature kMultiPlaneSharedImageVideo;
+MEDIA_EXPORT extern const base::Feature kMultiPlaneVideoSharedImages;
 MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo;
 MEDIA_EXPORT extern const base::Feature kPictureInPicture;
 MEDIA_EXPORT extern const base::Feature kPlaybackSpeedButton;
diff --git a/media/base/overlay_info.cc b/media/base/overlay_info.cc
index 2f67aae..5f6e833 100644
--- a/media/base/overlay_info.cc
+++ b/media/base/overlay_info.cc
@@ -8,6 +8,7 @@
 
 OverlayInfo::OverlayInfo() = default;
 OverlayInfo::OverlayInfo(const OverlayInfo&) = default;
+OverlayInfo& OverlayInfo::operator=(const OverlayInfo&) = default;
 
 bool OverlayInfo::HasValidRoutingToken() const {
   return routing_token.has_value();
diff --git a/media/base/overlay_info.h b/media/base/overlay_info.h
index f0f1e64..046e4d83 100644
--- a/media/base/overlay_info.h
+++ b/media/base/overlay_info.h
@@ -20,6 +20,7 @@
 
   OverlayInfo();
   OverlayInfo(const OverlayInfo&);
+  OverlayInfo& operator=(const OverlayInfo&);
 
   // Convenience functions to return true if and only if this specifies a
   // surface ID / routing token that is not kNoSurfaceID / empty.  I.e., if we
diff --git a/media/base/text_track_config.cc b/media/base/text_track_config.cc
index bede52a..a736883b 100644
--- a/media/base/text_track_config.cc
+++ b/media/base/text_track_config.cc
@@ -20,7 +20,9 @@
       id_(id) {
 }
 
-TextTrackConfig::TextTrackConfig(const TextTrackConfig& other) = default;
+TextTrackConfig::TextTrackConfig(const TextTrackConfig&) = default;
+
+TextTrackConfig& TextTrackConfig::operator=(const TextTrackConfig&) = default;
 
 bool TextTrackConfig::Matches(const TextTrackConfig& config) const {
   return config.kind() == kind_ &&
diff --git a/media/base/text_track_config.h b/media/base/text_track_config.h
index e692037..07f604d 100644
--- a/media/base/text_track_config.h
+++ b/media/base/text_track_config.h
@@ -25,6 +25,7 @@
  public:
   TextTrackConfig();
   TextTrackConfig(const TextTrackConfig& other);
+  TextTrackConfig& operator=(const TextTrackConfig& other);
   TextTrackConfig(TextKind kind,
                   const std::string& label,
                   const std::string& language,
diff --git a/media/capabilities/video_decode_stats_db.cc b/media/capabilities/video_decode_stats_db.cc
index 954b8008..b435618 100644
--- a/media/capabilities/video_decode_stats_db.cc
+++ b/media/capabilities/video_decode_stats_db.cc
@@ -76,10 +76,11 @@
 }
 
 VideoDecodeStatsDB::DecodeStatsEntry::DecodeStatsEntry(
-    const DecodeStatsEntry& entry)
-    : frames_decoded(entry.frames_decoded),
-      frames_dropped(entry.frames_dropped),
-      frames_power_efficient(entry.frames_power_efficient) {}
+    const DecodeStatsEntry& entry) = default;
+
+VideoDecodeStatsDB::DecodeStatsEntry&
+VideoDecodeStatsDB::DecodeStatsEntry::operator=(const DecodeStatsEntry& entry) =
+    default;
 
 std::string VideoDecodeStatsDB::DecodeStatsEntry::ToLogString() const {
   return base::StringPrintf(
diff --git a/media/capabilities/video_decode_stats_db.h b/media/capabilities/video_decode_stats_db.h
index 128214a9..aa5299ad 100644
--- a/media/capabilities/video_decode_stats_db.h
+++ b/media/capabilities/video_decode_stats_db.h
@@ -59,6 +59,7 @@
                      uint64_t frames_dropped,
                      uint64_t frames_power_efficient);
     DecodeStatsEntry(const DecodeStatsEntry& entry);
+    DecodeStatsEntry& operator=(const DecodeStatsEntry& entry);
 
     // Add stats from |right| to |this| entry.
     DecodeStatsEntry& operator+=(const DecodeStatsEntry& right);
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc
index d05e9c1..3c253f1 100644
--- a/media/capture/video/chromeos/request_manager.cc
+++ b/media/capture/video/chromeos/request_manager.cc
@@ -549,11 +549,22 @@
 
 bool RequestManager::TryPrepareRecordingRequest(
     std::set<StreamType>* stream_types) {
-  if (!stream_buffer_manager_->IsRecordingSupported() ||
-      !stream_buffer_manager_->HasFreeBuffers({StreamType::kRecordingOutput})) {
+  if (!stream_buffer_manager_->IsRecordingSupported()) {
     return false;
   }
 
+  if (!stream_buffer_manager_->HasFreeBuffers({StreamType::kRecordingOutput})) {
+    // Try our best to reserve an usable buffer.  If the reservation still
+    // fails, then we'd have to drop the camera frame.
+    DLOG(WARNING) << "Late request for reserving recording buffer";
+    stream_buffer_manager_->ReserveBuffer(StreamType::kRecordingOutput);
+    if (!stream_buffer_manager_->HasFreeBuffers(
+            {StreamType::kRecordingOutput})) {
+      DLOG(WARNING) << "No free buffer for recording stream";
+      return false;
+    }
+  }
+
   stream_types->insert({StreamType::kRecordingOutput});
   return true;
 }
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.h b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
index 68ee39a..c7418bf 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.h
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
@@ -95,6 +95,8 @@
   // Protects concurrent setting and using |frameReceiver_|. Note that the
   // GUARDED_BY decoration below does not have any effect.
   base::Lock _lock;
+  // Used to avoid UAF in -captureOutput.
+  base::Lock _destructionLock;
   media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver
       GUARDED_BY(_lock);  // weak.
   bool _capturedFirstFrame GUARDED_BY(_lock);
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index e062332d..81f81e30c 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -184,12 +184,26 @@
 }
 
 - (void)dealloc {
-  [self stopStillImageOutput];
-  [self stopCapture];
-  _sampleBufferTransformer.reset();
-  _weakPtrFactoryForTakePhoto = nullptr;
-  _mainThreadTaskRunner = nullptr;
-  _sampleQueue.reset();
+  {
+    // To avoid races with concurrent callbacks, grab the lock before stopping
+    // capture and clearing all the variables.
+    base::AutoLock lock(_lock);
+    [self stopStillImageOutput];
+    [self stopCapture];
+    _frameReceiver = nullptr;
+    _sampleBufferTransformer.reset();
+    _weakPtrFactoryForTakePhoto = nullptr;
+    _mainThreadTaskRunner = nullptr;
+    _sampleQueue.reset();
+  }
+  {
+    // Ensures -captureOutput has finished before we continue the destruction
+    // steps. If -captureOutput grabbed the destruction lock before us this
+    // prevents UAF. If -captureOutput grabbed the destruction lock after us
+    // it will exit early because |_frameReceiver| is already null at this
+    // point.
+    base::AutoLock destructionLock(_destructionLock);
+  }
   [super dealloc];
 }
 
@@ -887,7 +901,9 @@
   VLOG(3) << __func__;
 
   // Concurrent calls into |_frameReceiver| are not supported, so take |_lock|
-  // before any of the subsequent paths.
+  // before any of the subsequent paths. The |_destructionLock| must be grabbed
+  // first to avoid races with -dealloc.
+  base::AutoLock destructionLock(_destructionLock);
   base::AutoLock lock(_lock);
   _capturedFrameSinceLastStallCheck = YES;
   if (!_frameReceiver)
diff --git a/media/capture/video/mac/video_capture_device_factory_mac.mm b/media/capture/video/mac/video_capture_device_factory_mac.mm
index 882f947..28b6f40 100644
--- a/media/capture/video/mac/video_capture_device_factory_mac.mm
+++ b/media/capture/video/mac/video_capture_device_factory_mac.mm
@@ -11,9 +11,9 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/task_runner_util.h"
diff --git a/media/cdm/cdm_paths_unittest.cc b/media/cdm/cdm_paths_unittest.cc
index 1cc84ce..c9fce43 100644
--- a/media/cdm/cdm_paths_unittest.cc
+++ b/media/cdm/cdm_paths_unittest.cc
@@ -37,9 +37,9 @@
     "mac";
 #elif defined(OS_WIN)
     "win";
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
+#elif defined(OS_CHROMEOS)
     "cros";
-#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#elif defined(OS_LINUX)
     "linux";
 #else
     "unsupported_platform";
diff --git a/media/cdm/library_cdm/cdm_paths.gni b/media/cdm/library_cdm/cdm_paths.gni
index 21fd5f6..8306412 100644
--- a/media/cdm/library_cdm/cdm_paths.gni
+++ b/media/cdm/library_cdm/cdm_paths.gni
@@ -11,9 +11,9 @@
 
 # OS name for components is close to "target_os" but has some differences.
 # Explicitly define what we use to avoid confusion.
-if (is_chromeos_ash) {
+if (is_chromeos) {
   component_os = "cros"
-} else if (is_linux || is_chromeos_lacros) {
+} else if (is_linux) {
   component_os = "linux"
 } else if (is_win) {
   component_os = "win"
diff --git a/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc b/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
index 045042e..1f61bc74 100644
--- a/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
+++ b/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
@@ -117,7 +117,7 @@
   test_parameters_.profile = FF_PROFILE_AAC_HE;
   FFmpegAACBitstreamConverter converter_he(&test_parameters_);
 
-  test_packet.reset(new AVPacket());
+  test_packet.reset(av_packet_alloc());
   CreatePacket(test_packet.get(), dummy_packet,
                sizeof(dummy_packet));
 
@@ -130,7 +130,7 @@
   test_parameters_.profile = FF_PROFILE_AAC_ELD;
   FFmpegAACBitstreamConverter converter_eld(&test_parameters_);
 
-  test_packet.reset(new AVPacket());
+  test_packet.reset(av_packet_alloc());
   CreatePacket(test_packet.get(), dummy_packet,
                sizeof(dummy_packet));
 
diff --git a/media/gpu/chromeos/image_processor_factory.cc b/media/gpu/chromeos/image_processor_factory.cc
index e3b664c..c39717fa 100644
--- a/media/gpu/chromeos/image_processor_factory.cc
+++ b/media/gpu/chromeos/image_processor_factory.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/containers/contains.h"
 #include "base/memory/scoped_refptr.h"
 #include "media/base/video_types.h"
 #include "media/gpu/buildflags.h"
@@ -41,12 +42,8 @@
   std::vector<Fourcc> supported_fourccs;
   for (const auto& format : supported_output_formats) {
     const auto fourcc = Fourcc::FromV4L2PixFmt(format);
-    if (!fourcc) {
-      VLOGF(1) << "unsupported image processor format "
-               << FourccToString(format) << ", skipping...";
-      continue;
-    }
-    supported_fourccs.push_back(*fourcc);
+    if (fourcc.has_value())
+      supported_fourccs.push_back(*fourcc);
   }
 
   const auto output_fourcc = out_format_picker.Run(supported_fourccs);
@@ -59,14 +56,11 @@
     const Fourcc input_fourcc = input_candidate.first;
     const gfx::Size& input_size = input_candidate.second;
 
-    if (std::find(supported_input_pixfmts.begin(),
-                  supported_input_pixfmts.end(), input_fourcc.ToV4L2PixFmt()) ==
-        supported_input_pixfmts.end()) {
+    if (!base::Contains(supported_input_pixfmts, input_fourcc.ToV4L2PixFmt()))
       continue;
-    }
 
     // Try to get an image size as close as possible to the final size.
-    gfx::Size output_size(visible_size.width(), visible_size.height());
+    gfx::Size output_size = visible_size;
     size_t num_planes = 0;
     if (!V4L2ImageProcessorBackend::TryOutputFormat(
             input_fourcc.ToV4L2PixFmt(), output_fourcc->ToV4L2PixFmt(),
diff --git a/media/gpu/chromeos/mailbox_video_frame_converter.cc b/media/gpu/chromeos/mailbox_video_frame_converter.cc
index afa3bf56..6da0229 100644
--- a/media/gpu/chromeos/mailbox_video_frame_converter.cc
+++ b/media/gpu/chromeos/mailbox_video_frame_converter.cc
@@ -85,8 +85,9 @@
     UnwrapFrameCB unwrap_frame_cb,
     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
     GetCommandBufferStubCB get_stub_cb) {
-  if (!unwrap_frame_cb || !gpu_task_runner || !get_stub_cb)
-    return nullptr;
+  DCHECK(unwrap_frame_cb);
+  DCHECK(gpu_task_runner);
+  DCHECK(get_stub_cb);
 
   auto get_gpu_channel_cb = base::BindRepeating(
       [](base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb) {
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index edc77a7..72b44cf7 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/containers/contains.h"
 #include "base/memory/ptr_util.h"
 #include "base/sequenced_task_runner.h"
 #include "base/task/post_task.h"
@@ -31,28 +32,19 @@
 // number of frames in media::Pipeline plus the current processing frame.
 constexpr size_t kNumFramesForImageProcessor = limits::kMaxVideoFrames + 1;
 
-// Pick a compositor renderable format from |candidates|.
-// Return zero if not found.
-absl::optional<Fourcc> PickRenderableFourcc(
-    const std::vector<Fourcc>& candidates) {
-  // Hardcode compositor renderable format now.
-  // TODO: figure out a way to pick the best one dynamically.
-  // Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports
-  // single physical plane.
-  constexpr Fourcc::Value kPreferredFourccValues[] = {
-#if defined(ARCH_CPU_ARM_FAMILY)
+// Preferred output formats in order of preference.
+// TODO(mcasas): query the platform for its preferred formats and modifiers.
+constexpr Fourcc::Value kPreferredRenderableFourccs[] = {
     Fourcc::NV12,
     Fourcc::YV12,
-#endif
-    // For kepler.
-    Fourcc::AR24,
-  };
+};
 
-  for (const auto& value : kPreferredFourccValues) {
-    if (std::find(candidates.begin(), candidates.end(), Fourcc(value)) !=
-        candidates.end()) {
+// Picks the preferred compositor renderable format from |candidates|, if any.
+absl::optional<Fourcc> PickRenderableFourcc(
+    const std::vector<Fourcc>& candidates) {
+  for (const auto value : kPreferredRenderableFourccs) {
+    if (base::Contains(candidates, Fourcc(value)))
       return Fourcc(value);
-    }
   }
   return absl::nullopt;
 }
@@ -77,16 +69,15 @@
     std::unique_ptr<VideoFrameConverter> frame_converter,
     std::unique_ptr<MediaLog> /*media_log*/,
     CreateDecoderFunctionCB create_decoder_function_cb) {
-  if (!client_task_runner || !frame_pool || !frame_converter) {
-    VLOGF(1) << "One of arguments is nullptr.";
-    return nullptr;
-  }
+  DCHECK(client_task_runner);
+  DCHECK(frame_pool);
+  DCHECK(frame_converter);
 
-  auto* decoder = new VideoDecoderPipeline(
+  auto* pipeline = new VideoDecoderPipeline(
       std::move(client_task_runner), std::move(frame_pool),
       std::move(frame_converter), std::move(create_decoder_function_cb));
   return std::make_unique<AsyncDestroyVideoDecoder<VideoDecoderPipeline>>(
-      base::WrapUnique(decoder));
+      base::WrapUnique(pipeline));
 }
 
 VideoDecoderPipeline::VideoDecoderPipeline(
@@ -134,14 +125,15 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
+// static
 void VideoDecoderPipeline::DestroyAsync(
-    std::unique_ptr<VideoDecoderPipeline> decoder) {
+    std::unique_ptr<VideoDecoderPipeline> pipeline) {
   DVLOGF(2);
-  DCHECK(decoder);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(decoder->client_sequence_checker_);
+  DCHECK(pipeline);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(pipeline->client_sequence_checker_);
 
-  auto* decoder_task_runner = decoder->decoder_task_runner_.get();
-  decoder_task_runner->DeleteSoon(FROM_HERE, std::move(decoder));
+  auto* decoder_task_runner = pipeline->decoder_task_runner_.get();
+  decoder_task_runner->DeleteSoon(FROM_HERE, std::move(pipeline));
 }
 
 VideoDecoderType VideoDecoderPipeline::GetDecoderType() const {
@@ -265,9 +257,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
   DVLOGF(4) << "Initialization status = " << status.code();
 
-  if (!status.is_ok()) {
+  if (!status.is_ok())
     decoder_ = nullptr;
-  }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   if (decoder_ && decoder_->NeedsTranscryption()) {
@@ -526,18 +517,12 @@
 
   image_processor_.reset();
 
-  // Check if any candidate format is renderable without the need of
-  // ImageProcessor.
-  std::vector<Fourcc> fourccs;
-  for (const auto& candidate : candidates)
-    fourccs.push_back(candidate.first);
-  const auto renderable_fourcc = PickRenderableFourcc(fourccs);
-  if (renderable_fourcc) {
-    for (const auto& candidate : candidates)
-      if (candidate.first == renderable_fourcc)
+  // Check if any of the |candidates| formats is directly renderable.
+  for (const auto preferred_fourcc : kPreferredRenderableFourccs) {
+    for (const auto& candidate : candidates) {
+      if (candidate.first == Fourcc(preferred_fourcc))
         return candidate;
-    DVLOGF(2) << "Renderable Fourcc not in candidates list. This is a bug.";
-    return absl::nullopt;
+    }
   }
 
   std::unique_ptr<ImageProcessor> image_processor =
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
index 874ad00..89af4d97 100644
--- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -530,4 +530,45 @@
   task_environment_.RunUntilIdle();
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+// Verifies the algorithm for choosing formats in PickDecoderOutputFormat works
+// as expected.
+TEST_F(VideoDecoderPipelineTest, PickDecoderOutputFormat) {
+  constexpr gfx::Size kSize(320, 240);
+  constexpr gfx::Rect kVisibleRect(320, 240);
+
+  const struct {
+    std::vector<std::pair<Fourcc, gfx::Size>> input_candidates;
+    std::pair<Fourcc, gfx::Size> expected_chosen_candidate;
+  } test_vectors[] = {
+      // Easy cases: one candidate that is supported, should be chosen.
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize)},
+      // Two candidates, both supported: pick as per implementation.
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize),
+        std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize),
+        std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+      // Two candidates, only one supported, the supported one should be picked.
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::P010, kSize),
+        std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::NV12, kSize)},
+      {{std::pair<Fourcc, gfx::Size>(Fourcc::P010, kSize),
+        std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize)},
+       std::pair<Fourcc, gfx::Size>(Fourcc::YV12, kSize)}};
+
+  for (const auto& test_vector : test_vectors) {
+    const auto chosen_candidate = decoder_->PickDecoderOutputFormat(
+        test_vector.input_candidates, kVisibleRect);
+    EXPECT_EQ(test_vector.expected_chosen_candidate, chosen_candidate)
+        << " expected: "
+        << test_vector.expected_chosen_candidate.first.ToString()
+        << ", actual: " << chosen_candidate->first.ToString();
+  }
+}
+
 }  // namespace media
diff --git a/media/gpu/test/video_encoder/decoder_buffer_validator.cc b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
index 4e866f3b..14551448 100644
--- a/media/gpu/test/video_encoder/decoder_buffer_validator.cc
+++ b/media/gpu/test/video_encoder/decoder_buffer_validator.cc
@@ -4,6 +4,9 @@
 
 #include "media/gpu/test/video_encoder/decoder_buffer_validator.h"
 
+#include <set>
+
+#include "base/containers/contains.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/logging.h"
 #include "media/base/decoder_buffer.h"
@@ -328,7 +331,8 @@
       return false;
     }
 
-    new_buffer_state.picture_id = next_picture_id_ = 0;
+    new_buffer_state.picture_id = 0;
+    next_picture_id_ = 1;
   } else if (header.show_existing_frame) {
     if (!reference_buffers_[header.frame_to_show_map_idx]) {
       LOG(ERROR) << "Attempting to show an existing frame, but the selected "
@@ -361,12 +365,23 @@
     }
   } else {
     std::vector<int> expected_pdiffs;
+    std::set<uint8_t> used_indices;
     for (uint8_t ref_frame_index : header.ref_frame_idx) {
       if (ref_frame_index >= static_cast<uint8_t>(kVp9NumRefFrames)) {
         LOG(ERROR) << "Invalid reference frame index: "
                    << static_cast<int>(ref_frame_index);
         return false;
       }
+
+      if (base::Contains(used_indices, ref_frame_index)) {
+        // |header.ref_frame_index| might have the same indices because an
+        // encoder fills the same index if the actually used ref frames is less
+        // than |kVp9NumRefsPerFrame|.
+        continue;
+      }
+
+      used_indices.insert(ref_frame_index);
+
       if (!reference_buffers_[ref_frame_index]) {
         LOG(ERROR) << "Frame is trying to reference buffer with invalid state.";
         return false;
diff --git a/media/gpu/vaapi/test_utils.h b/media/gpu/vaapi/test_utils.h
index bee8e5d..1b9cf227 100644
--- a/media/gpu/vaapi/test_utils.h
+++ b/media/gpu/vaapi/test_utils.h
@@ -15,7 +15,7 @@
 // See http://code.google.com/p/googletest/issues/detail?id=371
 #include "testing/gtest/include/gtest/gtest.h"
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace media {
diff --git a/media/gpu/vaapi/vp9_svc_layers.cc b/media/gpu/vaapi/vp9_svc_layers.cc
index 1b44703..99a65036 100644
--- a/media/gpu/vaapi/vp9_svc_layers.cc
+++ b/media/gpu/vaapi/vp9_svc_layers.cc
@@ -34,10 +34,10 @@
       : layer_index_(layer_index), buffer_flags_{first, second} {}
   FrameConfig() = delete;
 
-  // VP9SVCLayers uses 2 reference frames for each spatial layer, and totally
-  // uses up to 6 reference frames. SL0 uses the first two (0, 1) reference
-  // frames, SL1 uses middle two (2, 3) reference frames, and SL2 used last two
-  // (4, 5) reference frames.
+  // VP9SVCLayers uses 2 reference frame slots for each spatial layer, and
+  // totally uses up to 6 reference frame slots. SL0 uses the first two (0, 1)
+  // slots, SL1 uses middle two (2, 3) slots, and SL2 uses last two (4, 5)
+  // slots.
   std::vector<uint8_t> GetRefFrameIndices(size_t spatial_idx,
                                           size_t frame_num) const {
     std::vector<uint8_t> indices;
@@ -79,46 +79,35 @@
 namespace {
 // GetTemporalLayersReferencePattern() constructs the
 // following temporal layers.
-// 2 temporal layers structure: https://imgur.com/vBvHtdp.
-// 3 temporal layers structure: https://imgur.com/pURAGvp.
 std::vector<VP9SVCLayers::FrameConfig> GetTemporalLayersReferencePattern(
     size_t num_temporal_layers) {
   using FrameConfig = VP9SVCLayers::FrameConfig;
-  // In a vp9 software encoder used in libwebrtc, each frame has only one
-  // reference to the TL0 frame. It improves the encoding speed without reducing
-  // the frame quality noticeably. This class, at this moment, lets each frame
-  // have as many references as possible for the sake of better quality,
-  // assuming a hardware encoder is sufficiently fast. TODO(crbug.com/1030199):
-  // Measure speed vs. quality changing these structures.
   switch (num_temporal_layers) {
     case 1:
       // In this case, the number of spatial layers must great than 1.
       // TL0 references and updates the 'first' buffer.
+      // [TL0]---[TL0]
       return {FrameConfig(0, kReferenceAndUpdate, kNone)};
     case 2:
       // TL0 references and updates the 'first' buffer.
-      // TL1 references 'first' and references and updates 'second'.
+      // TL1 references 'first' buffer.
+      //      [TL1]
+      //     /
+      // [TL0]-----[TL0]
       return {FrameConfig(0, kReferenceAndUpdate, kNone),
-              FrameConfig(1, kReference, kUpdate),
-              FrameConfig(0, kReferenceAndUpdate, kNone),
-              FrameConfig(1, kReference, kReferenceAndUpdate),
-              FrameConfig(0, kReferenceAndUpdate, kNone),
-              FrameConfig(1, kReference, kReferenceAndUpdate),
-              FrameConfig(0, kReferenceAndUpdate, kNone),
-              FrameConfig(1, kReference, kReferenceAndUpdate)};
+              FrameConfig(1, kReference, kNone)};
     case 3:
       // TL0 references and updates the 'first' buffer.
-      // TL1 references 'first' and references and updates 'second'.
-      // TL2 references, if there are, both 'first' and 'second' but updates no
-      // buffer.
+      // TL1 references 'first' and updates 'second'.
+      // TL2 references either 'first' or 'second' buffer.
+      //    [TL2]      [TL2]
+      //    _/   [TL1]--/
+      //   /_______/
+      // [TL0]--------------[TL0]
       return {FrameConfig(0, kReferenceAndUpdate, kNone),
               FrameConfig(2, kReference, kNone),
               FrameConfig(1, kReference, kUpdate),
-              FrameConfig(2, kReference, kReference),
-              FrameConfig(0, kReferenceAndUpdate, kNone),
-              FrameConfig(2, kReference, kReference),
-              FrameConfig(1, kReference, kReferenceAndUpdate),
-              FrameConfig(2, kReference, kReference)};
+              FrameConfig(2, kNone, kReference)};
     default:
       NOTREACHED();
       return {};
diff --git a/media/gpu/vaapi/vp9_svc_layers_unittest.cc b/media/gpu/vaapi/vp9_svc_layers_unittest.cc
index 1d3bb0f..aadcd46 100644
--- a/media/gpu/vaapi/vp9_svc_layers_unittest.cc
+++ b/media/gpu/vaapi/vp9_svc_layers_unittest.cc
@@ -143,8 +143,15 @@
 
   // Six slots at most in the reference pool are used in spatial/temporal layer
   // encoding. Additionally, non-keyframe must reference some frames.
+  // |ref_frames_used| must be {true, false, false} because here is,
+  // 1. if the frame is in key picture, it references one lower spatial layer,
+  // 2. otherwise the frame doesn't reference other spatial layers and thus
+  // references only one frame in the same spatial layer based on the current
+  // reference pattern.
+  constexpr std::array<bool, kVp9NumRefsPerFrame> kExpectedRefFramesUsed = {
+      true, false, false};
   EXPECT_EQ(frame_hdr.refresh_frame_flags & ~(0b111111u), 0u);
-  EXPECT_TRUE(base::Contains(ref_frames_used, true));
+  EXPECT_EQ(ref_frames_used, kExpectedRefFramesUsed);
   EXPECT_EQ(metadata.has_reference, !metadata.p_diffs.empty());
   EXPECT_EQ(metadata.has_reference, !key_pic);
   if (key_pic) {
@@ -157,25 +164,21 @@
   }
 
   // Check that the current frame doesn't reference upper layer frames.
-  for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
-    if (!ref_frames_used[i])
-      continue;
-    const uint8_t index = frame_hdr.ref_frame_idx[i];
-    scoped_refptr<VP9Picture> ref_frame = ref_frames.GetFrame(index);
-    ASSERT_TRUE(!!ref_frame);
-    const auto& ref_metadata = ref_frame->metadata_for_encoding;
-    ASSERT_TRUE(ref_metadata.has_value());
-    const size_t ref_temporal_index = ref_metadata->temporal_idx;
-    EXPECT_LE(ref_temporal_index, temporal_index);
-    const uint8_t ref_spatial_index = ref_metadata->spatial_idx;
-    EXPECT_LE(ref_spatial_index, spatial_index);
-    // In key picture, upper spatial layers must refer the lower spatial layer.
-    // Or referenced frames must be in the same spatial layer.
-    if (key_pic)
-      EXPECT_EQ(ref_spatial_index, spatial_index - 1);
-    else
-      EXPECT_EQ(ref_spatial_index, spatial_index);
-  }
+  const uint8_t index = frame_hdr.ref_frame_idx[0];
+  scoped_refptr<VP9Picture> ref_frame = ref_frames.GetFrame(index);
+  ASSERT_TRUE(!!ref_frame);
+  const auto& ref_metadata = ref_frame->metadata_for_encoding;
+  ASSERT_TRUE(ref_metadata.has_value());
+  const size_t ref_temporal_index = ref_metadata->temporal_idx;
+  EXPECT_LE(ref_temporal_index, temporal_index);
+  const uint8_t ref_spatial_index = ref_metadata->spatial_idx;
+  EXPECT_LE(ref_spatial_index, spatial_index);
+  // In key picture, upper spatial layers must refer the lower spatial layer.
+  // Or referenced frames must be in the same spatial layer.
+  if (key_pic)
+    EXPECT_EQ(ref_spatial_index, spatial_index - 1);
+  else
+    EXPECT_EQ(ref_spatial_index, spatial_index);
 }
 
 // This test verifies the bitrate check in MaybeUpdateActiveLayer().
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
index 6f41c4d..c48b67d0 100644
--- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
+++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
@@ -70,6 +70,8 @@
     false, false, false};
 constexpr std::array<bool, kVp9NumRefsPerFrame> kRefFramesUsedForInterFrame = {
     true, true, true};
+constexpr std::array<bool, kVp9NumRefsPerFrame>
+    kRefFramesUsedForInterFrameInTemporalLayer = {true, false, false};
 
 void GetTemporalLayer(bool keyframe,
                       int frame_num,
@@ -80,21 +82,11 @@
   switch (num_temporal_layers) {
     case 1:
       if (num_spatial_layers > 1) {
-        // K-SVC stream.
-        if (keyframe) {
-          *ref_frames_used = keyframe ? kRefFramesUsedForKeyFrame
-                                      : kRefFramesUsedForInterFrame;
-          return;
-        }
-
         *temporal_layer_id = 0;
-        {
-          constexpr std::tuple<uint8_t, std::array<bool, kVp9NumRefsPerFrame>>
-              kOneTemporalLayersDescription[] = {{0, {true, false, false}}};
-          const auto& layer_info = kOneTemporalLayersDescription
-              [frame_num % base::size(kOneTemporalLayersDescription)];
-          std::tie(*temporal_layer_id, *ref_frames_used) = layer_info;
-        }
+        // K-SVC stream.
+        *ref_frames_used = keyframe
+                               ? kRefFramesUsedForKeyFrame
+                               : kRefFramesUsedForInterFrameInTemporalLayer;
       } else {
         // Simple stream.
         *ref_frames_used =
@@ -109,17 +101,10 @@
       }
 
       {
-        // 2 temporal layers structure. See https://imgur.com/vBvHtdp.
-        constexpr std::tuple<uint8_t, std::array<bool, kVp9NumRefsPerFrame>>
-            kTwoTemporalLayersDescription[] = {
-                {0, {true, false, false}}, {1, {true, false, false}},
-                {0, {true, false, false}}, {1, {true, true, false}},
-                {0, {true, false, false}}, {1, {true, true, false}},
-                {0, {true, false, false}}, {1, {true, true, false}},
-            };
-        const auto& layer_info = kTwoTemporalLayersDescription
-            [frame_num % base::size(kTwoTemporalLayersDescription)];
-        std::tie(*temporal_layer_id, *ref_frames_used) = layer_info;
+        constexpr uint8_t kTwoTemporalLayerIds[] = {0, 1};
+        *temporal_layer_id =
+            kTwoTemporalLayerIds[frame_num % base::size(kTwoTemporalLayerIds)];
+        *ref_frames_used = kRefFramesUsedForInterFrameInTemporalLayer;
       }
       break;
     case 3:
@@ -130,17 +115,11 @@
       }
 
       {
-        // 3 temporal layers structure. See https://imgur.com/pURAGvp.
-        constexpr std::tuple<uint8_t, std::array<bool, kVp9NumRefsPerFrame>>
-            kThreeTemporalLayersDescription[] = {
-                {0, {true, false, false}}, {2, {true, false, false}},
-                {1, {true, false, false}}, {2, {true, true, false}},
-                {0, {true, false, false}}, {2, {true, true, false}},
-                {1, {true, true, false}},  {2, {true, true, false}},
-            };
-        const auto& layer_info = kThreeTemporalLayersDescription
-            [frame_num % base::size(kThreeTemporalLayersDescription)];
-        std::tie(*temporal_layer_id, *ref_frames_used) = layer_info;
+        constexpr uint8_t kThreeTemporalLayerIds[] = {0, 2, 1, 2};
+        *temporal_layer_id =
+            kThreeTemporalLayerIds[frame_num %
+                                   base::size(kThreeTemporalLayerIds)];
+        *ref_frames_used = kRefFramesUsedForInterFrameInTemporalLayer;
       }
       break;
   }
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc
index 877673a..c4e6e5fd 100644
--- a/media/gpu/video_encode_accelerator_tests.cc
+++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -153,7 +153,7 @@
     // couldn't compress a low resolution video efficiently with a low bitrate.
     constexpr gfx::Size k360p(640, 360);
     constexpr double kSSIMToleranceForLowerResolution = 0.65;
-    const gfx::Size encode_resolution = video->VisibleRect().size();
+    const gfx::Size encode_resolution = decoder_config.visible_rect().size();
     const double ssim_tolerance =
         encode_resolution.GetArea() < k360p.GetArea()
             ? kSSIMToleranceForLowerResolution
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc
index b911c62..1a2cc64 100644
--- a/media/gpu/windows/d3d11_video_decoder.cc
+++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -910,7 +910,7 @@
     // decode_cb and input_buffer_queue cb's.
     // Let the init handler set the error string if this is an init failure.
     MEDIA_LOG(ERROR, media_log_) << "D3D11VideoDecoder error: 0x" << std::hex
-                                 << reason.code() << reason.message();
+                                 << reason.code() << " " << reason.message();
   }
 
   current_buffer_ = nullptr;
diff --git a/media/mojo/services/media_foundation_renderer_wrapper.cc b/media/mojo/services/media_foundation_renderer_wrapper.cc
index dc5a3ee..9a37a61 100644
--- a/media/mojo/services/media_foundation_renderer_wrapper.cc
+++ b/media/mojo/services/media_foundation_renderer_wrapper.cc
@@ -83,6 +83,7 @@
 }
 
 void MediaFoundationRendererWrapper::SetVolume(float volume) {
+  volume_ = volume;
   renderer_->SetVolume(muted_ ? 0 : volume_);
 }
 
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index b7b45a9..fe2b5b23 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -50,8 +50,8 @@
 
 namespace {
 
-bool MultiPlaneSharedImagesEnabled() {
-  return base::FeatureList::IsEnabled(kMultiPlaneSharedImageVideo);
+bool MultiPlaneVideoSharedImagesEnabled() {
+  return base::FeatureList::IsEnabled(kMultiPlaneVideoSharedImages);
 }
 
 }  // namespace
@@ -366,7 +366,7 @@
 // The number of shared images for a given format. Note that a single
 // GpuMemoryBuffer can be mapped to several SharedImages (one for each plane).
 size_t NumSharedImages(GpuVideoAcceleratorFactories::OutputFormat format) {
-  if (MultiPlaneSharedImagesEnabled()) {
+  if (MultiPlaneVideoSharedImagesEnabled()) {
     if (format == GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB) {
       return 2;
     }
@@ -380,7 +380,7 @@
 size_t GpuMemoryBufferPlaneResourceIndexForPlane(
     GpuVideoAcceleratorFactories::OutputFormat format,
     size_t plane) {
-  if (MultiPlaneSharedImagesEnabled()) {
+  if (MultiPlaneVideoSharedImagesEnabled()) {
     if (format == GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB) {
       return 0;
     }
@@ -393,7 +393,7 @@
 gfx::BufferPlane GetSharedImageBufferPlane(
     GpuVideoAcceleratorFactories::OutputFormat format,
     size_t plane) {
-  if (MultiPlaneSharedImagesEnabled()) {
+  if (MultiPlaneVideoSharedImagesEnabled()) {
     if (format == GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB) {
       switch (plane) {
         case 0:
@@ -1048,11 +1048,15 @@
     FrameResources* frame_resources) {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
   if (copy_failed) {
-    // Drop the resources if there was an error with them.
-    auto it = std::find(resources_pool_.begin(), resources_pool_.end(),
-                        frame_resources);
-    DCHECK(it != resources_pool_.end());
-    resources_pool_.erase(it);
+    // Drop the resources if there was an error with them. If we're not in
+    // shutdown we also need to remove the pool entry for them.
+    if (!in_shutdown_) {
+      auto it = std::find(resources_pool_.begin(), resources_pool_.end(),
+                          frame_resources);
+      DCHECK(it != resources_pool_.end());
+      resources_pool_.erase(it);
+    }
+
     DeleteFrameResources(gpu_factories_, frame_resources);
     delete frame_resources;
 
diff --git a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
index 3dd9536..b925cfa 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool_unittest.cc
@@ -515,6 +515,21 @@
   EXPECT_EQ(0u, sii_->shared_image_count());
 }
 
+TEST_F(GpuMemoryBufferVideoFramePoolTest,
+       CreateGpuMemoryBufferFailAfterShutdown) {
+  scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
+  scoped_refptr<VideoFrame> frame;
+  mock_gpu_factories_->SetFailToMapGpuMemoryBufferForTesting(true);
+  gpu_memory_buffer_pool_->MaybeCreateHardwareFrame(
+      software_frame, base::BindOnce(MaybeCreateHardwareFrameCallback, &frame));
+  gpu_memory_buffer_pool_.reset();
+  RunUntilIdle();
+
+  // Software frame should be returned if mapping fails.
+  EXPECT_EQ(software_frame.get(), frame.get());
+  EXPECT_EQ(0u, sii_->shared_image_count());
+}
+
 TEST_F(GpuMemoryBufferVideoFramePoolTest, ShutdownReleasesUnusedResources) {
   scoped_refptr<VideoFrame> software_frame = CreateTestYUVVideoFrame(10);
   scoped_refptr<VideoFrame> frame_1;
diff --git a/media/video/mock_gpu_video_accelerator_factories.cc b/media/video/mock_gpu_video_accelerator_factories.cc
index 32a5ce8..8003efc 100644
--- a/media/video/mock_gpu_video_accelerator_factories.cc
+++ b/media/video/mock_gpu_video_accelerator_factories.cc
@@ -20,12 +20,15 @@
 
 class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
  public:
-  GpuMemoryBufferImpl(const gfx::Size& size, gfx::BufferFormat format)
+  GpuMemoryBufferImpl(const gfx::Size& size,
+                      gfx::BufferFormat format,
+                      bool fail_to_map_gpu_memory_buffer)
       : mapped_(false),
         format_(format),
         size_(size),
         num_planes_(gfx::NumberOfPlanesForLinearBufferFormat(format)),
-        id_(g_gpu_memory_buffer_id_generator.GetNext() + 1) {
+        id_(g_gpu_memory_buffer_id_generator.GetNext() + 1),
+        fail_to_map_gpu_memory_buffer_(fail_to_map_gpu_memory_buffer) {
     DCHECK(gfx::BufferFormat::R_8 == format_ ||
            gfx::BufferFormat::RG_88 == format_ ||
            gfx::BufferFormat::YUV_420_BIPLANAR == format_ ||
@@ -44,6 +47,8 @@
 
   // Overridden from gfx::GpuMemoryBuffer:
   bool Map() override {
+    if (fail_to_map_gpu_memory_buffer_)
+      return false;
     DCHECK(!mapped_);
     mapped_ = true;
     return true;
@@ -54,6 +59,8 @@
     return &bytes_[plane][0];
   }
   void Unmap() override {
+    if (fail_to_map_gpu_memory_buffer_)
+      return;
     DCHECK(mapped_);
     mapped_ = false;
   }
@@ -90,6 +97,7 @@
   size_t num_planes_;
   std::vector<uint8_t> bytes_[kMaxPlanes];
   gfx::GpuMemoryBufferId id_;
+  bool fail_to_map_gpu_memory_buffer_ = false;
 };
 
 }  // unnamed namespace
@@ -113,7 +121,7 @@
   if (fail_to_allocate_gpu_memory_buffer_)
     return nullptr;
   std::unique_ptr<gfx::GpuMemoryBuffer> ret(
-      new GpuMemoryBufferImpl(size, format));
+      new GpuMemoryBufferImpl(size, format, fail_to_map_gpu_memory_buffer_));
   created_memory_buffers_.push_back(ret.get());
   return ret;
 }
diff --git a/media/video/mock_gpu_video_accelerator_factories.h b/media/video/mock_gpu_video_accelerator_factories.h
index 65859ef1..785098a 100644
--- a/media/video/mock_gpu_video_accelerator_factories.h
+++ b/media/video/mock_gpu_video_accelerator_factories.h
@@ -74,6 +74,10 @@
     fail_to_allocate_gpu_memory_buffer_ = fail;
   }
 
+  void SetFailToMapGpuMemoryBufferForTesting(bool fail) {
+    fail_to_map_gpu_memory_buffer_ = fail;
+  }
+
   void SetGpuMemoryBuffersInUseByMacOSWindowServer(bool in_use);
 
   // Allocate & return a read-only shared memory region
@@ -98,6 +102,8 @@
 
   bool fail_to_allocate_gpu_memory_buffer_ = false;
 
+  bool fail_to_map_gpu_memory_buffer_ = false;
+
   gpu::SharedImageInterface* sii_;
 
   std::vector<gfx::GpuMemoryBuffer*> created_memory_buffers_;
diff --git a/media/video/openh264_video_encoder.cc b/media/video/openh264_video_encoder.cc
index 32e12ba..4bb4a37 100644
--- a/media/video/openh264_video_encoder.cc
+++ b/media/video/openh264_video_encoder.cc
@@ -60,6 +60,9 @@
 OpenH264VideoEncoder::ISVCEncoderDeleter::ISVCEncoderDeleter() = default;
 OpenH264VideoEncoder::ISVCEncoderDeleter::ISVCEncoderDeleter(
     const ISVCEncoderDeleter&) = default;
+OpenH264VideoEncoder::ISVCEncoderDeleter&
+OpenH264VideoEncoder::ISVCEncoderDeleter::operator=(const ISVCEncoderDeleter&) =
+    default;
 void OpenH264VideoEncoder::ISVCEncoderDeleter::operator()(ISVCEncoder* codec) {
   if (codec) {
     if (initialized_) {
diff --git a/media/video/openh264_video_encoder.h b/media/video/openh264_video_encoder.h
index 47e0bdd..11caf10 100644
--- a/media/video/openh264_video_encoder.h
+++ b/media/video/openh264_video_encoder.h
@@ -43,6 +43,7 @@
    public:
     ISVCEncoderDeleter();
     ISVCEncoderDeleter(const ISVCEncoderDeleter&);
+    ISVCEncoderDeleter& operator=(const ISVCEncoderDeleter&);
     void operator()(ISVCEncoder* coder);
     void MarkInitialized();
 
diff --git a/mojo/public/tools/bindings/generate_type_mappings.py b/mojo/public/tools/bindings/generate_type_mappings.py
index a009664..5eaad1e 100755
--- a/mojo/public/tools/bindings/generate_type_mappings.py
+++ b/mojo/public/tools/bindings/generate_type_mappings.py
@@ -82,6 +82,7 @@
       for entry in config['types']:
         configs[entry['mojom']] = {
             'typename': entry['cpp'],
+            'forward_declaration': entry.get('forward_declaration', None),
             'public_headers': config.get('traits_headers', []),
             'traits_headers': config.get('traits_private_headers', []),
             'copyable_pass_by_value': entry.get('copyable_pass_by_value',
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 58bbb17..60d30f43 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -120,6 +120,10 @@
 #endif
 {%- endif %}
 
+{%- for forward_declaration in typemap_forward_declarations %}
+{{forward_declaration}}
+{%- endfor %}
+
 {#--- WTF enum hashing #}
 {%- from "enum_macros.tmpl" import enum_hash_blink%}
 {%- if for_blink %}
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 95ab9b7..1156987 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -331,6 +331,12 @@
     for interface in self.module.interfaces:
       all_enums.extend(interface.enums)
 
+    typemap_forward_declarations = []
+    for kind in self.module.imported_kinds.values():
+      forward_declaration = self._GetTypemappedForwardDeclaration(kind)
+      if forward_declaration:
+        typemap_forward_declarations.append(forward_declaration)
+
     return {
         "all_enums": all_enums,
         "contains_only_enums": self._ContainsOnlyEnums(),
@@ -344,6 +350,7 @@
         "extra_traits_headers": self._GetExtraTraitsHeaders(),
         "for_blink": self.for_blink,
         "imports": self.module.imports,
+        "typemap_forward_declarations": typemap_forward_declarations,
         "interfaces": self.module.interfaces,
         "kinds": self.module.kinds,
         "module": self.module,
@@ -566,6 +573,12 @@
     return hasattr(kind, "name") and \
         self._GetFullMojomNameForKind(kind) in self.typemap
 
+  def _GetTypemappedForwardDeclaration(self, kind):
+    if not self._IsTypemappedKind(kind):
+      return None
+    return self.typemap[self._GetFullMojomNameForKind(
+        kind)]["forward_declaration"]
+
   def _IsHashableKind(self, kind):
     """Check if the kind can be hashed.
 
@@ -729,11 +742,11 @@
     """Determines whether a given import module requires a full header include,
     or if the forward header is sufficient."""
 
-    # Type-mapped kinds don't have forward declarations, and nested kinds cannot
-    # be forward declared.
-    # TODO(hans): Use forward declarations for type-mapped kinds.
+    # Type-mapped kinds may not have forward declarations, and nested kinds
+    # cannot be forward declared.
     if any(kind.module == imported_module and (
-        self._IsTypemappedKind(kind) or kind.parent_kind != None)
+        (self._IsTypemappedKind(kind) and not self.
+         _GetTypemappedForwardDeclaration(kind)) or kind.parent_kind != None)
            for kind in self.module.imported_kinds.values()):
       return True
 
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni
index b458650..6875346 100644
--- a/mojo/public/tools/bindings/mojom.gni
+++ b/mojo/public/tools/bindings/mojom.gni
@@ -401,6 +401,12 @@
 #             should be mapped in generated bindings. This is a string like
 #             "::base::Value" or "std::vector<::base::Value>".
 #
+#         forward_declaration (optional)
+#             A forward declaration of the C++ type, which bindings that don't
+#             need the full type definition can use to reduce the size of
+#             the generated code. This is a string like
+#             "namespace base { class Value; }".
+#
 #         move_only (optional)
 #             A boolean value (default false) which indicates whether the C++
 #             type is move-only. If true, generated bindings will pass the type
diff --git a/mojo/public/tools/bindings/validate_typemap_config.py b/mojo/public/tools/bindings/validate_typemap_config.py
index f1783d59..4cb714a 100755
--- a/mojo/public/tools/bindings/validate_typemap_config.py
+++ b/mojo/public/tools/bindings/validate_typemap_config.py
@@ -17,7 +17,7 @@
   ])
   _SUPPORTED_TYPE_KEYS = set([
       'mojom', 'cpp', 'copyable_pass_by_value', 'force_serialize', 'hashable',
-      'move_only', 'nullable_is_same_type'
+      'move_only', 'nullable_is_same_type', 'forward_declaration'
   ])
   with open(config_filename, 'r') as f:
     for config in json.load(f):
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 5d89075..5857481 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -2546,6 +2546,7 @@
   testonly = true
   sources = [
     "quiche/common/platform/impl/quiche_test_helpers_impl.h",
+    "quiche/common/platform/impl/quiche_test_impl.cc",
     "quiche/common/platform/impl/quiche_test_impl.h",
   ]
   deps = [
diff --git a/net/base/backoff_entry_serializer_unittest.cc b/net/base/backoff_entry_serializer_unittest.cc
index f662059..d2c37731 100644
--- a/net/base/backoff_entry_serializer_unittest.cc
+++ b/net/base/backoff_entry_serializer_unittest.cc
@@ -141,8 +141,8 @@
 
     // Check that the serialized backoff duration matches our expectation.
     double serialized_backoff_duration_double;
-    EXPECT_TRUE(serialized.GetList()[2].GetAsDouble(
-        &serialized_backoff_duration_double));
+    serialized_backoff_duration_double = serialized.GetList()[2].GetDouble();
+
     base::TimeDelta serialized_backoff_duration =
         base::TimeDelta::FromSecondsD(serialized_backoff_duration_double);
     EXPECT_EQ(serialized_backoff_duration, test_case.expected_backoff_duration);
diff --git a/net/cookies/parse_cookie_line_fuzzer.cc b/net/cookies/parse_cookie_line_fuzzer.cc
index 0376622..830a8bf 100644
--- a/net/cookies/parse_cookie_line_fuzzer.cc
+++ b/net/cookies/parse_cookie_line_fuzzer.cc
@@ -25,7 +25,7 @@
 
   // Call zero or one of ParsedCookie's mutator methods.  Should not call
   // anything other than SetName/SetValue when !IsValid().
-  const uint8_t action = data_provider.ConsumeIntegralInRange(0, 11);
+  const uint8_t action = data_provider.ConsumeIntegralInRange(0, 12);
   switch (action) {
     case 1:
       parsed_cookie.SetName(GetArbitraryString(&data_provider));
@@ -65,6 +65,9 @@
       case 11:
         parsed_cookie.SetIsSameParty(data_provider.ConsumeBool());
         break;
+      case 12:
+        parsed_cookie.SetIsPartitioned(data_provider.ConsumeBool());
+        break;
     }
   }
 
diff --git a/net/cookies/parsed_cookie.cc b/net/cookies/parsed_cookie.cc
index 4fc5a19..c87510f 100644
--- a/net/cookies/parsed_cookie.cc
+++ b/net/cookies/parsed_cookie.cc
@@ -61,6 +61,7 @@
 const char kSameSiteTokenName[] = "samesite";
 const char kPriorityTokenName[] = "priority";
 const char kSamePartyTokenName[] = "sameparty";
+const char kPartitionedTokenName[] = "partitioned";
 
 const char kTerminator[] = "\n\r\0";
 const int kTerminatorLen = sizeof(kTerminator) - 1;
@@ -228,6 +229,10 @@
   return SetBool(&same_party_index_, kSamePartyTokenName, is_same_party);
 }
 
+bool ParsedCookie::SetIsPartitioned(bool is_partitioned) {
+  return SetBool(&partitioned_index_, kPartitionedTokenName, is_partitioned);
+}
+
 std::string ParsedCookie::ToCookieLine() const {
   std::string out;
   for (auto it = pairs_.begin(); it != pairs_.end(); ++it) {
@@ -239,7 +244,8 @@
     // we need to consider whether the name component is a special token.
     if (it == pairs_.begin() ||
         (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName &&
-         it->first != kSamePartyTokenName)) {
+         it->first != kSamePartyTokenName &&
+         it->first != kPartitionedTokenName)) {
       out.append("=");
       out.append(it->second);
     }
@@ -480,6 +486,8 @@
       priority_index_ = i;
     } else if (pairs_[i].first == kSamePartyTokenName) {
       same_party_index_ = i;
+    } else if (pairs_[i].first == kPartitionedTokenName) {
+      partitioned_index_ = i;
     } else {
       /* some attribute we don't know or don't care about. */
     }
@@ -545,9 +553,10 @@
   if (index == 0)
     return;
 
-  size_t* indexes[] = {&path_index_,      &domain_index_,   &expires_index_,
-                       &maxage_index_,    &secure_index_,   &httponly_index_,
-                       &same_site_index_, &priority_index_, &same_party_index_};
+  size_t* indexes[] = {&path_index_,       &domain_index_,   &expires_index_,
+                       &maxage_index_,     &secure_index_,   &httponly_index_,
+                       &same_site_index_,  &priority_index_, &same_party_index_,
+                       &partitioned_index_};
   for (size_t* attribute_index : indexes) {
     if (*attribute_index == index)
       *attribute_index = 0;
diff --git a/net/cookies/parsed_cookie.h b/net/cookies/parsed_cookie.h
index cd9cfed0..b064855 100644
--- a/net/cookies/parsed_cookie.h
+++ b/net/cookies/parsed_cookie.h
@@ -54,6 +54,7 @@
       CookieSameSiteString* samesite_string = nullptr) const;
   CookiePriority Priority() const;
   bool IsSameParty() const { return same_party_index_ != 0; }
+  bool IsPartitioned() const { return partitioned_index_ != 0; }
   bool HasTruncatedNameOrValue() const { return truncated_name_or_value_; }
 
   // Returns the number of attributes, for example, returning 2 for:
@@ -81,6 +82,7 @@
   bool SetSameSite(const std::string& same_site);
   bool SetPriority(const std::string& priority);
   bool SetIsSameParty(bool is_same_party);
+  bool SetIsPartitioned(bool is_partitioned);
 
   // Returns the cookie description as it appears in a HTML response header.
   std::string ToCookieLine() const;
@@ -160,6 +162,7 @@
   size_t same_site_index_ = 0;
   size_t priority_index_ = 0;
   size_t same_party_index_ = 0;
+  size_t partitioned_index_ = 0;
   // For metrics on cookie name/value truncation. See usage at the bottom of
   // `ParseTokenValuePairs()` for more details.
   bool truncated_name_or_value_ = false;
diff --git a/net/cookies/parsed_cookie_unittest.cc b/net/cookies/parsed_cookie_unittest.cc
index c12c1b83..5d28985 100644
--- a/net/cookies/parsed_cookie_unittest.cc
+++ b/net/cookies/parsed_cookie_unittest.cc
@@ -16,6 +16,7 @@
   EXPECT_FALSE(pc1.IsSecure());
   EXPECT_FALSE(pc1.IsHttpOnly());
   EXPECT_FALSE(pc1.IsSameParty());
+  EXPECT_FALSE(pc1.IsPartitioned());
   EXPECT_EQ("a", pc1.Name());
   EXPECT_EQ("b", pc1.Value());
   EXPECT_FALSE(pc1.HasPath());
@@ -27,11 +28,12 @@
 
   ParsedCookie pc2(
       "c=d; secure; httponly; sameparty; path=/foo; domain=bar.test; "
-      "max-age=60; samesite=lax; priority=high");
+      "max-age=60; samesite=lax; priority=high; partitioned;");
   EXPECT_TRUE(pc2.IsValid());
   EXPECT_TRUE(pc2.IsSecure());
   EXPECT_TRUE(pc2.IsHttpOnly());
   EXPECT_TRUE(pc2.IsSameParty());
+  EXPECT_TRUE(pc2.IsPartitioned());
   EXPECT_EQ("c", pc2.Name());
   EXPECT_EQ("d", pc2.Value());
   EXPECT_TRUE(pc2.HasPath());
@@ -138,18 +140,20 @@
 
 TEST(ParsedCookieTest, TestAttributeCase) {
   ParsedCookie pc(
-      "BLAH; Path=/; sECuRe; httpONLY; sAmESitE=LaX; pRIoRitY=hIgH; samePaRtY");
+      "BLAH; Path=/; sECuRe; httpONLY; sAmESitE=LaX; pRIoRitY=hIgH; samePaRtY; "
+      "pARTitIoNeD;");
   EXPECT_TRUE(pc.IsValid());
   EXPECT_TRUE(pc.IsSecure());
   EXPECT_TRUE(pc.IsHttpOnly());
   EXPECT_TRUE(pc.IsSameParty());
+  EXPECT_TRUE(pc.IsPartitioned());
   EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
   EXPECT_TRUE(pc.HasPath());
   EXPECT_EQ("/", pc.Path());
   EXPECT_EQ("", pc.Name());
   EXPECT_EQ("BLAH", pc.Value());
   EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
-  EXPECT_EQ(6U, pc.NumberOfAttributes());
+  EXPECT_EQ(7U, pc.NumberOfAttributes());
 }
 
 TEST(ParsedCookieTest, TestDoubleQuotedNameless) {
@@ -396,10 +400,11 @@
   EXPECT_TRUE(pc.SetSameSite("LAX"));
   EXPECT_TRUE(pc.SetPriority("HIGH"));
   EXPECT_TRUE(pc.SetIsSameParty(true));
+  EXPECT_TRUE(pc.SetIsPartitioned(true));
   EXPECT_EQ(
       "name=value; domain=domain.com; path=/; "
       "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
-      "httponly; samesite=LAX; priority=HIGH; sameparty",
+      "httponly; samesite=LAX; priority=HIGH; sameparty; partitioned",
       pc.ToCookieLine());
   EXPECT_TRUE(pc.HasDomain());
   EXPECT_TRUE(pc.HasPath());
@@ -423,7 +428,7 @@
   EXPECT_EQ(
       "name=value; domain=domain.com; path=/foo; "
       "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
-      "httponly; samesite=LAX; priority=HIGH; sameparty",
+      "httponly; samesite=LAX; priority=HIGH; sameparty; partitioned",
       pc.ToCookieLine());
 
   // Set priority to medium.
@@ -432,16 +437,16 @@
   EXPECT_EQ(
       "name=value; domain=domain.com; path=/foo; "
       "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
-      "httponly; samesite=LAX; priority=medium; sameparty",
+      "httponly; samesite=LAX; priority=medium; sameparty; partitioned",
       pc.ToCookieLine());
 
   // Clear attribute from the end.
-  EXPECT_TRUE(pc.SetIsSameParty(false));
-  EXPECT_FALSE(pc.IsSameParty());
+  EXPECT_TRUE(pc.SetIsPartitioned(false));
+  EXPECT_FALSE(pc.IsPartitioned());
   EXPECT_EQ(
       "name=value; domain=domain.com; path=/foo; "
       "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
-      "httponly; samesite=LAX; priority=medium",
+      "httponly; samesite=LAX; priority=medium; sameparty",
       pc.ToCookieLine());
 
   // Clear the rest and change the name and value.
@@ -462,8 +467,11 @@
   EXPECT_FALSE(pc.IsSecure());
   EXPECT_FALSE(pc.IsHttpOnly());
   EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
+  EXPECT_TRUE(pc.SetIsSameParty(false));
+  EXPECT_TRUE(pc.SetIsPartitioned(false));
   EXPECT_EQ("name2=value2", pc.ToCookieLine());
   EXPECT_FALSE(pc.IsSameParty());
+  EXPECT_FALSE(pc.IsPartitioned());
 }
 
 // Set the domain attribute twice in a cookie line. If the second attribute's
@@ -692,6 +700,31 @@
     EXPECT_TRUE(pc.IsSameParty());
     EXPECT_TRUE(pc.IsHttpOnly());
   }
+  {
+    ParsedCookie pc("partitioned=foo");
+    EXPECT_EQ("partitioned", pc.Name());
+    EXPECT_EQ("foo", pc.Value());
+    EXPECT_FALSE(pc.IsPartitioned());
+  }
+  {
+    ParsedCookie pc("partitioned=");
+    EXPECT_EQ("partitioned", pc.Name());
+    EXPECT_EQ("", pc.Value());
+    EXPECT_FALSE(pc.IsPartitioned());
+  }
+  {
+    ParsedCookie pc("=partitioned");
+    EXPECT_EQ("", pc.Name());
+    EXPECT_EQ("partitioned", pc.Value());
+    EXPECT_FALSE(pc.IsPartitioned());
+  }
+  {
+    ParsedCookie pc(
+        "partitioned; partitioned; secure; httponly; httponly; secure");
+    EXPECT_EQ("", pc.Name());
+    EXPECT_EQ("partitioned", pc.Value());
+    EXPECT_TRUE(pc.IsPartitioned());
+  }
 }
 
 TEST(ParsedCookieTest, SameSiteValues) {
diff --git a/net/dns/dns_test_util.h b/net/dns/dns_test_util.h
index 8c04281..0f9128c 100644
--- a/net/dns/dns_test_util.h
+++ b/net/dns/dns_test_util.h
@@ -14,9 +14,9 @@
 #include <utility>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_config.h"
diff --git a/net/dns/host_resolver_source.h b/net/dns/host_resolver_source.h
index cf9633b..abff492 100644
--- a/net/dns/host_resolver_source.h
+++ b/net/dns/host_resolver_source.h
@@ -5,7 +5,7 @@
 #ifndef NET_DNS_HOST_RESOLVER_SOURCE_H_
 #define NET_DNS_HOST_RESOLVER_SOURCE_H_
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 
 namespace net {
 
diff --git a/net/dns/public/dns_query_type.h b/net/dns/public/dns_query_type.h
index 11aa0b69..0fea7db4 100644
--- a/net/dns/public/dns_query_type.h
+++ b/net/dns/public/dns_query_type.h
@@ -5,7 +5,7 @@
 #ifndef NET_DNS_PUBLIC_DNS_QUERY_TYPE_H_
 #define NET_DNS_PUBLIC_DNS_QUERY_TYPE_H_
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "net/base/net_export.h"
 
 namespace net {
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index 63e607af..e494f63 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -1322,11 +1322,11 @@
             }
             add_statement.BindCString(3, "");  // value
             // BindBlob() immediately makes an internal copy of the data.
-            add_statement.BindBlob(12, encrypted_value.data(),
-                                   static_cast<int>(encrypted_value.length()));
+            add_statement.BindBlob(12, encrypted_value);
           } else {
             add_statement.BindString(3, po->cc().Value());
-            add_statement.BindBlob(12, "", 0);  // encrypted_value
+            add_statement.BindBlob(12,
+                                   base::span<uint8_t>());  // encrypted_value
           }
           add_statement.BindString(4, po->cc().Path());
           add_statement.BindTime(5, po->cc().ExpiryDate());
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
index b4cecb46..070c361 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
 
+#include <stdint.h>
+
 #include <map>
 #include <memory>
 #include <set>
@@ -11,6 +13,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/location.h"
@@ -1172,7 +1175,7 @@
     statement.BindString(1, cookies[i].Domain());
     statement.BindString(2, cookies[i].Name());
     statement.BindString(3, cookies[i].Value());
-    statement.BindBlob(4, "", 0);  // encrypted_value
+    statement.BindBlob(4, base::span<uint8_t>());  // encrypted_value
     statement.BindString(5, cookies[i].Path());
     statement.BindInt64(
         6, cookies[i].ExpiryDate().ToDeltaSinceWindowsEpoch().InMicroseconds());
@@ -1639,7 +1642,7 @@
     statement.BindString(1, cookies[i].Domain());
     statement.BindString(2, cookies[i].Name());
     statement.BindString(3, cookies[i].Value());
-    statement.BindBlob(4, "", 0);  // encrypted_value
+    statement.BindBlob(4, base::span<uint8_t>());  // encrypted_value
     statement.BindString(5, cookies[i].Path());
     statement.BindInt64(
         6, cookies[i].ExpiryDate().ToDeltaSinceWindowsEpoch().InMicroseconds());
@@ -1854,7 +1857,7 @@
     statement.BindString(1, cookies[i].Domain());
     statement.BindString(2, cookies[i].Name());
     statement.BindString(3, cookies[i].Value());
-    statement.BindBlob(4, "", 0);  // encrypted_value
+    statement.BindBlob(4, base::span<uint8_t>());  // encrypted_value
     statement.BindString(5, cookies[i].Path());
     statement.BindInt64(
         6, cookies[i].ExpiryDate().ToDeltaSinceWindowsEpoch().InMicroseconds());
@@ -1902,7 +1905,7 @@
     statement.BindString(1, cookie.Domain());
     statement.BindString(2, cookie.Name());
     statement.BindString(3, cookie.Value());
-    statement.BindBlob(4, "", 0);  // encrypted_value
+    statement.BindBlob(4, base::span<uint8_t>());  // encrypted_value
     statement.BindString(5, cookie.Path());
     statement.BindInt64(
         6, cookie.ExpiryDate().ToDeltaSinceWindowsEpoch().InMicroseconds());
diff --git a/net/http/http_auth_handler_factory.cc b/net/http/http_auth_handler_factory.cc
index 4617186a..516066c 100644
--- a/net/http/http_auth_handler_factory.cc
+++ b/net/http/http_auth_handler_factory.cc
@@ -29,14 +29,20 @@
 
 namespace {
 
-base::Value NetLogParamsForCreateAuth(const std::string& scheme,
-                                      const std::string& challenge,
-                                      const int net_error,
-                                      net::NetLogCaptureMode capture_mode) {
+base::Value NetLogParamsForCreateAuth(
+    const std::string& scheme,
+    const std::string& challenge,
+    const int net_error,
+    const GURL& origin,
+    const absl::optional<bool>& allows_default_credentials,
+    net::NetLogCaptureMode capture_mode) {
   base::Value dict(base::Value::Type::DICTIONARY);
   dict.SetKey("scheme", net::NetLogStringValue(scheme));
   if (net::NetLogCaptureIncludesSensitive(capture_mode))
     dict.SetKey("challenge", net::NetLogStringValue(challenge));
+  dict.SetStringKey("origin", origin.spec());
+  if (allows_default_credentials)
+    dict.SetBoolKey("allows_default_credentials", *allows_default_credentials);
   if (net_error < 0)
     dict.SetIntKey("net_error", net_error);
   return dict;
@@ -246,7 +252,10 @@
   net_log.AddEvent(NetLogEventType::AUTH_HANDLER_CREATE_RESULT,
                    [&](NetLogCaptureMode capture_mode) {
                      return NetLogParamsForCreateAuth(
-                         scheme, challenge->challenge_text(), net_error,
+                         scheme, challenge->challenge_text(), net_error, origin,
+                         *handler ? absl::make_optional(
+                                        (*handler)->AllowsDefaultCredentials())
+                                  : absl::nullopt,
                          capture_mode);
                    });
   return net_error;
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index ef934fc2..9201fd2 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -5065,7 +5065,6 @@
     { "name": "lafkor.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "leob.in", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "loacg.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
-    { "name": "loucanfixit.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "marcoececilia.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "marie.club", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "markusweimar.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -5729,7 +5728,6 @@
     { "name": "jamesbradach.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "jamesdoell.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "jamiemagee.dk", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
-    { "name": "jamon.ca", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "janario.me", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "jaqen.ch", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "jasonamorrow.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -21524,7 +21522,6 @@
     { "name": "singaporemint.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "sitecloudify.com", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "sk-net.cz", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
-    { "name": "sketchywebsite.net", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "skiinstructor.services", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "skischule-wildewiese.de", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
     { "name": "skommettiamo.it", "policy": "bulk-18-weeks", "mode": "force-https", "include_subdomains": true },
@@ -72301,7 +72298,6 @@
     { "name": "importsign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "imstocker.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "inanam.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
-    { "name": "inbound.menu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "inefin.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "infoland.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "informspb.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -125594,7 +125590,6 @@
     { "name": "concealoutfitters.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "conditionyellowacademy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "connectedrisksolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
-    { "name": "consec.systems", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "conssec.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "consultation.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "contrapeso.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -126544,7 +126539,6 @@
     { "name": "shellcore.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "shidurdan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "shieldnsheath.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
-    { "name": "shopcon.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "shugarmanpsychiatric.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "sickhou.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "sickhouse.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -144311,7 +144305,6 @@
     { "name": "ashfak.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "atev.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "auto-quote.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
-    { "name": "automobile-gabriel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "automotivesource.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "avanade.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "avanade.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
@@ -149770,6 +149763,731 @@
     { "name": "zprogramming.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "ztmovies.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     { "name": "zydecozityradio.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "0r3.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "1a-media.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "1dot1dot1dot1.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "3h-co.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "3mbuilders.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "4motionsgmbh.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "4season-flowers.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "a-frique.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aarsen.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "abcprodutosvirtuais.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "acculongrange.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adamcarbonell.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adammartelletti.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adel.lol", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adigolifestyle.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adriennekiss.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "adviesgv.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ahg-offices.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ahiha-design.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ahityayinlari.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ahityayinlari.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "airconditioning-centurion.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aixm.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "al-hekka.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alborgwatch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alcasan.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aldebaranbm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alessandropuccistudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alexsavin.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alibi-ua.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aliceophotographie.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alizah.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alpencams.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alphat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alpine.com.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "altimax.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alumnifire-staging.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "alumnifire.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "amberesdetective.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "amxm.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "andor.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "andyblu.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "angelnumber.faith", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "animalcaretrust.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "animari.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ankarasondajkuyusutemizleme.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "annestadie.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "antecipa.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "apcw.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "apit-kovrov.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "appllio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "apssolucoesfinanceiras.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "arabic-for-nerds.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aromaonlinestore-korat.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "arthurboes.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "artomalu.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "arz-online.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "asessiglo21.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ashadin.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "astano.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "asteroskonh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "asuamaytinh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "atlana.pro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "atmmasterplan.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aurorak12.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "austinhartzheim.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "austinlaw.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "avanad.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "avanade-jobs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "avanade.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "avanade.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "avanadealumni.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aviaskan.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "aymhome.top", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "azs-nw.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "b11p.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "backupauthentication.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bangkok-thailand.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bankmno.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bankrbk.kz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "barcelonatours.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "basicsuamarca.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bdepolytechgrenoble.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "beapieceofart.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bedrijfsfeesten.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bejo.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "benleggiero.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "betlancer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "betwinner.co.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "beyers.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bifrostwallet.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bigdayproductions.biz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "billogram.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "blackcountrymusicband.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "blackfrogagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "blankgeneration.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "boardoftheworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "boatseller.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bolele.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "boleleboyz.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "botdiril.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "boyscoutcampcars.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bpvgoncalves.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "brandbags.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "brasilnatu.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bravelocation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "bridg-it.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "brokerlink.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "brotwurz.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "budpolimer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "businessvalue.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "caiobatistamkt.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "camasirkazani.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "canariasport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "canuslucitrus.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "caranya.my.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "caricatures-uk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "carpetcleaningprofessionals.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cashola.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "casinocity.sb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "casinocity.sl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "casinocity.vu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "catlicking.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "caxaa.mx", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ccaag.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ccwallet.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ceiphr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cfdt-fleurymichon.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "charles-migaud.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "chirality.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "chrisogedengbe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "christian-garo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "chun.si", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cinco-ind.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cinicostudio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cjaconsultoria.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "claarycherry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cliveptr.cc", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "codpwned.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "coffeestory.in.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cogetop.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "collectifpinceoreilles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "communitylivingalgoma.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "comovenderpelowhatsapp.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "comparai.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "consult-altius.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "copybysophie.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "couchscreen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "covidtracker.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cpatoday.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "craytos.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cryozenic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "csgoba.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "culturaanarquista.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "curinline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "cymricweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dailysomething.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dailywarteg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dankevich.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "datos-quimsaitw.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "daveredfern.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "davidsdika.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dawnbyte.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "deinjoghurt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dejongebeth.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "deliuksta.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "delprete.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "departure-transfer-reservation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "devnull.win", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "digipartindex.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "digitoucan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dirtysindy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "discoveryvirtualsolutions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "djboris.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dnslytics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dolezalpartners.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "domenick-lieneweg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "doriangardes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dqfilesonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dragonsgate.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "drenergysaveror.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "drummer.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ds.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dsg.ac.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dsg.gd.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dualexistence.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "duhanic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "duhanic.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "duhurensohn.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "dvkg.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "e-buspacific.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "eatmportal.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "eco-doors.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "edacasa.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "educampus.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "edunet.training", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "effmio.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "einfachkiss.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "eisenstark.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ekcomp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ekosaltis.lt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "elektrilevi.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "eliteprostheticdentistry.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "elliyoung.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "emmanuellecerat.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "endpipe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "enewspf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "engenhariadomarketing.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "enriqueamaro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "esurveynordic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "evileye-xl.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ewighost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "extua.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ezybook.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ezybook.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fabricalaser.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "faimdevoyages.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fairlesslaw.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "faithfulfaye.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "familie-oberlander.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fedposting.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ff-tostedt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "findahero.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "finehomesource.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fitbase.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "flyly.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "folife.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "foma.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fongsoul.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "format.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "formations-maritimes.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fortniteup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "forumrowerowe.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "frandash.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fredz.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "freedomworldoutreach.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fruturaproduce.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "fsmi.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gabriellearruda.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gameparadise24.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "garbuszus.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "garo.email", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gatemotorsbenoni.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gazoneo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gddzqg.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gelaterista.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "genesisray.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "george.black", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "germaniumsoft.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "getidee.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "giaydepvnn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gillsco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gillscompany.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ginabae.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "girlandhermoon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "glamluxestudios.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "glennfitzpatrick.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "glgattorneys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "globemilk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "globemilk.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "golfbettingsystem.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "goxyshuk.duckdns.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gpwa.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "graine-de-cafe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "greffe-de-cheveux-turquie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gregoryhammond.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "gretaraccontastorie.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "groupama.sk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "guddaff.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hackingacademy.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hal52.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hartpsychologen.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "has.gy", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hasgeek.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hasjob.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "headymafia.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "healthchecks.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "healthtipsfactory.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hello-papaye.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hellocat.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "herbarium.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "highgravityconsulting.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hirix.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "holgr.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hosthum.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "huboo.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hypercritical.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "hyunjoonkim.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "idctechnologies.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "igamingnews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ikbenrichie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "immanuelos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "impressao3d.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "inantrantung.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "indiangamingreport.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "intelligroup360.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "irbisweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "irion-edm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "iron.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "israelitas.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "it-tainment.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "italianforkids.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "itasis.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ixiatiao.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "izzuddinxcii.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "izzycat.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jacobtaylor.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jesseklaver.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jlqwer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jls.idv.tw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jobkontor.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "johnsons.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "joincahoot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jonasbrothers-la-jonaticas.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jonasvildmark.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jongenstromp.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jonkpl.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jooblis.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jooblis.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "josiemccoy.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jpr.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jsemprestimos.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "jtkconstructiongroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "juanmapauso.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "judithsargentini.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "juliajuice.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kaaraali.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kam-teh.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kapsouroparea.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kde-je-skladem.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "keelandlong.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "keeppost.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kefucha.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kimberlycaprice.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kimherala.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kittygalore.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kjg-hattingen.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kolorkids.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kooranaps.wa.edu.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kopenenvergelijken.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "koreankiosk.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kroowmarketing.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "krustyland.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "kyleggiero.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lab-oborud.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "laiweiyi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lamecaniquepourlesfilles.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "landfrauen-hermetschwil.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "larenaissance.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lasertalk.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lastingpower.com.pe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "latefeeking.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "latefeeking.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "legendfinancial.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "leismann.sbs", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lemonadefashion.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lepetitblond.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "letscounthigher.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "levimarvin.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lifamily.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lightning.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lilov.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "limenotlemon.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "litterfreeriversandstreams.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "littleson.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "local-maintenance.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "locas.me", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "location-vacances-campello.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lojasoulstyle.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lolacandy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "loreedeslandes.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "luatan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lucascaton.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "lukepeltier.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "luxelyhome.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "makeovershop.ro", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "maksympro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "maksymsdesign.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "managed-it.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mansfield.id.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mariadelcastillo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "marico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "markmetcalfe.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "markterweele.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "maruconsultoria.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "massage-la-clusaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "massiveanalyser.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "matroussedetoilette.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mattab.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mattga.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "matthiasott.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mbrjun.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mcgarrybair.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mddietclinic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mdl.co.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mdswlegal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mernau.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mfanalyzer.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mgocs.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "miaadler.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "micropigmentacaobh.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mijnblog.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "millalex.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mindequityinternational.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "miui.kr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mjollnir.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mjuktvatten.nu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mn-hootsuite.herokuapp.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "modenodf.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "moguls.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "morosystems.cloud", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "moscardino.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "moshavergroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "motd.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mrclutch.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mtzfederico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "muma.cf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mundohispanico.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "munnasleepwear.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "music-bar.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "musictalk.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mvrcheck.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mvrdrivingrecords.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "myanmar-responsiblebusiness.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mydesignrules.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "myglobalopti.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mylittlewizard.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "mynissan.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "n8.gay", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nada-photo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nangstuff.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "narevapromotions.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "naringslivsala.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nastationztv.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nationalgridrenewables.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nekomanten.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "netgen.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "newgardenfarms.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nexlight.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ngocchaua.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ngplus.name", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nhance.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nicktamin.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nimnadasl.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nio.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nlib.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nobz.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nordico.club", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "norwichzen.org.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "novasdecadamanha.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nrg.edu.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "nummer378.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "objavka.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "occupynightlife.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ockara.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "oevkg.at", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "office-mizutani.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "offlineauthentication.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "okinawan-lyrics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "omniarch.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "one-cozmic.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "onestarclassics.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "onionshare.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "onlineradio.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "only2chat.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "onpreise.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "optimadental.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "opusclassical.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "os.ax", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "osdeployments.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "otomny.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ovhcdn.pw", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "owo.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "paribus.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "paslc.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "passion-billard.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "paygvpn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "paykassa.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pedo.house", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pegrum.rocks", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "physiotheler.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pialove.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pirate-proxy.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pod.lv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "politisplasticsurgery.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "pollypaps.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "posterlounge.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "powerpc.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "premieraviation.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "primevtc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "projetootaku.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "promobit.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "propertyvalue.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "provedorlivre.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "providmedical.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "proxy-bay.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "puffy.tube", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "puffyan.us", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "puppylove.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "puzzyfun.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "qcert.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "qiber.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "qmp-media.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "qubicgames.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "quest7.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "questionyu.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "quickquote.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "quirkycruise.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "radiocommande-forestiere.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "radiopanikos.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "radopsec.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "radopsec.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ragstores.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rahvusraamatukogu.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "randburgplumber-247.co.za", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rantevou.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "reachollos.site", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "red1it.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "reikicrystal.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "relationshipsandprivatestuff.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "revosoft.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rialto.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "right.wtf", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rmsu.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "robbins-construction.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "robotask.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "royalembassys.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rubberband.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rubenslikkarchive.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rubidium.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ruckify.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ruffm.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rusificatio.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "rvf6.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "s4hosting.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "saam.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "salonsuites.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sangina.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "saracenmarkets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sarayeketabesoti.ir", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sarrworld.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "satipatthanamula.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sbmsmartaccounting.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "schokobebe.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "scoep.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "scooby.ml", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "scoopgh.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sdaniel55.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "secolve.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "seeit.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "seizethedaybrasil.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "seresco.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "serwislukit.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sexystine.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sgaravato.it", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sgtaivs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "shade.sh", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "shinkamigoto.tv", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "shkilna-kraina.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "shuizilan.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sigma.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "simplyfixit.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "simpson.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sint-maarten.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "siteviseagency.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sixam.co.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "skillavid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "skinos.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sksongs.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "skullowner.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "skybrary.eu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "slotcatalog.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "smallcubed.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "smksatriamagelang.sch.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "smooth-e.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "snapmuse.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "softmas.cl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "softowe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "soin-rebozo.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "solongandthanksforallthe.fish", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "songstothesiren.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sourcegraph.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "spanishblackboard.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sparta.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "splinterzeeland.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "split.rent", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "spocool.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sprossen-keimlinge.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "stackery.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "startupweb.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "stasyan.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "stjosephtownship.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "strappazzon.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "stuartwilsonhair.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "subology.co", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "summitpediatriaz.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sundoctors.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sunglassstyle.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "sunrisesolutionsutah.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "superops.ai", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "surveyapp.io", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "surveyspy.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "swim.aero", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "swizio.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tabacarika.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "taigalaloca.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "taltech.ee", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "targoncavasarlas.hu", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tatercraft.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tbunews.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tbunews.info", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "techsalot.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tecverso.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tedhardy.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "testsnelcovid.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tgt.co.il", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thandanhapkhau.vn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "theartwolf.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thedailyreporteronline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thekittivibe.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thematchless.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "theotherconcept.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "therapie-psycho-emotionnelle.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "theswansonlawgroup.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thewatchdog.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thimic.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thimic.no", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "thw-jugend-muenchen-west.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ticnom.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "timomontalto.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tirinfo.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tobiasheinze.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "toftered.se", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tomoarigato.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "toponlinecasino.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "toskavista.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tr3fit.xyz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trainingstore.fish", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "transmitrecordings.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trata.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "traumaberatung-lindner.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trewdistributors.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tribe-d.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "triomoda.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trionyx.ph", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "triplefork.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trixietainted.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "truepestcontrol.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "truework.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "trustusnyc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tscampus.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tubuenpedido.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tuketicidergisi.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tusatonline.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tutiendard.ga", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "two-many.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tylerpayne.tk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "typesolution.pt", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "tzhsoj.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "uatuning.com.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "uavis.com.au", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "udilicitana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ultrabkk.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "umasoda-tohoku.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "universalmusic.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "universitypark.com.tr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "unsupervised.ca", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "uopeople.review", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "upmediaclick.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "upped.com.my", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "uwe-arzt.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "valedigitalservice.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "valisevoyage.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vanityestetik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vanndigital.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vanrichie.nl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vasconcellos.casa", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vasficelik.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vdstc.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vikrantkakad.in", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "villagevetcattery.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "visualetiquetas.art.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "voctto.com.br", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "voditel.ua", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "voiretmanger.fr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "vulnerable.af", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wartegseberangsana.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "webka.online", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "websdeweb.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "webwiz.co.uk", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "weijero.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "weitundbreit.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "werranfehtan.org", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wikimho.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "willship.co.nz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wkd.one", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "woc.ao", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "woo.bi", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wordindonesia.id", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wordpress-inc.ru", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "woutfeys.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "woutiscoding.be", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "writingontablets.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "wuermlitaucher.ch", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "xanthitoday.gr", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "xedap24h.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "xinxin.fun", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "xn----7sbkofbbj4akz.xn--80asehdb", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "xn--9wy84dkz4a.love", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yamagata-fujinka.jp", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yebshotel.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yecdn.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yeltzland.net", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yespornfree.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "ymy.moe", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "yousefi.de", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zeigren.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zentoid.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zero-link.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zerolink.click", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zerolink.es", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zjyoulian.cn", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "znaceni-max.cz", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "znajdzprzodka.pl", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
+    { "name": "zvukipro.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true },
     // END OF 1-YEAR BULK HSTS ENTRIES
 
     // Only eTLD+1 domains can be submitted automatically to hstspreload.org,
diff --git a/net/http/transport_security_state_static.template b/net/http/transport_security_state_static.template
index ceb400a..21542f9b7 100644
--- a/net/http/transport_security_state_static.template
+++ b/net/http/transport_security_state_static.template
@@ -9,7 +9,7 @@
 
 #include <stdint.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "net/http/transport_security_state_source.h"
 
 // These are SubjectPublicKeyInfo hashes for public key pinning. The
diff --git a/net/http/transport_security_state_static_unittest.template b/net/http/transport_security_state_static_unittest.template
index 08b2116..0c4f596 100644
--- a/net/http/transport_security_state_static_unittest.template
+++ b/net/http/transport_security_state_static_unittest.template
@@ -8,7 +8,7 @@
 
 #include <stdint.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "net/http/transport_security_state_source.h"
 
 [[SPKI_HASHES]]
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index 3bb6386a..1f8b028 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -2647,6 +2647,9 @@
 //      "scheme": <scheme>
 //      "net_error": <Net Error. Only present in case of error.>
 //      "challenge": <challenge string, if NetLogCaptureIncludesSensitive>
+//      "origin": <the origin of the server or proxy which issued the challenge>
+//      "allows_default_credentials": <whether the default credentials may be
+//                                     used for the origin>
 //  }
 EVENT_TYPE(AUTH_HANDLER_CREATE_RESULT)
 
diff --git a/net/log/trace_net_log_observer_unittest.cc b/net/log/trace_net_log_observer_unittest.cc
index 13eb16bf..7bdc5a7 100644
--- a/net/log/trace_net_log_observer_unittest.cc
+++ b/net/log/trace_net_log_observer_unittest.cc
@@ -120,7 +120,7 @@
       base::RunLoop* run_loop,
       const scoped_refptr<base::RefCountedString>& events_str,
       bool has_more_events) {
-    DCHECK(trace_events_->empty());
+    DCHECK(trace_events_->GetList().empty());
     trace_buffer_.Start();
     trace_buffer_.AddFragment(events_str->data());
     trace_buffer_.Finish();
diff --git a/net/ntlm/ntlm_constants.h b/net/ntlm/ntlm_constants.h
index 3a3c263..d1163bab 100644
--- a/net/ntlm/ntlm_constants.h
+++ b/net/ntlm/ntlm_constants.h
@@ -10,7 +10,7 @@
 
 #include <vector>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "net/base/net_export.h"
 
 namespace net {
diff --git a/net/quic/quic_connectivity_probing_manager_test.cc b/net/quic/quic_connectivity_probing_manager_test.cc
index 6579f64e..eafb78f 100644
--- a/net/quic/quic_connectivity_probing_manager_test.cc
+++ b/net/quic/quic_connectivity_probing_manager_test.cc
@@ -514,7 +514,7 @@
   EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount());
 
   // Request cancel probing for |newPeerAddress| on |testNetworkHandle| doesn't
-  // affect the exisiting probing.
+  // affect the existing probing.
   probing_manager_.CancelProbing(testNetworkHandle, newPeerAddress);
   EXPECT_TRUE(
       probing_manager_.IsUnderProbing(testNetworkHandle, testPeerAddress));
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index d5d04e88..4f6ff620 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -1685,6 +1685,7 @@
   EXPECT_TRUE(socket_data.AllWriteDataConsumed());
 }
 
+// Regression test for https://crbug.com/639916.
 TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
   // Set up session to migrate.
   host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
@@ -1708,6 +1709,7 @@
   QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
   session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
                                quic::ConnectionCloseBehavior::SILENT_CLOSE);
+  EXPECT_FALSE(HasActiveSession(host_port_pair_));
 
   client_maker_.Reset();
   // Set up server IP, socket, proof, and config for new session.
@@ -1743,7 +1745,11 @@
 
   EXPECT_TRUE(socket_data1.AllReadDataConsumed());
   EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
-  // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
+
+  EXPECT_TRUE(HasActiveSession(server2));
+
+  // No zombie entry in session map.
+  EXPECT_FALSE(HasActiveSession(host_port_pair_));
 }
 
 TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
@@ -2511,7 +2517,7 @@
   EXPECT_THAT(callback_.WaitForResult(), IsOk());
   stream = CreateStream(&request2);
 
-  // Check a new active session exisits for the destination and the old session
+  // Check a new active session exists for the destination and the old session
   // is no longer live.
   EXPECT_TRUE(HasActiveSession(host_port_pair_));
   QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
@@ -2620,7 +2626,7 @@
   std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
   EXPECT_TRUE(stream2.get());
 
-  // Check an active session exisits for the destination.
+  // Check an active session exists for the destination.
   EXPECT_TRUE(HasActiveSession(host_port_pair_));
   EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
   QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
diff --git a/net/quiche/common/platform/impl/quiche_test_impl.cc b/net/quiche/common/platform/impl/quiche_test_impl.cc
new file mode 100644
index 0000000..8b70d6a
--- /dev/null
+++ b/net/quiche/common/platform/impl/quiche_test_impl.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quiche/common/platform/impl/quiche_test_impl.h"
+
+#include <string>
+
+#include "base/files/file_path.h"
+#include "net/test/test_data_directory.h"
+
+namespace quiche {
+namespace test {
+
+std::string QuicheGetCommonSourcePathImpl() {
+  base::FilePath net_path = net::GetTestNetDirectory();
+  return net_path.AppendASCII("third_party/quiche/common").MaybeAsASCII();
+}
+
+}  // namespace test
+}  // namespace quiche
diff --git a/net/quiche/common/platform/impl/quiche_test_impl.h b/net/quiche/common/platform/impl/quiche_test_impl.h
index a2db91e..43475be0 100644
--- a/net/quiche/common/platform/impl/quiche_test_impl.h
+++ b/net/quiche/common/platform/impl/quiche_test_impl.h
@@ -10,10 +10,14 @@
 
 namespace quiche {
 namespace test {
+
 class QuicheTest : public ::testing::Test {};
 
 template <class T>
 class QuicheTestWithParamImpl : public ::testing::TestWithParam<T> {};
+
+std::string QuicheGetCommonSourcePathImpl();
+
 }  // namespace test
 }  // namespace quiche
 
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index d5defb17..a9dbfe8f 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -13,8 +13,8 @@
 #include <string>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
-#include "base/stl_util.h"
 #include "base/strings/string_piece.h"
 #include "crypto/ec_private_key.h"
 #include "crypto/ec_signature_creator.h"
diff --git a/net/test/spawned_test_server/local_test_server.cc b/net/test/spawned_test_server/local_test_server.cc
index a389fe5..8cbb9da 100644
--- a/net/test/spawned_test_server/local_test_server.cc
+++ b/net/test/spawned_test_server/local_test_server.cc
@@ -205,7 +205,7 @@
     // Add arguments from a list.
     if (value.is_list()) {
       const base::ListValue* list = nullptr;
-      if (!value.GetAsList(&list) || !list || list->empty())
+      if (!value.GetAsList(&list) || !list || list->GetList().empty())
         return false;
       for (const auto& entry : list->GetList()) {
         if (!AppendArgumentFromJSONValue(key, entry, command_line))
diff --git a/net/test/test_data_directory.cc b/net/test/test_data_directory.cc
index b6a79541..80540f3 100644
--- a/net/test/test_data_directory.cc
+++ b/net/test/test_data_directory.cc
@@ -12,9 +12,12 @@
 
 namespace {
 
-// Net data directory, relative to source root.
+// Net directory, relative to source root.
+const base::FilePath::CharType kNetRelativePath[] = FILE_PATH_LITERAL("net");
+
+// Net data directory, relative to net directory.
 const base::FilePath::CharType kNetDataRelativePath[] =
-    FILE_PATH_LITERAL("net/data");
+    FILE_PATH_LITERAL("data");
 
 // Test certificates directory, relative to kNetDataRelativePath.
 const base::FilePath::CharType kCertificateDataSubPath[] =
@@ -22,14 +25,18 @@
 
 }  // namespace
 
-base::FilePath GetTestNetDataDirectory() {
+base::FilePath GetTestNetDirectory() {
   base::FilePath src_root;
   {
     base::ScopedAllowBlockingForTesting allow_blocking;
     base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
   }
 
-  return src_root.Append(kNetDataRelativePath);
+  return src_root.Append(kNetRelativePath);
+}
+
+base::FilePath GetTestNetDataDirectory() {
+  return GetTestNetDirectory().Append(kNetDataRelativePath);
 }
 
 base::FilePath GetTestCertsDirectory() {
diff --git a/net/test/test_data_directory.h b/net/test/test_data_directory.h
index f7ab7ee..7d5711c 100644
--- a/net/test/test_data_directory.h
+++ b/net/test/test_data_directory.h
@@ -9,6 +9,10 @@
 
 namespace net {
 
+// Returns the FilePath object representing the absolute path of //net in the
+// source tree.
+base::FilePath GetTestNetDirectory();
+
 // Returns the FilePath object representing the absolute path in the source
 // tree that contains net data files.
 base::FilePath GetTestNetDataDirectory();
diff --git a/net/third_party/quiche/BUILD.gn b/net/third_party/quiche/BUILD.gn
index 8cc5df4..eff11d7 100644
--- a/net/third_party/quiche/BUILD.gn
+++ b/net/third_party/quiche/BUILD.gn
@@ -556,8 +556,6 @@
     "src/quic/platform/api/quic_error_code_wrappers.h",
     "src/quic/platform/api/quic_export.h",
     "src/quic/platform/api/quic_exported_stats.h",
-    "src/quic/platform/api/quic_file_utils.cc",
-    "src/quic/platform/api/quic_file_utils.h",
     "src/quic/platform/api/quic_flag_utils.h",
     "src/quic/platform/api/quic_flags.h",
     "src/quic/platform/api/quic_hostname_utils.cc",
@@ -867,6 +865,17 @@
   ]
 }
 
+source_set("quiche_file_utils") {
+  sources = [
+    "src/common/platform/api/quiche_file_utils.cc",
+    "src/common/platform/api/quiche_file_utils.h",
+    "src/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.cc",
+    "src/common/platform/default/quiche_platform_impl/quiche_file_utils_impl.h",
+  ]
+  configs += [ ":quiche_config" ]
+  deps = [ "//base" ]
+}
+
 source_set("quic_test_tools_core") {
   testonly = true
   sources = [
@@ -1003,6 +1012,7 @@
   ]
 
   deps = [
+    ":quiche_file_utils",
     "//base",
     "//crypto:test_support",
     "//net",
@@ -1098,6 +1108,7 @@
     "src/quic/tools/simple_ticket_crypter.h",
   ]
   deps = [
+    ":quiche_file_utils",
     "//base",
     "//base/third_party/dynamic_annotations",
     "//net",
@@ -1134,6 +1145,7 @@
   executable("quic_packet_printer") {
     sources = [ "src/quic/tools/quic_packet_printer_bin.cc" ]
     deps = [
+      ":quiche_file_utils",
       "//base",
       "//build/win:default_exe_manifest",
       "//net",
@@ -1183,6 +1195,8 @@
 source_set("quiche_tests") {
   testonly = true
   sources = [
+    # TODO(bnc): Include in tests after test data files are added to QUICHE.
+    # "src/common/platform/api/quiche_file_utils_test.cc",
     "src/common/platform/api/quiche_time_utils_test.cc",
     "src/common/quiche_circular_deque_test.cc",
     "src/common/quiche_data_writer_test.cc",
@@ -1454,6 +1468,7 @@
   ]
 
   deps = [
+    ":quiche_file_utils",
     "//net",
     "//net:quic_test_tools",
     "//net:quiche_test_tools",
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 75e4d12..d416b409 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -258,7 +258,7 @@
   g_isolate_holder = new gin::IsolateHolder(
       base::ThreadTaskRunnerHandle::Get(), gin::IsolateHolder::kSingleThread,
       gin::IsolateHolder::IsolateType::kUtility);
-  g_isolate_holder->isolate()->Enter();
+
 #if defined(PDF_ENABLE_XFA)
   gin::InitializeCppgcFromV8Platform();
 #endif
@@ -268,7 +268,7 @@
 #if defined(PDF_ENABLE_XFA)
   cppgc::ShutdownProcess();
 #endif
-  g_isolate_holder->isolate()->Exit();
+
   delete g_isolate_holder;
   g_isolate_holder = nullptr;
 }
@@ -505,7 +505,7 @@
 #if defined(PDF_ENABLE_V8)
   if (enable_v8) {
     SetUpV8();
-    config.m_pIsolate = v8::Isolate::GetCurrent();
+    config.m_pIsolate = g_isolate_holder->isolate();
     // NOTE: static_cast<> prior to assigning to (void*) is safer since it
     // will manipulate the pointer value should gin::V8Platform someday have
     // multiple base classes.
diff --git a/pdf/pdfium/pdfium_font_linux.cc b/pdf/pdfium/pdfium_font_linux.cc
index 4f1d365..77a5d5a 100644
--- a/pdf/pdfium/pdfium_font_linux.cc
+++ b/pdf/pdfium/pdfium_font_linux.cc
@@ -7,13 +7,13 @@
 #include <memory>
 #include <string>
 
+#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/i18n/encoding_detection.h"
 #include "base/i18n/icu_string_conversions.h"
 #include "base/no_destructor.h"
 #include "base/numerics/ranges.h"
 #include "base/sequence_checker.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "components/services/font/public/cpp/font_loader.h"
 #include "pdf/font_table_linux.h"
diff --git a/ppapi/cpp/dev/file_chooser_dev.cc b/ppapi/cpp/dev/file_chooser_dev.cc
index 333eb6f8..e2654a1 100644
--- a/ppapi/cpp/dev/file_chooser_dev.cc
+++ b/ppapi/cpp/dev/file_chooser_dev.cc
@@ -42,7 +42,11 @@
 }
 
 FileChooser_Dev::FileChooser_Dev(const FileChooser_Dev& other)
-    : Resource(other) {
+    : Resource(other) {}
+
+FileChooser_Dev& FileChooser_Dev::operator=(const FileChooser_Dev& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 int32_t FileChooser_Dev::Show(
diff --git a/ppapi/cpp/dev/file_chooser_dev.h b/ppapi/cpp/dev/file_chooser_dev.h
index b31c7386..74ae5fb 100644
--- a/ppapi/cpp/dev/file_chooser_dev.h
+++ b/ppapi/cpp/dev/file_chooser_dev.h
@@ -51,6 +51,7 @@
                   const Var& accept_types);
 
   FileChooser_Dev(const FileChooser_Dev& other);
+  FileChooser_Dev& operator=(const FileChooser_Dev& other);
 
   /// This function displays a previously created file chooser resource as a
   /// dialog box, prompting the user to choose a file or files. This function
diff --git a/ppapi/cpp/file_io.cc b/ppapi/cpp/file_io.cc
index 640016c..be22fe73 100644
--- a/ppapi/cpp/file_io.cc
+++ b/ppapi/cpp/file_io.cc
@@ -28,8 +28,7 @@
 
 }  // namespace
 
-FileIO::FileIO() {
-}
+FileIO::FileIO() {}
 
 FileIO::FileIO(const InstanceHandle& instance) {
   if (has_interface<PPB_FileIO_1_1>()) {
@@ -41,8 +40,11 @@
   }
 }
 
-FileIO::FileIO(const FileIO& other)
-    : Resource(other) {
+FileIO::FileIO(const FileIO& other) : Resource(other) {}
+
+FileIO& FileIO::operator=(const FileIO& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 int32_t FileIO::Open(const FileRef& file_ref,
diff --git a/ppapi/cpp/file_io.h b/ppapi/cpp/file_io.h
index 3f3faaa7..93d39a1b 100644
--- a/ppapi/cpp/file_io.h
+++ b/ppapi/cpp/file_io.h
@@ -39,6 +39,7 @@
   ///
   /// @param[in] other A reference to a <code>FileIO</code>.
   FileIO(const FileIO& other);
+  FileIO& operator=(const FileIO& other);
 
   /// Open() opens the specified regular file for I/O according to the given
   /// open flags, which is a bit-mask of the PP_FileOpenFlags values.  Upon
diff --git a/ppapi/cpp/file_ref.cc b/ppapi/cpp/file_ref.cc
index f9294a7e..444d0ca 100644
--- a/ppapi/cpp/file_ref.cc
+++ b/ppapi/cpp/file_ref.cc
@@ -49,8 +49,11 @@
   }
 }
 
-FileRef::FileRef(const FileRef& other)
-    : Resource(other) {
+FileRef::FileRef(const FileRef& other) : Resource(other) {}
+
+FileRef& FileRef::operator=(const FileRef& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 PP_FileSystemType FileRef::GetFileSystemType() const {
diff --git a/ppapi/cpp/file_ref.h b/ppapi/cpp/file_ref.h
index 9f94088..b3bc89f 100644
--- a/ppapi/cpp/file_ref.h
+++ b/ppapi/cpp/file_ref.h
@@ -58,6 +58,7 @@
   ///
   /// @param[in] other A pointer to a <code>FileRef</code>.
   FileRef(const FileRef& other);
+  FileRef& operator=(const FileRef& other);
 
   /// GetFileSystemType() returns the type of the file system.
   ///
diff --git a/ppapi/cpp/message_loop.cc b/ppapi/cpp/message_loop.cc
index df38007..917f5b74 100644
--- a/ppapi/cpp/message_loop.cc
+++ b/ppapi/cpp/message_loop.cc
@@ -20,8 +20,7 @@
 
 }  // namespace
 
-MessageLoop::MessageLoop() : Resource() {
-}
+MessageLoop::MessageLoop() : Resource() {}
 
 MessageLoop::MessageLoop(const InstanceHandle& instance) : Resource() {
   if (has_interface<PPB_MessageLoop>()) {
@@ -30,8 +29,11 @@
   }
 }
 
-MessageLoop::MessageLoop(const MessageLoop& other)
-    : Resource(other) {
+MessageLoop::MessageLoop(const MessageLoop& other) : Resource(other) {}
+
+MessageLoop& MessageLoop::operator=(const MessageLoop& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 MessageLoop::MessageLoop(PP_Resource pp_message_loop)
diff --git a/ppapi/cpp/message_loop.h b/ppapi/cpp/message_loop.h
index c97fdf52..bf468ce5 100644
--- a/ppapi/cpp/message_loop.h
+++ b/ppapi/cpp/message_loop.h
@@ -146,6 +146,7 @@
   explicit MessageLoop(const InstanceHandle& instance);
 
   MessageLoop(const MessageLoop& other);
+  MessageLoop& operator=(const MessageLoop& other);
 
   /// Takes an additional ref to the resource.
   explicit MessageLoop(PP_Resource pp_message_loop);
diff --git a/ppapi/cpp/url_loader.cc b/ppapi/cpp/url_loader.cc
index 1be87a7..d666374 100644
--- a/ppapi/cpp/url_loader.cc
+++ b/ppapi/cpp/url_loader.cc
@@ -34,7 +34,11 @@
       instance.pp_instance()));
 }
 
-URLLoader::URLLoader(const URLLoader& other) : Resource(other) {
+URLLoader::URLLoader(const URLLoader& other) : Resource(other) {}
+
+URLLoader& URLLoader::operator=(const URLLoader& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 int32_t URLLoader::Open(const URLRequestInfo& request_info,
diff --git a/ppapi/cpp/url_loader.h b/ppapi/cpp/url_loader.h
index 00c086e..574dd621 100644
--- a/ppapi/cpp/url_loader.h
+++ b/ppapi/cpp/url_loader.h
@@ -44,6 +44,7 @@
   ///
   /// @param other A <code>URLLoader</code> to be copied.
   URLLoader(const URLLoader& other);
+  URLLoader& operator=(const URLLoader& other);
 
   /// This function begins loading the <code>URLRequestInfo</code>.
   /// The operation completes when response headers are received or when an
diff --git a/ppapi/cpp/url_response_info.cc b/ppapi/cpp/url_response_info.cc
index 032b405..c0c6d48 100644
--- a/ppapi/cpp/url_response_info.cc
+++ b/ppapi/cpp/url_response_info.cc
@@ -19,7 +19,11 @@
 }  // namespace
 
 URLResponseInfo::URLResponseInfo(const URLResponseInfo& other)
-    : Resource(other) {
+    : Resource(other) {}
+
+URLResponseInfo& URLResponseInfo::operator=(const URLResponseInfo& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 URLResponseInfo::URLResponseInfo(PassRef, PP_Resource resource)
diff --git a/ppapi/cpp/url_response_info.h b/ppapi/cpp/url_response_info.h
index e431b46..f5bf875 100644
--- a/ppapi/cpp/url_response_info.h
+++ b/ppapi/cpp/url_response_info.h
@@ -33,6 +33,7 @@
 
   /// The copy constructor for <code>URLResponseInfo</code>.
   URLResponseInfo(const URLResponseInfo& other);
+  URLResponseInfo& operator=(const URLResponseInfo& other);
 
   /// This function gets a response property.
   ///
diff --git a/ppapi/cpp/video_encoder.cc b/ppapi/cpp/video_encoder.cc
index eab719f..4a61828f 100644
--- a/ppapi/cpp/video_encoder.cc
+++ b/ppapi/cpp/video_encoder.cc
@@ -77,8 +77,7 @@
 
 }  // namespace
 
-VideoEncoder::VideoEncoder() {
-}
+VideoEncoder::VideoEncoder() {}
 
 VideoEncoder::VideoEncoder(const InstanceHandle& instance) {
   if (has_interface<PPB_VideoEncoder_0_2>()) {
@@ -90,7 +89,11 @@
   }
 }
 
-VideoEncoder::VideoEncoder(const VideoEncoder& other) : Resource(other) {
+VideoEncoder::VideoEncoder(const VideoEncoder& other) : Resource(other) {}
+
+VideoEncoder& VideoEncoder::operator=(const VideoEncoder& other) {
+  Resource::operator=(other);
+  return *this;
 }
 
 int32_t VideoEncoder::GetSupportedProfiles(const CompletionCallbackWithOutput<
diff --git a/ppapi/cpp/video_encoder.h b/ppapi/cpp/video_encoder.h
index 1a801850..7676ecd7 100644
--- a/ppapi/cpp/video_encoder.h
+++ b/ppapi/cpp/video_encoder.h
@@ -57,6 +57,7 @@
   /// The copy constructor for <code>VideoEncoder</code>.
   /// @param[in] other A reference to a <code>VideoEncoder</code>.
   VideoEncoder(const VideoEncoder& other);
+  VideoEncoder& operator=(const VideoEncoder& other);
 
   /// Gets an array of supported video encoder profiles.
   /// These can be used to choose a profile before calling Initialize().
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn b/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn
index 2526718..cda0cca 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/BUILD.gn
@@ -5,6 +5,10 @@
 assert(is_nacl,
        "These targets must only be built using the untrusted NaCl toolchains.")
 
+source_set("irt_ppapi") {
+  sources = [ "//ppapi/nacl_irt/irt_ppapi.h" ]
+}
+
 # We need to actually ship this library in the SDK.
 static_library("aot") {
   output_name = "pnacl_irt_shim"
@@ -14,6 +18,10 @@
     "shim_entry.c",
     "shim_ppapi.c",
   ]
+  deps = [
+    ":irt_ppapi",
+    "//ppapi/c",
+  ]
 
   # Indicate that this variant of the shim library should not depend on
   # the unstable/private IRT hook interface.
@@ -41,4 +49,8 @@
     "irt_shim_ppapi.c",
     "pnacl_shim.c",
   ]
+  deps = [
+    ":irt_ppapi",
+    "//ppapi/c",
+  ]
 }
diff --git a/ppapi/proxy/tcp_socket_resource_base.cc b/ppapi/proxy/tcp_socket_resource_base.cc
index be3ba247..19935c2 100644
--- a/ppapi/proxy/tcp_socket_resource_base.cc
+++ b/ppapi/proxy/tcp_socket_resource_base.cc
@@ -8,8 +8,8 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/notreached.h"
-#include "base/stl_util.h"
 #include "ppapi/c/pp_bool.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/proxy/error_conversion.h"
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
index 3367f55..307fc60 100644
--- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
+++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
@@ -50,9 +50,7 @@
       return PP_MakeInt32(value->GetInt());
     }
     case base::Value::Type::DOUBLE: {
-      double val;
-      value->GetAsDouble(&val);
-      return PP_MakeDouble(val);
+      return PP_MakeDouble(value->GetDouble());
     }
     case base::Value::Type::STRING: {
       std::string val;
diff --git a/printing/backend/cups_connection.cc b/printing/backend/cups_connection.cc
index c76a791b..bd8f003 100644
--- a/printing/backend/cups_connection.cc
+++ b/printing/backend/cups_connection.cc
@@ -11,14 +11,13 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "printing/backend/cups_helper.h"
 #include "printing/backend/cups_jobs.h"
 
 namespace printing {
 
 namespace {
 
-constexpr int kTimeoutMs = 3000;
-
 // The number of jobs we'll retrieve for a queue.  We expect a user to queue at
 // most 10 jobs per printer.  If they queue more, they won't receive updates for
 // the 11th job until one finishes.
@@ -86,18 +85,11 @@
       LOG(WARNING) << "CUPS connection failed: ";
       return false;
     }
-
-    // On macOS, AirPrint destinations show up even if they're not added to the
-    // system, and their capabilities cannot be read in that situation
-    // (crbug.com/1027834). Therefore, only show discovered destinations that
-    // have been added locally. Also exclude fax and scanner devices.
-    constexpr cups_ptype_t kMask =
-        CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED;
     DestinationEnumerator enumerator;
     const int success =
-        cupsEnumDests(CUPS_DEST_FLAGS_NONE, kTimeoutMs,
+        cupsEnumDests(CUPS_DEST_FLAGS_NONE, kCupsTimeoutMs,
                       /*cancel=*/nullptr,
-                      /*type=*/CUPS_PRINTER_LOCAL, kMask,
+                      /*type=*/CUPS_PRINTER_LOCAL, kDestinationsFilterMask,
                       &DestinationEnumerator::cups_callback, &enumerator);
 
     if (!success) {
@@ -199,7 +191,7 @@
 
     cups_http_.reset(httpConnect2(host.c_str(), port, nullptr, AF_UNSPEC,
                                   cups_encryption_, blocking_ ? 1 : 0,
-                                  kTimeoutMs, nullptr));
+                                  kCupsTimeoutMs, nullptr));
     return !!cups_http_;
   }
 
diff --git a/printing/backend/cups_helper.h b/printing/backend/cups_helper.h
index 3b6fb68..e28b48c 100644
--- a/printing/backend/cups_helper.h
+++ b/printing/backend/cups_helper.h
@@ -17,6 +17,18 @@
 
 struct PrinterSemanticCapsAndDefaults;
 
+// Time willing to wait for individual CUPS calls to complete, such as
+// establishing a new connection or enumerating list of printers.
+constexpr int kCupsTimeoutMs = 3000;
+
+// Exclude fax and scanner devices when enumerating printers.
+// Also exclude discovered printers that have not been added locally.
+// On macOS, AirPrint destinations show up even if they're not added to
+// the system, and their capabilities cannot be read in that situation.
+// (crbug.com/1027834)
+constexpr cups_ptype_t kDestinationsFilterMask =
+    CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED;
+
 // Helper wrapper around http_t structure, with connection and cleanup
 // functionality.
 class COMPONENT_EXPORT(PRINT_BACKEND) HttpConnectionCUPS {
diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc
index 7c23d2a7..4148bd71 100644
--- a/printing/backend/print_backend_cups.cc
+++ b/printing/backend/print_backend_cups.cc
@@ -4,6 +4,7 @@
 
 #include "printing/backend/print_backend_cups.h"
 
+#include <cups/cups.h>
 #include <cups/ppd.h>
 #include <dlfcn.h>
 #include <errno.h>
@@ -35,6 +36,27 @@
 
 namespace printing {
 
+namespace {
+
+struct CupsDestsData {
+  int num_dests;
+  cups_dest_t* dests;
+};
+
+int CaptureCupsDestCallback(void* data, unsigned flags, cups_dest_t* dest) {
+  CupsDestsData* dests_data = reinterpret_cast<CupsDestsData*>(data);
+  if (flags & CUPS_DEST_FLAGS_REMOVED) {
+    dests_data->num_dests = cupsRemoveDest(
+        dest->name, dest->instance, dests_data->num_dests, &dests_data->dests);
+  } else {
+    dests_data->num_dests =
+        cupsCopyDest(dest, dests_data->num_dests, &dests_data->dests);
+  }
+  return 1;  // Keep going.
+}
+
+}  // namespace
+
 PrintBackendCUPS::PrintBackendCUPS(const GURL& print_server_url,
                                    http_encryption_t encryption,
                                    bool blocking,
@@ -55,14 +77,7 @@
   if (type_str) {
     cups_ptype_t type;
     if (base::StringToUint(type_str, &type)) {
-      // Exclude fax and scanner devices.
-      // Also exclude discovered printers that have not been added locally.
-      // On macOS, AirPrint destinations show up even if they're not added to
-      // the system, and their capabilities cannot be read in that situation.
-      // (crbug.com/1027834)
-      constexpr cups_ptype_t kMask =
-          CUPS_PRINTER_FAX | CUPS_PRINTER_SCANNER | CUPS_PRINTER_DISCOVERED;
-      if (type & kMask)
+      if (type & kDestinationsFilterMask)
         return mojom::ResultCode::kFailed;
     }
   }
@@ -125,15 +140,39 @@
   DCHECK(printer_list);
   printer_list->clear();
 
-  cups_dest_t* destinations = nullptr;
-  int num_dests = GetDests(&destinations);
-  DCHECK_GE(num_dests, 0);
-  if (!num_dests) {
+  // If possible prefer to use cupsEnumDests() over GetDests(), because the
+  // latter has been found to filter out some destination values if a device
+  // reports multiple times (crbug.com/1209175), which can lead to destinations
+  // not showing as available.  Using cupsEnumDests() allows us to do our own
+  // filtering should any duplicates occur.
+  CupsDestsData dests_data = {0, nullptr};
+  ipp_status_t last_error = IPP_STATUS_OK;
+  if (print_server_url_.is_empty()) {
+    VLOG(1) << "CUPS: using cupsEnumDests to enumerate printers";
+    if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, kCupsTimeoutMs,
+                       /*cancel=*/nullptr,
+                       /*type=*/CUPS_PRINTER_LOCAL, kDestinationsFilterMask,
+                       CaptureCupsDestCallback, &dests_data)) {
+      // Free any allocations and reset data, and then fall through to common
+      // error handling below.
+      last_error = cupsLastError();
+      cupsFreeDests(dests_data.num_dests, dests_data.dests);
+      dests_data.num_dests = 0;
+      dests_data.dests = nullptr;
+    }
+  } else {
+    VLOG(1) << "CUPS: using cupsGetDests2 to enumerate printers";
+    dests_data.num_dests = GetDests(&dests_data.dests);
+    if (!dests_data.num_dests)
+      last_error = cupsLastError();
+  }
+
+  DCHECK_GE(dests_data.num_dests, 0);
+  if (!dests_data.num_dests) {
     // No destinations could mean the operation failed or that there are simply
     // no printer drivers installed.  Rely upon CUPS error code to distinguish
     // between these.
-    DCHECK(!destinations);
-    const ipp_status_t last_error = cupsLastError();
+    DCHECK(!dests_data.dests);
     if (last_error != IPP_STATUS_ERROR_NOT_FOUND) {
       VLOG(1) << "CUPS: Error getting printers from CUPS server"
               << ", server: " << print_server_url_
@@ -145,8 +184,9 @@
     return mojom::ResultCode::kSuccess;
   }
 
-  for (int printer_index = 0; printer_index < num_dests; ++printer_index) {
-    const cups_dest_t& printer = destinations[printer_index];
+  for (int printer_index = 0; printer_index < dests_data.num_dests;
+       ++printer_index) {
+    const cups_dest_t& printer = dests_data.dests[printer_index];
 
     PrinterBasicInfo printer_info;
     if (PrinterBasicInfoFromCUPS(printer, &printer_info) ==
@@ -155,7 +195,7 @@
     }
   }
 
-  cupsFreeDests(num_dests, destinations);
+  cupsFreeDests(dests_data.num_dests, dests_data.dests);
 
   VLOG(1) << "CUPS: Enumerated printers, server: " << print_server_url_
           << ", # of printers: " << printer_list->size();
diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc
index e9d5772..067e186c 100644
--- a/printing/backend/win_helper.cc
+++ b/printing/backend/win_helper.cc
@@ -11,13 +11,13 @@
 #include <memory>
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/file_version_info.h"
 #include "base/files/file_path.h"
 #include "base/memory/free_deleter.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/printing/printing_context_system_dialog_win.cc b/printing/printing_context_system_dialog_win.cc
index fe7fc79..891e957 100644
--- a/printing/printing_context_system_dialog_win.cc
+++ b/printing/printing_context_system_dialog_win.cc
@@ -7,7 +7,7 @@
 #include <utility>
 
 #include "base/auto_reset.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/current_thread.h"
 #include "printing/backend/win_helper.h"
diff --git a/printing/printing_test.h b/printing/printing_test.h
index 0839204..d9b0881 100644
--- a/printing/printing_test.h
+++ b/printing/printing_test.h
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 
 // Disable the whole test case when executing on a computer that has no printer
 // installed.
diff --git a/remoting/codec/audio_decoder_opus.cc b/remoting/codec/audio_decoder_opus.cc
index 752681f..26106285 100644
--- a/remoting/codec/audio_decoder_opus.cc
+++ b/remoting/codec/audio_decoder_opus.cc
@@ -6,8 +6,8 @@
 
 #include <stdint.h>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "remoting/proto/audio.pb.h"
 #include "third_party/opus/src/include/opus.h"
diff --git a/remoting/codec/audio_encoder_opus.cc b/remoting/codec/audio_encoder_opus.cc
index bae671d..9e02013 100644
--- a/remoting/codec/audio_encoder_opus.cc
+++ b/remoting/codec/audio_encoder_opus.cc
@@ -5,8 +5,8 @@
 #include "remoting/codec/audio_encoder_opus.h"
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "media/base/audio_bus.h"
 #include "media/base/multi_channel_resampler.h"
diff --git a/remoting/codec/video_encoder_verbatim.cc b/remoting/codec/video_encoder_verbatim.cc
index 06887d48..b217af7 100644
--- a/remoting/codec/video_encoder_verbatim.cc
+++ b/remoting/codec/video_encoder_verbatim.cc
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "base/check.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "remoting/base/util.h"
 #include "remoting/proto/video.pb.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index afafb12a..bda4225 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -163,6 +163,13 @@
     deps += [ "//remoting/host/mac:constants" ]
   }
 }
+source_set("host_extension") {
+  sources = [
+    "client_session_details.h",
+    "host_extension.h",
+    "host_extension_session.h",
+  ]
+}
 
 # This must be a static library instead of a source set because
 # remoting_unittests requires that remoting_me2me_host.cc not be pulled in,
@@ -200,7 +207,6 @@
     "chromoting_param_traits_impl.h",
     "client_session.cc",
     "client_session.h",
-    "client_session_details.h",
     "config_file_watcher.cc",
     "config_file_watcher.h",
     "config_watcher.h",
@@ -256,8 +262,6 @@
     "host_experiment_session_plugin.cc",
     "host_experiment_session_plugin.h",
     "host_export.h",
-    "host_extension.h",
-    "host_extension_session.h",
     "host_extension_session_manager.cc",
     "host_extension_session_manager.h",
     "host_power_save_blocker.cc",
@@ -401,6 +405,7 @@
   ]
 
   public_deps = [
+    ":host_extension",
     "//ipc",
     "//remoting/proto",
     "//remoting/proto/remoting/v1:directory_proto",
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
index f91320a..03d4465 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/location.h"
@@ -18,7 +19,6 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/stringize_macros.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
diff --git a/remoting/host/linux/audio_pipe_reader.cc b/remoting/host/linux/audio_pipe_reader.cc
index 4f44c2f..031179e1 100644
--- a/remoting/host/linux/audio_pipe_reader.cc
+++ b/remoting/host/linux/audio_pipe_reader.cc
@@ -13,9 +13,9 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
-#include "base/stl_util.h"
 
 namespace remoting {
 
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc
index 1663724..1c133b54 100644
--- a/remoting/host/native_messaging/native_messaging_reader.cc
+++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/json/json_reader.h"
 #include "base/location.h"
@@ -18,7 +19,6 @@
 #include "base/message_loop/message_pump_type.h"
 #include "base/sequenced_task_runner.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
diff --git a/remoting/host/native_messaging/native_messaging_writer_unittest.cc b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
index b2f9cbce..6b788c6e 100644
--- a/remoting/host/native_messaging/native_messaging_writer_unittest.cc
+++ b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
@@ -9,8 +9,8 @@
 #include <memory>
 #include <utility>
 
+#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
-#include "base/stl_util.h"
 #include "base/values.h"
 #include "remoting/host/setup/test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/remoting/host/pairing_registry_delegate_win_unittest.cc b/remoting/host/pairing_registry_delegate_win_unittest.cc
index fcd875f..e51cbc8 100644
--- a/remoting/host/pairing_registry_delegate_win_unittest.cc
+++ b/remoting/host/pairing_registry_delegate_win_unittest.cc
@@ -53,7 +53,7 @@
   delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
 
   // Check that registry is initially empty.
-  EXPECT_TRUE(delegate->LoadAll()->empty());
+  EXPECT_TRUE(delegate->LoadAll()->GetList().empty());
 
   // Add a couple of pairings.
   PairingRegistry::Pairing pairing1(base::Time::Now(), "xxx", "xxx", "xxx");
@@ -84,7 +84,7 @@
 
   // Delete the rest and verify.
   EXPECT_TRUE(delegate->DeleteAll());
-  EXPECT_TRUE(delegate->LoadAll()->empty());
+  EXPECT_TRUE(delegate->LoadAll()->GetList().empty());
 }
 
 // Verifies that the delegate is stateless by using two different instances.
diff --git a/remoting/host/security_key/BUILD.gn b/remoting/host/security_key/BUILD.gn
index b9c55c5..57adea1 100644
--- a/remoting/host/security_key/BUILD.gn
+++ b/remoting/host/security_key/BUILD.gn
@@ -39,6 +39,7 @@
     "//mojo/public/cpp/system",
     "//net:net",
     "//net/traffic_annotation:traffic_annotation",
+    "//remoting/host:host_extension",
     "//remoting/proto",
     "//remoting/protocol:protocol",
     "//third_party/webrtc_overrides:webrtc_component",
@@ -145,6 +146,7 @@
   deps = [
     ":security_key",
     "//ipc",
+    "//remoting/host:common",
     "//remoting/proto",
     "//testing/gtest",
   ]
diff --git a/remoting/host/security_key/security_key_ipc_client.cc b/remoting/host/security_key/security_key_ipc_client.cc
index 08a58f1..27ce21e 100644
--- a/remoting/host/security_key/security_key_ipc_client.cc
+++ b/remoting/host/security_key/security_key_ipc_client.cc
@@ -11,12 +11,12 @@
 #include "base/callback.h"
 #include "base/logging.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_message_macros.h"
 #include "remoting/host/chromoting_messages.h"
-#include "remoting/host/ipc_constants.h"
 #include "remoting/host/security_key/security_key_ipc_constants.h"
 
 namespace remoting {
diff --git a/remoting/host/security_key/security_key_ipc_server.cc b/remoting/host/security_key/security_key_ipc_server.cc
index 2ae4748..0fcae0f3 100644
--- a/remoting/host/security_key/security_key_ipc_server.cc
+++ b/remoting/host/security_key/security_key_ipc_server.cc
@@ -16,7 +16,6 @@
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_message_macros.h"
 #include "remoting/base/logging.h"
-#include "remoting/host/chromoting_messages.h"
 #include "remoting/host/security_key/security_key_ipc_server_impl.h"
 
 namespace {
diff --git a/remoting/host/security_key/security_key_message_reader_impl.cc b/remoting/host/security_key/security_key_message_reader_impl.cc
index 877e163..6140f9d7 100644
--- a/remoting/host/security_key/security_key_message_reader_impl.cc
+++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -9,12 +9,12 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/message_loop/message_pump_type.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "remoting/host/security_key/security_key_message.h"
 
diff --git a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc
index efb40ca..1d6fea44 100644
--- a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc
+++ b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc
@@ -9,8 +9,8 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/task_runner_util.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread.h"
diff --git a/remoting/ios/app/BUILD.gn b/remoting/ios/app/BUILD.gn
index 38c539c5..8b911c5 100644
--- a/remoting/ios/app/BUILD.gn
+++ b/remoting/ios/app/BUILD.gn
@@ -67,6 +67,12 @@
     "remoting_view_controller.mm",
     "session_reconnect_view.h",
     "session_reconnect_view.mm",
+    "settings/remoting_settings_view_controller.h",
+    "settings/remoting_settings_view_controller.mm",
+    "settings/setting_option.h",
+    "settings/setting_option.mm",
+    "settings/settings_view_cell.h",
+    "settings/settings_view_cell.mm",
     "side_menu_items.h",
     "side_menu_items.mm",
     "user_status_presenter.h",
@@ -88,7 +94,6 @@
     "//remoting/client/notification",
     "//remoting/ios:ios_core",
     "//remoting/ios/app/resources:assets",
-    "//remoting/ios/app/settings",
     "//remoting/ios/audio",
     "//remoting/ios/display",
     "//remoting/ios/domain",
diff --git a/remoting/ios/app/settings/BUILD.gn b/remoting/ios/app/settings/BUILD.gn
deleted file mode 100644
index 64d65914..0000000
--- a/remoting/ios/app/settings/BUILD.gn
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/apple/tweak_info_plist.gni")
-import("//build/config/chrome_build.gni")
-import("//build/config/ios/rules.gni")
-import("//build/util/process_version.gni")
-import("//remoting/build/config/remoting_build.gni")
-
-source_set("settings") {
-  sources = [
-    "remoting_settings_view_controller.h",
-    "remoting_settings_view_controller.mm",
-    "setting_option.h",
-    "setting_option.mm",
-    "settings_view_cell.h",
-    "settings_view_cell.mm",
-  ]
-
-  deps = [
-    "//base",
-    "//remoting/base",
-    "//remoting/ios:ios_core",
-    "//ui/base",
-    "//ui/gfx",
-    "//ui/resources",
-  ]
-
-  public_deps = [ "//ios/third_party/material_components_ios" ]
-
-  configs += [ "//build/config/compiler:enable_arc" ]
-}
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn
index 7e36025..64acc85 100644
--- a/remoting/protocol/BUILD.gn
+++ b/remoting/protocol/BUILD.gn
@@ -389,7 +389,6 @@
     "negotiating_authenticator_unittest.cc",
     "pairing_registry_unittest.cc",
     "port_range_unittest.cc",
-    "ppapi_module_stub.cc",
     "pseudotcp_adapter_unittest.cc",
     "remoting_ice_config_request_unittest.cc",
     "sdp_message_unittest.cc",
diff --git a/remoting/protocol/pairing_registry_unittest.cc b/remoting/protocol/pairing_registry_unittest.cc
index 1fd7ad78..1bf66e38 100644
--- a/remoting/protocol/pairing_registry_unittest.cc
+++ b/remoting/protocol/pairing_registry_unittest.cc
@@ -175,7 +175,7 @@
   registry->GetAllPairings(base::BindOnce(&PairingRegistryTest::set_pairings,
                                           base::Unretained(this)));
 
-  EXPECT_TRUE(pairings_->empty());
+  EXPECT_TRUE(pairings_->GetList().empty());
 }
 
 ACTION_P(QuitMessageLoop, callback) {
@@ -187,7 +187,7 @@
 }
 
 MATCHER(NoPairings, "") {
-  return arg->empty();
+  return arg->GetList().empty();
 }
 
 TEST_F(PairingRegistryTest, SerializedRequests) {
diff --git a/remoting/protocol/ppapi_module_stub.cc b/remoting/protocol/ppapi_module_stub.cc
deleted file mode 100644
index 22d4f6c..0000000
--- a/remoting/protocol/ppapi_module_stub.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ppapi/cpp/module.h"
-
-namespace pp {
-
-// Factory function for your specialization of the Module object.
-Module* CreateModule() {
-  return nullptr;
-}
-
-}  // namespace pp
diff --git a/remoting/protocol/webrtc_dummy_video_encoder.cc b/remoting/protocol/webrtc_dummy_video_encoder.cc
index 7e58fbc..9e36743 100644
--- a/remoting/protocol/webrtc_dummy_video_encoder.cc
+++ b/remoting/protocol/webrtc_dummy_video_encoder.cc
@@ -9,9 +9,9 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper.cc b/remoting/protocol/webrtc_video_encoder_wrapper.cc
index 3f01fad8..1230d7b 100644
--- a/remoting/protocol/webrtc_video_encoder_wrapper.cc
+++ b/remoting/protocol/webrtc_video_encoder_wrapper.cc
@@ -12,9 +12,9 @@
 
 #include "base/bind.h"
 #include "base/bind_post_task.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
diff --git a/remoting/resources/remoting_strings_ca.xtb b/remoting/resources/remoting_strings_ca.xtb
index f456838..2d24b24 100644
--- a/remoting/resources/remoting_strings_ca.xtb
+++ b/remoting/resources/remoting_strings_ca.xtb
@@ -33,7 +33,7 @@
 <translation id="2509394361235492552">Connectat a <ph name="HOSTNAME" /></translation>
 <translation id="2540992418118313681">Voleu compartir aquest ordinador perquè un altre usuari el pugui veure i controlar?</translation>
 <translation id="2579271889603567289">L'amfitrió s'ha bloquejat o no s'ha pogut iniciar.</translation>
-<translation id="2599300881200251572">Aquest servei permet les connexions entrants de clients de l'escriptori remot de Chrome.</translation>
+<translation id="2599300881200251572">Aquest servei permet les connexions entrants de clients d'Escriptori remot de Chrome.</translation>
 <translation id="2647232381348739934">Servei de Chromoting</translation>
 <translation id="2676780859508944670">S'hi està treballant...</translation>
 <translation id="2699970397166997657">Chromoting</translation>
diff --git a/remoting/signaling/fake_signal_strategy.h b/remoting/signaling/fake_signal_strategy.h
index ae176c2..70d11e5 100644
--- a/remoting/signaling/fake_signal_strategy.h
+++ b/remoting/signaling/fake_signal_strategy.h
@@ -13,6 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/sequence_checker.h"
+#include "base/time/time.h"
 #include "remoting/signaling/iq_sender.h"
 #include "remoting/signaling/signal_strategy.h"
 #include "remoting/signaling/signaling_address.h"
diff --git a/remoting/test/fake_socket_factory.h b/remoting/test/fake_socket_factory.h
index deb357a..eb24f3f 100644
--- a/remoting/test/fake_socket_factory.h
+++ b/remoting/test/fake_socket_factory.h
@@ -14,6 +14,7 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "remoting/test/fake_network_dispatcher.h"
 #include "third_party/webrtc/api/packet_socket_factory.h"
 
diff --git a/sandbox/linux/bpf_dsl/test_trap_registry_unittest.cc b/sandbox/linux/bpf_dsl/test_trap_registry_unittest.cc
index 6f0f71f..05bca9ed 100644
--- a/sandbox/linux/bpf_dsl/test_trap_registry_unittest.cc
+++ b/sandbox/linux/bpf_dsl/test_trap_registry_unittest.cc
@@ -6,7 +6,7 @@
 
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sandbox {
diff --git a/sandbox/win/src/app_container_test.cc b/sandbox/win/src/app_container_test.cc
index 3e23197..ff897c1a 100644
--- a/sandbox/win/src/app_container_test.cc
+++ b/sandbox/win/src/app_container_test.cc
@@ -14,6 +14,7 @@
 #include "base/files/file_path.h"
 #include "base/hash/sha1.h"
 #include "base/logging.h"
+#include "base/process/process_info.h"
 #include "base/rand_util.h"
 #include "base/scoped_native_library.h"
 #include "base/strings/strcat.h"
@@ -411,6 +412,12 @@
   return SBOX_TEST_FAILED;
 }
 
+SBOX_TESTS_COMMAND int CheckIsAppContainer(int argc, wchar_t** argv) {
+  if (base::IsCurrentProcessInAppContainer())
+    return SBOX_TEST_SUCCEEDED;
+  return SBOX_TEST_FAILED;
+}
+
 TEST(AppContainerLaunchTest, CheckLPACACE) {
   if (base::win::GetVersion() < base::win::Version::WIN10_RS1)
     return;
@@ -422,4 +429,21 @@
   AppContainerBase::Delete(GetAppContainerProfileName().c_str());
 }
 
+TEST(AppContainerLaunchTest, IsAppContainer) {
+  if (base::win::GetVersion() < base::win::Version::WIN10_RS1)
+    return;
+  TestRunner runner;
+  AddNetworkAppContainerPolicy(runner.GetPolicy());
+
+  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIsAppContainer"));
+
+  AppContainerBase::Delete(GetAppContainerProfileName().c_str());
+}
+
+TEST(AppContainerLaunchTest, IsNotAppContainer) {
+  TestRunner runner;
+
+  EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"CheckIsAppContainer"));
+}
+
 }  // namespace sandbox
diff --git a/sandbox/win/src/win_utils.h b/sandbox/win/src/win_utils.h
index 5945cd60..085be2a 100644
--- a/sandbox/win/src/win_utils.h
+++ b/sandbox/win/src/win_utils.h
@@ -10,8 +10,8 @@
 #include <memory>
 #include <string>
 
+#include "base/cxx17_backports.h"
 #include "base/macros.h"
-#include "base/stl_util.h"
 #include "sandbox/win/src/nt_internals.h"
 
 namespace sandbox {
diff --git a/services/audio/public/cpp/sounds/test_data.h b/services/audio/public/cpp/sounds/test_data.h
index f69202b..6cfa9e4 100644
--- a/services/audio/public/cpp/sounds/test_data.h
+++ b/services/audio/public/cpp/sounds/test_data.h
@@ -10,9 +10,9 @@
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
 #include "media/base/audio_renderer_sink.h"
 #include "services/audio/public/cpp/sounds/audio_stream_handler.h"
 
diff --git a/services/device/geolocation/network_location_request.cc b/services/device/geolocation/network_location_request.cc
index 99c0aa9e..e623472 100644
--- a/services/device/geolocation/network_location_request.cc
+++ b/services/device/geolocation/network_location_request.cc
@@ -286,7 +286,7 @@
     AddInteger("signalToNoiseRatio", ap_data->signal_to_noise, wifi_dict.get());
     wifi_access_point_list->Append(std::move(wifi_dict));
   }
-  if (!wifi_access_point_list->empty())
+  if (!wifi_access_point_list->GetList().empty())
     request->Set("wifiAccessPoints", std::move(wifi_access_point_list));
 }
 
diff --git a/services/device/public/mojom/BUILD.gn b/services/device/public/mojom/BUILD.gn
index f96ff16e..07c0490 100644
--- a/services/device/public/mojom/BUILD.gn
+++ b/services/device/public/mojom/BUILD.gn
@@ -72,7 +72,6 @@
   export_header_blink = "third_party/blink/public/platform/web_common.h"
 
   visibility_blink = [
-    "//third_party/blink/renderer/bindings/modules/v8:generate_mojo_bindings",
     "//third_party/blink/renderer/platform:blink_platform_public_deps",
     "//third_party/blink/public/mojom:mojom_platform_blink",
   ]
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index aba6133..9faf68c 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -76,7 +76,8 @@
     for (const auto& header : headers)
       response_headers->SetHeader(header.first, header.second);
     auto hints = mojom::EarlyHints::New(
-        PopulateParsedHeaders(response_headers.get(), GetRequestedURL()));
+        PopulateParsedHeaders(response_headers.get(), GetRequestedURL()),
+        mojom::IPAddressSpace::kPublic);
     client_remote_->OnReceiveEarlyHints(std::move(hints));
   }
 
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
index 4abe09d..c394e4ff 100644
--- a/services/network/public/mojom/BUILD.gn
+++ b/services/network/public/mojom/BUILD.gn
@@ -264,6 +264,7 @@
         {
           mojom = "network.mojom.URLRequest"
           cpp = "::network::ResourceRequest"
+          forward_declaration = "namespace network { struct ResourceRequest; }"
         },
         {
           mojom = "network.mojom.URLRequestBody"
diff --git a/services/network/public/mojom/early_hints.mojom b/services/network/public/mojom/early_hints.mojom
index 3cbf1b4..a5cc816b 100644
--- a/services/network/public/mojom/early_hints.mojom
+++ b/services/network/public/mojom/early_hints.mojom
@@ -5,10 +5,13 @@
 module network.mojom;
 
 import "services/network/public/mojom/parsed_headers.mojom";
+import "services/network/public/mojom/ip_address_space.mojom";
 
 // Represents a 103 Early Hints response.
 // https://tools.ietf.org/html/rfc8297
 struct EarlyHints {
   // The parsed headers.
   ParsedHeaders headers;
+  // The IP address space of the request client instantiated from this response.
+  IPAddressSpace ip_address_space;
 };
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index c5931df..6b7f07b 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -1915,8 +1915,21 @@
   DCHECK(headers);
   DCHECK_EQ(headers->response_code(), 103);
 
-  url_loader_client_->OnReceiveEarlyHints(mojom::EarlyHints::New(
-      PopulateParsedHeaders(headers.get(), url_request_->url())));
+  // Calculate IP address space.
+  mojom::ParsedHeadersPtr parsed_headers =
+      PopulateParsedHeaders(headers.get(), url_request_->url());
+  std::vector<GURL> url_list_via_service_worker;
+  net::IPEndPoint transaction_endpoint;
+  bool has_endpoint =
+      url_request_->GetTransactionRemoteEndpoint(&transaction_endpoint);
+  DCHECK(has_endpoint);
+  CalculateClientAddressSpaceParams params(
+      url_list_via_service_worker, parsed_headers, transaction_endpoint);
+  mojom::IPAddressSpace ip_address_space =
+      CalculateClientAddressSpace(url_request_->url(), params);
+
+  url_loader_client_->OnReceiveEarlyHints(
+      mojom::EarlyHints::New(std::move(parsed_headers), ip_address_space));
 }
 
 void URLLoader::SetRawRequestHeadersAndNotify(
diff --git a/services/network/websocket.cc b/services/network/websocket.cc
index a790662..b8cb560 100644
--- a/services/network/websocket.cc
+++ b/services/network/websocket.cc
@@ -185,6 +185,9 @@
     net::URLRequest* url_request) {
   url_request->SetUserData(WebSocket::kUserDataKey,
                            std::make_unique<UnownedPointer>(impl_));
+  impl_->net_log_source_id_ = url_request->net_log().source().id;
+  impl_->throttling_token_ = network::ScopedThrottlingToken::MaybeCreate(
+      impl_->net_log_source_id_, impl_->throttling_profile_id_);
 }
 
 void WebSocket::WebSocketEventHandler::OnAddChannelResponse(
@@ -433,7 +436,8 @@
                         mojo::SimpleWatcher::ArmingPolicy::MANUAL,
                         base::ThreadTaskRunnerHandle::Get()),
       reassemble_short_messages_(base::FeatureList::IsEnabled(
-          network::features::kWebSocketReassembleShortMessages)) {
+          network::features::kWebSocketReassembleShortMessages)),
+      throttling_profile_id_(throttling_profile_id) {
   DCHECK(handshake_client_);
   // |delay| should be zero if this connection is not throttled.
   DCHECK(pending_connection_tracker.has_value() || delay.is_zero());
diff --git a/services/network/websocket.h b/services/network/websocket.h
index 6c8731ad..27f3ff2 100644
--- a/services/network/websocket.h
+++ b/services/network/websocket.h
@@ -26,6 +26,7 @@
 #include "services/network/network_service.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/websocket.mojom.h"
+#include "services/network/throttling/scoped_throttling_token.h"
 #include "services/network/websocket_throttler.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
@@ -243,6 +244,10 @@
   // which StartClosingHandshake() is called.
   std::unique_ptr<CloseInfo> pending_start_closing_handshake_;
 
+  const absl::optional<base::UnguessableToken> throttling_profile_id_;
+  uint32_t net_log_source_id_ = net::NetLogSource::kInvalidId;
+  std::unique_ptr<ScopedThrottlingToken> throttling_token_;
+
   base::WeakPtrFactory<WebSocket> weak_ptr_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(WebSocket);
diff --git a/services/preferences/public/cpp/dictionary_value_update.cc b/services/preferences/public/cpp/dictionary_value_update.cc
index 978d09d4..32e9ca50 100644
--- a/services/preferences/public/cpp/dictionary_value_update.cc
+++ b/services/preferences/public/cpp/dictionary_value_update.cc
@@ -275,9 +275,18 @@
   return value_->GetListWithoutPathExpansion(key, out_value);
 }
 
-bool DictionaryValueUpdate::Remove(base::StringPiece path,
-                                   std::unique_ptr<base::Value>* out_value) {
-  if (!value_->Remove(path, out_value))
+bool DictionaryValueUpdate::Remove(base::StringPiece path) {
+  base::StringPiece current_path(path);
+  base::Value* current_dictionary = value_;
+  size_t delimiter_position = current_path.rfind('.');
+  if (delimiter_position != base::StringPiece::npos) {
+    current_dictionary =
+        value_->FindPath(current_path.substr(0, delimiter_position));
+    if (!current_dictionary)
+      return false;
+    current_path = current_path.substr(delimiter_position + 1);
+  }
+  if (!current_dictionary->RemoveKey(current_path))
     return false;
 
   RecordPath(path);
diff --git a/services/preferences/public/cpp/dictionary_value_update.h b/services/preferences/public/cpp/dictionary_value_update.h
index ba854ca..2c20aa4 100644
--- a/services/preferences/public/cpp/dictionary_value_update.h
+++ b/services/preferences/public/cpp/dictionary_value_update.h
@@ -123,11 +123,9 @@
 
   // Removes the Value with the specified path from this dictionary (or one
   // of its child dictionaries, if the path is more than just a local key).
-  // If |out_value| is non-NULL, the removed Value will be passed out via
-  // |out_value|.  If |out_value| is NULL, the removed value will be deleted.
   // This method returns true if |path| is a valid path; otherwise it will
   // return false and the DictionaryValue object will be unchanged.
-  bool Remove(base::StringPiece path, std::unique_ptr<base::Value>* out_value);
+  bool Remove(base::StringPiece path);
 
   // Like Remove(), but without special treatment of '.'.  This allows e.g. URLs
   // to be used as paths.
diff --git a/services/preferences/tracked/dictionary_hash_store_contents.cc b/services/preferences/tracked/dictionary_hash_store_contents.cc
index d1385c4..f9c5f81 100644
--- a/services/preferences/tracked/dictionary_hash_store_contents.cc
+++ b/services/preferences/tracked/dictionary_hash_store_contents.cc
@@ -45,7 +45,7 @@
 }
 
 void DictionaryHashStoreContents::Reset() {
-  storage_->Remove(kPreferenceMACs, NULL);
+  storage_->RemovePath(kPreferenceMACs);
 }
 
 bool DictionaryHashStoreContents::GetMac(const std::string& path,
diff --git a/services/preferences/tracked/pref_hash_filter.cc b/services/preferences/tracked/pref_hash_filter.cc
index 5ccb87a..f036e31 100644
--- a/services/preferences/tracked/pref_hash_filter.cc
+++ b/services/preferences/tracked/pref_hash_filter.cc
@@ -40,7 +40,7 @@
 
   for (size_t i = 0; i < base::size(kDeprecatedTrackedPreferences); ++i) {
     const char* key = kDeprecatedTrackedPreferences[i];
-    pref_store_contents->Remove(key, NULL);
+    pref_store_contents->RemovePath(key);
     hash_store_transaction->ClearHash(key);
   }
 }
@@ -308,12 +308,9 @@
             changed_path, inner_it.key(), mac);
       }
     } else {
-      const base::Value* value_as_string;
-      bool is_string = it.value().GetAsString(&value_as_string);
-      DCHECK(is_string);
-
-      external_validation_hash_store_contents->SetMac(
-          changed_path, value_as_string->GetString());
+      DCHECK(it.value().is_string());
+      external_validation_hash_store_contents->SetMac(changed_path,
+                                                      it.value().GetString());
     }
   }
 }
diff --git a/services/preferences/tracked/pref_hash_filter_unittest.cc b/services/preferences/tracked/pref_hash_filter_unittest.cc
index fdd5b54..2ceb929 100644
--- a/services/preferences/tracked/pref_hash_filter_unittest.cc
+++ b/services/preferences/tracked/pref_hash_filter_unittest.cc
@@ -431,10 +431,9 @@
 std::string MockHashStoreContents::GetStoredMac(const std::string& path) const {
   const base::Value* out_value = dictionary_.FindKey(path);
   if (out_value) {
-    const base::Value* value_as_string;
-    EXPECT_TRUE(out_value->GetAsString(&value_as_string));
+    EXPECT_TRUE(out_value->is_string());
 
-    return value_as_string->GetString();
+    return out_value->GetString();
   }
 
   return std::string();
@@ -450,10 +449,9 @@
 
     out_value = dictionary_.FindKey(split_path);
     if (out_value) {
-      const base::Value* value_as_string;
-      EXPECT_TRUE(out_value->GetAsString(&value_as_string));
+      EXPECT_TRUE(out_value->is_string());
 
-      return value_as_string->GetString();
+      return out_value->GetString();
     }
   }
 
diff --git a/services/preferences/tracked/pref_hash_store_impl.cc b/services/preferences/tracked/pref_hash_store_impl.cc
index 095016ee..e508880 100644
--- a/services/preferences/tracked/pref_hash_store_impl.cc
+++ b/services/preferences/tracked/pref_hash_store_impl.cc
@@ -272,11 +272,9 @@
 
     for (base::DictionaryValue::Iterator it(*split_macs); !it.IsAtEnd();
          it.Advance()) {
-      const base::Value* value_as_string;
-      bool is_string = it.value().GetAsString(&value_as_string);
-      DCHECK(is_string);
+      DCHECK(it.value().is_string());
 
-      contents_->SetSplitMac(path, it.key(), value_as_string->GetString());
+      contents_->SetSplitMac(path, it.key(), it.value().GetString());
     }
   }
   super_mac_dirty_ = true;
diff --git a/services/preferences/tracked/tracked_preferences_migration.cc b/services/preferences/tracked/tracked_preferences_migration.cc
index f710b48..3342daf 100644
--- a/services/preferences/tracked/tracked_preferences_migration.cc
+++ b/services/preferences/tracked/tracked_preferences_migration.cc
@@ -186,7 +186,7 @@
         // value in order to provide the same no-op behaviour as if the pref was
         // added to the wrong file when there was already a value for
         // |pref_name| in |new_store|.
-        new_store->Remove(pref_name, NULL);
+        new_store->RemovePath(pref_name);
         *new_store_altered = true;
       }
     }
diff --git a/services/preferences/tracked/tracked_split_preference.cc b/services/preferences/tracked/tracked_split_preference.cc
index 053f315..a0f3392 100644
--- a/services/preferences/tracked/tracked_split_preference.cc
+++ b/services/preferences/tracked/tracked_split_preference.cc
@@ -90,7 +90,7 @@
 
       for (std::vector<std::string>::const_iterator it = invalid_keys.begin();
            it != invalid_keys.end(); ++it) {
-        dict_value->Remove(*it, NULL);
+        dict_value->RemoveKey(*it);
       }
     } else {
       pref_store_contents->RemovePath(pref_path_, NULL);
diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc
index 6764c13..a4dd256 100644
--- a/services/video_capture/device_media_to_mojo_adapter.cc
+++ b/services/video_capture/device_media_to_mojo_adapter.cc
@@ -189,15 +189,15 @@
   // runs out of three when just displaying 60 FPS media in a video element.
   kMaxBufferCount = 10;
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
-  // On Chrome OS with MIPI cameras running on HAL v3, there can be three
-  // concurrent streams of camera pipeline depth ~6. We allow at most 30 buffers
+  // On Chrome OS with MIPI cameras running on HAL v3, there can be four
+  // concurrent streams of camera pipeline depth ~6. We allow at most 36 buffers
   // here to take into account the delay caused by the consumer (e.g. display or
   // video encoder).
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableVideoCaptureUseGpuMemoryBuffer) &&
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kVideoCaptureUseGpuMemoryBuffer)) {
-    kMaxBufferCount = 30;
+    kMaxBufferCount = 36;
   }
 #elif defined(OS_WIN)
   // On Windows, for GMB backed zero-copy more buffers are needed because it's
diff --git a/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc b/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
index 5fff0ff..206f8c3 100644
--- a/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
+++ b/services/video_capture/lacros/video_frame_handler_proxy_lacros.cc
@@ -91,7 +91,8 @@
 // mojo::Remote<crosapi::mojom::ScopedAccessPermission> pipes alive until
 // EraseAccessPermission() calls.
 class VideoFrameHandlerProxyLacros::AccessPermissionProxyMap
-    : public base::RefCountedThreadSafe<ScopedAccessPermissionMap> {
+    : public base::RefCountedThreadSafe<
+          VideoFrameHandlerProxyLacros::AccessPermissionProxyMap> {
  public:
   AccessPermissionProxyMap() = default;
 
@@ -99,8 +100,10 @@
       int32_t buffer_id,
       mojo::PendingRemote<crosapi::mojom::ScopedAccessPermission>
           pending_remote_access_permission) {
-    mojo::Remote<crosapi::mojom::ScopedAccessPermission>
-        remote_access_permission(std::move(pending_remote_access_permission));
+    std::unique_ptr<mojo::Remote<crosapi::mojom::ScopedAccessPermission>>
+        remote_access_permission = std::make_unique<
+            mojo::Remote<crosapi::mojom::ScopedAccessPermission>>(
+            std::move(pending_remote_access_permission));
     auto result = access_permissions_by_buffer_ids_.insert(
         std::make_pair(buffer_id, std::move(remote_access_permission)));
     DCHECK(result.second);
@@ -116,10 +119,13 @@
   }
 
  private:
-  friend class base::RefCountedThreadSafe<AccessPermissionProxyMap>;
+  friend class base::RefCountedThreadSafe<
+      VideoFrameHandlerProxyLacros::AccessPermissionProxyMap>;
   ~AccessPermissionProxyMap() = default;
 
-  std::map<int32_t, mojo::Remote<crosapi::mojom::ScopedAccessPermission>>
+  std::map<
+      int32_t,
+      std::unique_ptr<mojo::Remote<crosapi::mojom::ScopedAccessPermission>>>
       access_permissions_by_buffer_ids_;
 };
 
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 985c4a7d..d7e5f778 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -205,6 +205,8 @@
 // Max. verb count for paths rendered by the edge-AA tessellating path renderer.
 #define GR_AA_TESSELLATOR_MAX_VERB_COUNT 100
 
+#define SK_SUPPORT_LEGACY_GETBLENDMODE
+
 #define GR_DISABLE_TESSELLATION_ON_ES2
 
 #define SK_SUPPORT_LEGACY_AAA_CHOICE
diff --git a/skia/ext/convolver_unittest.cc b/skia/ext/convolver_unittest.cc
index 9518c15..ba7fea7 100644
--- a/skia/ext/convolver_unittest.cc
+++ b/skia/ext/convolver_unittest.cc
@@ -9,8 +9,8 @@
 #include <numeric>
 #include <vector>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "skia/ext/convolver.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/skia/ext/image_operations_bench.cc b/skia/ext/image_operations_bench.cc
index 9433a73..c962315 100644
--- a/skia/ext/image_operations_bench.cc
+++ b/skia/ext/image_operations_bench.cc
@@ -19,8 +19,8 @@
 #include <stdio.h>
 
 #include "base/command_line.h"
+#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc
index 8970955..cc565755 100644
--- a/skia/ext/image_operations_unittest.cc
+++ b/skia/ext/image_operations_unittest.cc
@@ -11,9 +11,9 @@
 #include <vector>
 
 #include "base/compiler_specific.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/numerics/math_constants.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "skia/ext/image_operations.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/skia/ext/skia_utils_ios.mm b/skia/ext/skia_utils_ios.mm
index faa1e57..b0b35f6 100644
--- a/skia/ext/skia_utils_ios.mm
+++ b/skia/ext/skia_utils_ios.mm
@@ -9,10 +9,10 @@
 #include <stdint.h>
 #import <UIKit/UIKit.h>
 
+#include "base/cxx17_backports.h"
 #include "base/ios/ios_util.h"
 #include "base/logging.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
 
 namespace {
diff --git a/skia/ext/test_fonts_mac.mm b/skia/ext/test_fonts_mac.mm
index da6b2935..5768fe64 100644
--- a/skia/ext/test_fonts_mac.mm
+++ b/skia/ext/test_fonts_mac.mm
@@ -7,10 +7,10 @@
 #include <AppKit/AppKit.h>
 #include <Foundation/Foundation.h>
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
-#include "base/stl_util.h"
 #include "base/strings/sys_string_conversions.h"
 
 namespace skia {
diff --git a/sql/database.h b/sql/database.h
index fc9f9676..d05fff74 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -19,7 +19,6 @@
 #include "base/containers/flat_map.h"
 #include "base/feature_list.h"
 #include "base/gtest_prod_util.h"
-#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
 #include "base/threading/scoped_blocking_call.h"
@@ -127,6 +126,8 @@
   Database();
   // |options| only affects newly created databases.
   explicit Database(DatabaseOptions options);
+  Database(const Database&) = delete;
+  Database& operator=(const Database&) = delete;
   ~Database();
 
   // Allows mmapping to be disabled globally by default in the calling process.
@@ -563,6 +564,9 @@
     // been forcibly closed by an error handler.
     StatementRef(Database* database, sqlite3_stmt* stmt, bool was_valid);
 
+    StatementRef(const StatementRef&) = delete;
+    StatementRef& operator=(const StatementRef&) = delete;
+
     // When true, the statement can be used.
     bool is_valid() const { return !!stmt_; }
 
@@ -605,8 +609,6 @@
     Database* database_;
     sqlite3_stmt* stmt_;
     bool was_valid_;
-
-    DISALLOW_COPY_AND_ASSIGN(StatementRef);
   };
   friend class StatementRef;
 
@@ -742,8 +744,6 @@
 
   // Stores the dump provider object when db is open.
   std::unique_ptr<DatabaseMemoryDumpProvider> memory_dump_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(Database);
 };
 
 }  // namespace sql
diff --git a/sql/database_memory_dump_provider.h b/sql/database_memory_dump_provider.h
index 1df2c1b..3b612c0 100644
--- a/sql/database_memory_dump_provider.h
+++ b/sql/database_memory_dump_provider.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "base/macros.h"
 #include "base/synchronization/lock.h"
 #include "base/trace_event/memory_dump_provider.h"
 
@@ -25,6 +24,11 @@
     : public base::trace_event::MemoryDumpProvider {
  public:
   DatabaseMemoryDumpProvider(sqlite3* db, const std::string& name);
+
+  DatabaseMemoryDumpProvider(const DatabaseMemoryDumpProvider&) = delete;
+  DatabaseMemoryDumpProvider& operator=(const DatabaseMemoryDumpProvider&) =
+      delete;
+
   ~DatabaseMemoryDumpProvider() override;
 
   void ResetDatabase();
@@ -47,8 +51,6 @@
   sqlite3* db_;  // not owned.
   base::Lock lock_;
   std::string connection_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(DatabaseMemoryDumpProvider);
 };
 
 }  // namespace sql
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc
index c2d6516..5ad77dc 100644
--- a/sql/database_unittest.cc
+++ b/sql/database_unittest.cc
@@ -50,12 +50,11 @@
   RefCounter(const RefCounter& other) : counter_(other.counter_) {
     (*counter_)++;
   }
+  RefCounter& operator=(const RefCounter&) = delete;
   ~RefCounter() { (*counter_)--; }
 
  private:
   size_t* counter_;
-
-  DISALLOW_ASSIGN(RefCounter);
 };
 
 // Empty callback for implementation of ErrorCallbackSetHelper().
diff --git a/sql/meta_table.h b/sql/meta_table.h
index 3ac6aa0..8ffbc8b 100644
--- a/sql/meta_table.h
+++ b/sql/meta_table.h
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/component_export.h"
-#include "base/macros.h"
 
 namespace sql {
 
@@ -25,6 +24,8 @@
 class COMPONENT_EXPORT(SQL) MetaTable {
  public:
   MetaTable();
+  MetaTable(const MetaTable&) = delete;
+  MetaTable& operator=(const MetaTable&) = delete;
   ~MetaTable();
 
   // Values for Get/SetMmapStatus(). |kMmapFailure| indicates that there was at
@@ -121,8 +122,6 @@
   bool PrepareGetStatement(Statement* statement, const char* key);
 
   Database* db_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(MetaTable);
 };
 
 }  // namespace sql
diff --git a/sql/recover_module/module_unittest.cc b/sql/recover_module/module_unittest.cc
index 8ab83ad..9d25c5af 100644
--- a/sql/recover_module/module_unittest.cc
+++ b/sql/recover_module/module_unittest.cc
@@ -991,14 +991,7 @@
   sql::Statement insert(
       db_.GetUniqueStatement("INSERT INTO blob_encodings VALUES(?)"));
   for (const std::vector<uint8_t>& value : values) {
-    // std::vector::data() returns nullptr for empty vectors. Unfortunately,
-    // sqlite3_bind_blob() always interprets null data as a NULL value. In this
-    // case, we really want to write an empty blob, so we need to pass non-null
-    // data.
-    const uint8_t* blob_data =
-        (value.size() > 0) ? value.data() : values[1].data();
-
-    insert.BindBlob(0, blob_data, value.size());
+    insert.BindBlob(0, value);
     ASSERT_TRUE(insert.Run());
     insert.Reset(/* clear_bound_vars= */ true);
   }
diff --git a/sql/recovery.h b/sql/recovery.h
index bb44a78..c140655 100644
--- a/sql/recovery.h
+++ b/sql/recovery.h
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/component_export.h"
-#include "base/macros.h"
 #include "sql/database.h"
 #include "sql/internal_api_token.h"
 
@@ -66,6 +65,8 @@
 
 class COMPONENT_EXPORT(SQL) Recovery {
  public:
+  Recovery(const Recovery&) = delete;
+  Recovery& operator=(const Recovery&) = delete;
   ~Recovery();
 
   // Begin the recovery process by opening a temporary database handle
@@ -202,8 +203,6 @@
 
   Database* db_;         // Original Database connection.
   Database recover_db_;  // Recovery Database connection.
-
-  DISALLOW_COPY_AND_ASSIGN(Recovery);
 };
 
 }  // namespace sql
diff --git a/sql/sql_memory_dump_provider.h b/sql/sql_memory_dump_provider.h
index 190b802a..ffb932b6 100644
--- a/sql/sql_memory_dump_provider.h
+++ b/sql/sql_memory_dump_provider.h
@@ -6,7 +6,6 @@
 #define SQL_SQL_MEMORY_DUMP_PROVIDER_H_
 
 #include "base/component_export.h"
-#include "base/macros.h"
 #include "base/memory/singleton.h"
 #include "base/trace_event/memory_dump_provider.h"
 
@@ -19,6 +18,9 @@
  public:
   static SqlMemoryDumpProvider* GetInstance();
 
+  SqlMemoryDumpProvider(const SqlMemoryDumpProvider&) = delete;
+  SqlMemoryDumpProvider& operator=(const SqlMemoryDumpProvider&) = delete;
+
   // MemoryDumpProvider implementation.
   bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                     base::trace_event::ProcessMemoryDump* pmd) override;
@@ -28,8 +30,6 @@
 
   SqlMemoryDumpProvider();
   ~SqlMemoryDumpProvider() override;
-
-  DISALLOW_COPY_AND_ASSIGN(SqlMemoryDumpProvider);
 };
 
 }  // namespace sql
diff --git a/sql/statement.cc b/sql/statement.cc
index fe8ae34..d161fe3 100644
--- a/sql/statement.cc
+++ b/sql/statement.cc
@@ -224,14 +224,28 @@
   return BindString(col, base::UTF16ToUTF8(value));
 }
 
-bool Statement::BindBlob(int col, const void* val, int val_len) {
+bool Statement::BindBlob(int col, base::span<const uint8_t> value) {
 #if !defined(OS_ANDROID)  // TODO(crbug.com/866218): Remove this conditional
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 #endif  // OS_ANDROID
   DCHECK(!stepped_);
 
-  return is_valid() && CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, val,
-                                                 val_len, SQLITE_TRANSIENT));
+  // span::data() may return null for empty spans. In particular, this may
+  // happen when the span is created out of a std::vector, because
+  // std::vector::data() may (or may not) return null for empty vectors.
+  //
+  // However, sqlite3_bind_blob() always interprets a nullptr data argument as a
+  // NULL value, instead of an empty BLOB value.
+  //
+  // While the difference between NULL and an empty BLOB may not matter in some
+  // cases, it may also cause subtle bugs in other cases. So, we cannot pass
+  // span.data() directly to sqlite3_bind_blob().
+  static constexpr uint8_t kEmptyPlaceholder[] = {0x00};
+  const uint8_t* data = (value.size() > 0) ? value.data() : kEmptyPlaceholder;
+
+  return is_valid() &&
+         CheckOk(sqlite3_bind_blob(ref_->stmt(), col + 1, data, value.size(),
+                                   SQLITE_TRANSIENT));
 }
 
 int Statement::ColumnCount() const {
diff --git a/sql/statement.h b/sql/statement.h
index bc01693..4f997b9 100644
--- a/sql/statement.h
+++ b/sql/statement.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/component_export.h"
-#include "base/macros.h"
+#include "base/containers/span.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_piece_forward.h"
@@ -58,6 +58,10 @@
   Statement();
 
   explicit Statement(scoped_refptr<Database::StatementRef> ref);
+
+  Statement(const Statement&) = delete;
+  Statement& operator=(const Statement&) = delete;
+
   ~Statement();
 
   // Initializes this object with the given statement, which may or may not
@@ -126,7 +130,12 @@
   bool BindCString(int col, const char* val);
   bool BindString(int col, const std::string& val);
   bool BindString16(int col, base::StringPiece16 value);
-  bool BindBlob(int col, const void* value, int value_len);
+  bool BindBlob(int col, base::span<const uint8_t> value);
+
+  // Overload that makes it easy to pass in std::string values.
+  bool BindBlob(int col, base::span<const char> value) {
+    return BindBlob(col, base::as_bytes(base::make_span(value)));
+  }
 
   // Conforms with base::Time serialization recommendations.
   //
@@ -182,7 +191,7 @@
   bool ColumnBlobAsString(int col, std::string* blob) const;
   bool ColumnBlobAsString16(int col, std::u16string* val) const;
   bool ColumnBlobAsVector(int col, std::vector<char>* val) const;
-  bool ColumnBlobAsVector(int col, std::vector<unsigned char>* val) const;
+  bool ColumnBlobAsVector(int col, std::vector<uint8_t>* val) const;
 
   // Diagnostics --------------------------------------------------------------
 
@@ -234,8 +243,6 @@
   bool succeeded_ = false;
 
   SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(Statement);
 };
 
 }  // namespace sql
diff --git a/sql/statement_unittest.cc b/sql/statement_unittest.cc
index af85326..a153ffe3 100644
--- a/sql/statement_unittest.cc
+++ b/sql/statement_unittest.cc
@@ -126,5 +126,60 @@
   ASSERT_FALSE(s.Step());
 }
 
+TEST_F(SQLStatementTest, BindBlob) {
+  ASSERT_TRUE(db_.Execute("CREATE TABLE blobs (b BLOB NOT NULL)"));
+
+  const std::vector<std::vector<uint8_t>> values = {
+      {},
+      {0x01},
+      {0x41, 0x42, 0x43, 0x44},
+  };
+
+  Statement insert(db_.GetUniqueStatement("INSERT INTO blobs VALUES(?)"));
+  for (const std::vector<uint8_t>& value : values) {
+    insert.BindBlob(0, value);
+    ASSERT_TRUE(insert.Run());
+    insert.Reset(/* clear_bound_vars= */ true);
+  }
+
+  Statement select(db_.GetUniqueStatement("SELECT b FROM blobs"));
+  for (const std::vector<uint8_t>& value : values) {
+    ASSERT_TRUE(select.Step());
+    std::vector<uint8_t> column_value;
+    EXPECT_TRUE(select.ColumnBlobAsVector(0, &column_value));
+    EXPECT_EQ(value, column_value);
+  }
+  EXPECT_FALSE(select.Step());
+}
+
+TEST_F(SQLStatementTest, BindString) {
+  ASSERT_TRUE(db_.Execute("CREATE TABLE strings (s TEXT NOT NULL)"));
+
+  const std::vector<std::string> values = {
+      "",
+      "a",
+      "\x01",
+      std::string("\x00", 1),
+      "abcd",
+      "\x01\x02\x03\x04",
+      std::string("\x01Test", 5),
+      std::string("\x00Test", 5),
+  };
+
+  Statement insert(db_.GetUniqueStatement("INSERT INTO strings VALUES(?)"));
+  for (const std::string& value : values) {
+    insert.BindString(0, value);
+    ASSERT_TRUE(insert.Run());
+    insert.Reset(/* clear_bound_vars= */ true);
+  }
+
+  Statement select(db_.GetUniqueStatement("SELECT s FROM strings"));
+  for (const std::string& value : values) {
+    ASSERT_TRUE(select.Step());
+    EXPECT_EQ(value, select.ColumnString(0));
+  }
+  EXPECT_FALSE(select.Step());
+}
+
 }  // namespace
 }  // namespace sql
diff --git a/sql/test/error_callback_support.h b/sql/test/error_callback_support.h
index 4774180..02f5612 100644
--- a/sql/test/error_callback_support.h
+++ b/sql/test/error_callback_support.h
@@ -5,7 +5,6 @@
 #ifndef SQL_TEST_ERROR_CALLBACK_SUPPORT_H_
 #define SQL_TEST_ERROR_CALLBACK_SUPPORT_H_
 
-#include "base/macros.h"
 #include "sql/database.h"
 
 namespace sql {
@@ -25,12 +24,12 @@
  public:
   ScopedErrorCallback(sql::Database* db,
                       const sql::Database::ErrorCallback& cb);
+  ScopedErrorCallback(const ScopedErrorCallback&) = delete;
+  ScopedErrorCallback& operator=(const ScopedErrorCallback&) = delete;
   ~ScopedErrorCallback();
 
  private:
   sql::Database* db_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedErrorCallback);
 };
 
 }  // namespace sql
diff --git a/sql/test/scoped_error_expecter.h b/sql/test/scoped_error_expecter.h
index dbf8b431..a885a2c 100644
--- a/sql/test/scoped_error_expecter.h
+++ b/sql/test/scoped_error_expecter.h
@@ -7,7 +7,6 @@
 
 #include <set>
 
-#include "base/macros.h"
 #include "sql/database.h"
 
 // This is not strictly necessary for the operation of ScopedErrorExpecter, but
@@ -32,6 +31,8 @@
 class ScopedErrorExpecter {
  public:
   ScopedErrorExpecter();
+  ScopedErrorExpecter(const ScopedErrorExpecter&) = delete;
+  ScopedErrorExpecter& operator=(const ScopedErrorExpecter&) = delete;
   ~ScopedErrorExpecter();
 
   // Add an error to expect.  Extended error codes can be specified
@@ -66,8 +67,6 @@
 
   // Expected errors which have been encountered.
   std::set<int> errors_seen_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedErrorExpecter);
 };
 
 }  // namespace test
diff --git a/sql/test/sql_test_suite.h b/sql/test/sql_test_suite.h
index 86c09168..b6323ccc 100644
--- a/sql/test/sql_test_suite.h
+++ b/sql/test/sql_test_suite.h
@@ -5,7 +5,6 @@
 #ifndef SQL_TEST_SQL_TEST_SUITE_H_
 #define SQL_TEST_SQL_TEST_SUITE_H_
 
-#include "base/macros.h"
 #include "base/test/test_suite.h"
 
 namespace sql {
@@ -13,15 +12,14 @@
 class SQLTestSuite : public base::TestSuite {
  public:
   SQLTestSuite(int argc, char** argv);
+  SQLTestSuite(const SQLTestSuite&) = delete;
+  SQLTestSuite& operator=(const SQLTestSuite&) = delete;
   ~SQLTestSuite() override;
 
  protected:
   // Overridden from base::TestSuite:
   void Initialize() override;
   void Shutdown() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SQLTestSuite);
 };
 
 }  // namespace sql
diff --git a/sql/transaction.h b/sql/transaction.h
index 27e8dfb..069936fb 100644
--- a/sql/transaction.h
+++ b/sql/transaction.h
@@ -6,7 +6,6 @@
 #define SQL_TRANSACTION_H_
 
 #include "base/component_export.h"
-#include "base/macros.h"
 
 namespace sql {
 
@@ -22,6 +21,8 @@
   // Nested transactions are supported. See sql::Database::BeginTransaction
   // for details.
   explicit Transaction(Database* connection);
+  Transaction(const Transaction&) = delete;
+  Transaction& operator=(const Transaction&) = delete;
   ~Transaction();
 
   // Returns true when there is a transaction that has been successfully begun.
@@ -51,8 +52,6 @@
   // True when the transaction is open, false when it's already been committed
   // or rolled back.
   bool is_open_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(Transaction);
 };
 
 }  // namespace sql
diff --git a/styleguide/web/web.md b/styleguide/web/web.md
index 5db2f77..e80eda55 100644
--- a/styleguide/web/web.md
+++ b/styleguide/web/web.md
@@ -370,7 +370,7 @@
 
 * In new code, use class based syntax for custom elements. Example:
 ```js
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.m.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 class MyAppElement extends PolymerElement {
   static get is() {
diff --git a/testing/android/native_test/native_test_launcher.cc b/testing/android/native_test/native_test_launcher.cc
index 71b4b60b..6a5ac16 100644
--- a/testing/android/native_test/native_test_launcher.cc
+++ b/testing/android/native_test/native_test_launcher.cc
@@ -20,11 +20,11 @@
 #include "base/base_switches.h"
 #include "base/clang_profiling_buildflags.h"
 #include "base/command_line.h"
+#include "base/cxx17_backports.h"
 #include "base/debug/debugger.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "base/test/test_support_android.h"
 #include "base/threading/thread_restrictions.h"
 #include "gtest/gtest.h"
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index a3ff918..2764100 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -816,7 +816,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -5125,7 +5125,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5211,7 +5211,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5383,7 +5383,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5469,7 +5469,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 1acbec8..f1d05ba 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -2552,7 +2552,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -6163,7 +6163,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -9764,7 +9764,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -13365,7 +13365,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -18318,7 +18318,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -31358,7 +31358,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -35121,7 +35121,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -40417,7 +40417,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -44380,7 +44380,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -49148,7 +49148,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -53730,7 +53730,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -53817,7 +53817,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -53991,7 +53991,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54078,7 +54078,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54324,7 +54324,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54410,7 +54410,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54582,7 +54582,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54668,7 +54668,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -54914,7 +54914,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55000,7 +55000,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55172,7 +55172,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M91",
-              "revision": "version:91.0.4472.156"
+              "revision": "version:91.0.4472.157"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -55258,7 +55258,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M92",
-              "revision": "version:92.0.4515.88"
+              "revision": "version:92.0.4515.93"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index f076733a..34514285 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -5683,7 +5683,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index b1e2e30..bd6a058 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -6,6 +6,11 @@
       "chromium_builder_asan"
     ]
   },
+  "Comparison Linux": {
+    "additional_compile_targets": [
+      "all"
+    ]
+  },
   "Linux Builder (core-32) (goma)": {
     "additional_compile_targets": [
       "all"
@@ -4666,7 +4671,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -8029,7 +8034,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -11392,7 +11397,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
@@ -15395,7 +15400,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 197ba98..62f124a5 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -15405,7 +15405,7 @@
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 4
+          "shards": 6
         },
         "test": "blink_unittests",
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/testing/buildbot/filters/linux-lacros.browser_tests.filter b/testing/buildbot/filters/linux-lacros.browser_tests.filter
index c3a7626..4b035bf 100644
--- a/testing/buildbot/filters/linux-lacros.browser_tests.filter
+++ b/testing/buildbot/filters/linux-lacros.browser_tests.filter
@@ -119,8 +119,8 @@
 -OutOfProcessPPAPITest.NetAddress
 -OutOfProcessPPAPITest.Printing
 -OutOfProcessPPAPITest.URLRequest_CreateAndIsURLRequestInfo
--PageInfoBubbleViewBrowserTest.FocusDoesNotReturnToContentsOnReloadPrompt
--PageInfoBubbleViewBrowserTest.FocusReturnsToContentOnClose
+-All/PageInfoBubbleViewBrowserTest.FocusDoesNotReturnToContentsOnReloadPrompt/*
+-All/PageInfoBubbleViewBrowserTest.FocusReturnsToContentOnClose/*
 -PageLoadMetricsBrowserTest.MainFrameIntersectionsMainFrame
 -PaymentRequestCompletionStatusMetricsTest.UserAborted_TabClosed
 -PaymentRequestCreditCardEditorTest.EditingExpiredCard
diff --git a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
index f1d4897..9a73611 100644
--- a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
+++ b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
@@ -33,8 +33,8 @@
 -BrowserViewTest.GetAccessibleTabModalDialogTree
 -OmniboxPopupContentsViewTest.ClickOmnibox
 -OmniboxPopupContentsViewTest.PopupMatchesLocationBarBackground
--PageInfoBubbleViewBrowserTest.FocusDoesNotReturnToContentsOnReloadPrompt
--PageInfoBubbleViewBrowserTest.FocusReturnsToContentOnClose
+-All/PageInfoBubbleViewBrowserTest.FocusDoesNotReturnToContentsOnReloadPrompt/*
+-All/PageInfoBubbleViewBrowserTest.FocusReturnsToContentOnClose/*
 -PrintBrowserTest.PDFPluginNotKeyboardFocusable
 
 # These tests fail when run either with weston's test-plugin module or with
diff --git a/testing/buildbot/filters/pixel_browser_tests.filter b/testing/buildbot/filters/pixel_browser_tests.filter
index dc37632b..14f59cb2 100644
--- a/testing/buildbot/filters/pixel_browser_tests.filter
+++ b/testing/buildbot/filters/pixel_browser_tests.filter
@@ -18,7 +18,7 @@
 ImportLockDialogViewBrowserTest.*

 OneTimePermissionPromptBubbleViewBrowserTest.*

 OutdatedUpgradeBubbleTest.*

-PageInfoBubbleViewDialogBrowserTest.*

+All/PageInfoBubbleViewDialogBrowserTest.*

 PasswordReuseModalWarningTest.*

 PermissionChipBrowserTest.*

 All/PermissionPromptBubbleViewBrowserTest.*

diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 147f58f..400e214c 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -865,7 +865,7 @@
     "type": "console_test_launcher",
   },
   "gen_linux_ash_chromium_cipd_yaml": {
-    "label": "//chrome:gen_linux_ash_chromium_cipd_yaml",
+    "label": "//chrome/test:gen_linux_ash_chromium_cipd_yaml",
     "type": "additional_compile_target",
   },
   "gfx_unittests": {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 66d8bcc..49c4af3 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -131,7 +131,7 @@
       'webkit_unit_tests':{
         'test': 'blink_unittests',
           'android_swarming': {
-            'shards': 4,
+            'shards': 6,
           },
       },
     },
@@ -822,7 +822,7 @@
       'webkit_unit_tests': {
         'test': 'blink_unittests',
         'android_swarming': {
-          'shards': 4,
+          'shards': 6,
         },
       },
       'wtf_unittests': {},
@@ -4631,7 +4631,7 @@
       'webkit_unit_tests': {
         'test': 'blink_unittests',
         'android_swarming': {
-          'shards': 4,
+          'shards': 6,
         },
       },
       'wtf_unittests': {},
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index df2a058..ee2a56c 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -416,7 +416,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.88',
+          'revision': 'version:92.0.4515.93',
         }
       ],
     },
@@ -440,7 +440,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.156',
+          'revision': 'version:91.0.4472.157',
         }
       ],
     },
@@ -488,7 +488,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.88',
+          'revision': 'version:92.0.4515.93',
         }
       ],
     },
@@ -512,7 +512,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.156',
+          'revision': 'version:91.0.4472.157',
         }
       ],
     },
@@ -560,7 +560,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M92',
-          'revision': 'version:92.0.4515.88',
+          'revision': 'version:92.0.4515.93',
         }
       ],
     },
@@ -584,7 +584,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M91',
-          'revision': 'version:91.0.4472.156',
+          'revision': 'version:91.0.4472.157',
         }
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index dac72b5a..ffb3024c 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2456,6 +2456,14 @@
           'chromium_builder_asan',
         ],
       },
+      'Comparison Linux': {
+        'mixins': [
+          'isolate_profile_data',
+        ],
+        'additional_compile_targets': [
+          'all'
+        ],
+      },
       'Linux Builder (core-32) (goma)': {
         # Copied from
         # https://source.chromium.org/chromium/chromium/src/+/main:testing/buildbot/waterfalls.pyl;l=4844-4854;drc=75f767e92e86611728189739fb26f4e2cdf212d9
diff --git a/testing/trigger_scripts/base_test_triggerer.py b/testing/trigger_scripts/base_test_triggerer.py
index 831dbc4..5ab7bfc 100755
--- a/testing/trigger_scripts/base_test_triggerer.py
+++ b/testing/trigger_scripts/base_test_triggerer.py
@@ -171,31 +171,6 @@
         finally:
             self.delete_temp_file(temp_file)
 
-    def query_swarming_for_bot_configs(self, verbose):
-        # Query Swarming to figure out which bots are available.
-        for config in self._bot_configs:
-            values = []
-            for key, value in sorted(config.iteritems()):
-                values.append(('dimensions', '%s:%s' % (key, value)))
-            # Ignore dead and quarantined bots.
-            values.append(('is_dead', 'FALSE'))
-            values.append(('quarantined', 'FALSE'))
-
-            query_result = self.query_swarming('bots/count', values, verbose)
-            # Summarize number of available bots per configuration.
-            count = int(query_result['count'])
-            # Be robust against errors in computation.
-            available = max(0, count - int(query_result['busy']))
-            self._bot_statuses.append({'total': count, 'available': available})
-            if verbose:
-                idx = len(self._bot_statuses) - 1
-                logging.info('Bot config %d: %s' %
-                             (idx, str(self._bot_statuses[idx])))
-        # Sum up the total count of all bots.
-        self._total_bots = sum(x['total'] for x in self._bot_statuses)
-        if verbose:
-            logging.info('Total bots: %d' % (self._total_bots))
-
     def remove_swarming_dimension(self, args, dimension):
         for i in xrange(len(args)):
             if args[i] == '--dimension' and args[i + 1] == dimension:
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index e2c9203..7b9b0e9 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1246,6 +1246,8 @@
     "BackForwardCacheDesktop": [
         {
             "platforms": [
+                "chromeos",
+                "chromeos_lacros",
                 "linux",
                 "mac",
                 "windows"
@@ -1258,6 +1260,7 @@
                         "blocked_websites": "https://domain1.org,https://domain2.org",
                         "cache_size": "6",
                         "check_eligibility_after_pagehide": "true",
+                        "content_injection_supported": "true",
                         "enable_same_site": "false",
                         "file_system_api_supported": "true",
                         "foreground_cache_size": "2",
@@ -1373,30 +1376,6 @@
             ]
         }
     ],
-    "ButterForPasswords": [
-        {
-            "platforms": [
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "ButterForPasswords",
-                    "params": {
-                        "availability": "any",
-                        "event_1": "name:passwords_account_storage_unselected;comparator:==0;window:180;storage:180",
-                        "event_trigger": "name:passwords_account_storage_trigger;comparator:<5;window:180;storage:180",
-                        "event_used": "name:passwords_account_storage_used;comparator:==0;window:180;storage:180"
-                    },
-                    "enable_features": [
-                        "EnablePasswordsAccountStorage",
-                        "IPH_PasswordsAccountStorage"
-                    ]
-                }
-            ]
-        }
-    ],
     "ButterForPaymentsStage2": [
         {
             "platforms": [
@@ -2438,6 +2417,27 @@
             ]
         }
     ],
+    "CrossOriginEmbedderPolicyCredentialless": [
+        {
+            "platforms": [
+                "android",
+                "android_webview",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CrossOriginEmbedderPolicyCredentialless"
+                    ]
+                }
+            ]
+        }
+    ],
     "CupsIppPrintingBackend": [
         {
             "platforms": [
@@ -6108,25 +6108,6 @@
             ]
         }
     ],
-    "PartitionAllocPCScanBrowserOnly": [
-        {
-            "platforms": [
-                "android",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "PartitionAllocPCScanBrowserOnly"
-                    ],
-                    "disable_features": [
-                        "PartitionAllocPCScanImmediateFreeing"
-                    ]
-                }
-            ]
-        }
-    ],
     "PartitionConnectionsByNetworkIsolationKey": [
         {
             "platforms": [
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn
index fa2b2ad..dd58685 100644
--- a/third_party/abseil-cpp/BUILD.gn
+++ b/third_party/abseil-cpp/BUILD.gn
@@ -189,6 +189,7 @@
         "absl/memory:memory_test",
         "absl/meta:type_traits_test",
         "absl/strings:ascii_test",
+        "absl/strings:cord_rep_consume_test",
         "absl/strings:cordz_functions_test",
         "absl/strings:cordz_info_statistics_test",
         "absl/strings:cordz_info_test",
diff --git a/third_party/abseil-cpp/CMake/AbseilDll.cmake b/third_party/abseil-cpp/CMake/AbseilDll.cmake
index 8ee4120..78ace82 100644
--- a/third_party/abseil-cpp/CMake/AbseilDll.cmake
+++ b/third_party/abseil-cpp/CMake/AbseilDll.cmake
@@ -203,6 +203,8 @@
   "strings/internal/charconv_parse.h"
   "strings/internal/cord_internal.cc"
   "strings/internal/cord_internal.h"
+  "strings/internal/cord_rep_consume.h"
+  "strings/internal/cord_rep_consume.cc"
   "strings/internal/cord_rep_flat.h"
   "strings/internal/cord_rep_ring.cc"
   "strings/internal/cord_rep_ring.h"
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index 2a3e7bc7..cf12cc6 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: 9a7e447c511dae7276ab65fde4d04f6ed52b39c9
+Revision: 58e042da9210710dc4ac3b320e48b54e2449521e
 Security Critical: yes
 
 Description:
diff --git a/third_party/abseil-cpp/absl/flags/flag_benchmark.cc b/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
index 57584f85..fc572d9 100644
--- a/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
+++ b/third_party/abseil-cpp/absl/flags/flag_benchmark.cc
@@ -101,7 +101,39 @@
   A(AbslDuration)            \
   A(UDT)
 
-#define FLAG_DEF(T) ABSL_FLAG(T, T##_flag, {}, "");
+#define REPLICATE_0(A, T, name, index) A(T, name, index)
+#define REPLICATE_1(A, T, name, index) \
+  REPLICATE_0(A, T, name, index##0) REPLICATE_0(A, T, name, index##1)
+#define REPLICATE_2(A, T, name, index) \
+  REPLICATE_1(A, T, name, index##0) REPLICATE_1(A, T, name, index##1)
+#define REPLICATE_3(A, T, name, index) \
+  REPLICATE_2(A, T, name, index##0) REPLICATE_2(A, T, name, index##1)
+#define REPLICATE_4(A, T, name, index) \
+  REPLICATE_3(A, T, name, index##0) REPLICATE_3(A, T, name, index##1)
+#define REPLICATE_5(A, T, name, index) \
+  REPLICATE_4(A, T, name, index##0) REPLICATE_4(A, T, name, index##1)
+#define REPLICATE_6(A, T, name, index) \
+  REPLICATE_5(A, T, name, index##0) REPLICATE_5(A, T, name, index##1)
+#define REPLICATE_7(A, T, name, index) \
+  REPLICATE_6(A, T, name, index##0) REPLICATE_6(A, T, name, index##1)
+#define REPLICATE_8(A, T, name, index) \
+  REPLICATE_7(A, T, name, index##0) REPLICATE_7(A, T, name, index##1)
+#define REPLICATE_9(A, T, name, index) \
+  REPLICATE_8(A, T, name, index##0) REPLICATE_8(A, T, name, index##1)
+#if defined(_MSC_VER)
+#define REPLICATE(A, T, name) \
+  REPLICATE_7(A, T, name, 0) REPLICATE_7(A, T, name, 1)
+#define SINGLE_FLAG(T) FLAGS_##T##_flag_00000000
+#else
+#define REPLICATE(A, T, name) \
+  REPLICATE_9(A, T, name, 0) REPLICATE_9(A, T, name, 1)
+#define SINGLE_FLAG(T) FLAGS_##T##_flag_0000000000
+#endif
+#define REPLICATE_ALL(A, T, name) \
+  REPLICATE_9(A, T, name, 0) REPLICATE_9(A, T, name, 1)
+
+#define COUNT(T, name, index) +1
+constexpr size_t kNumFlags = 0 REPLICATE(COUNT, _, _);
 
 #if defined(__clang__) && defined(__linux__)
 // Force the flags used for benchmarks into a separate ELF section.
@@ -110,38 +142,87 @@
 // benchmark results more reproducible across unrelated code changes.
 #pragma clang section data = ".benchmark_flags"
 #endif
+#define DEFINE_FLAG(T, name, index) ABSL_FLAG(T, name##_##index, {}, "");
+#define FLAG_DEF(T) REPLICATE(DEFINE_FLAG, T, T##_flag);
 BENCHMARKED_TYPES(FLAG_DEF)
 #if defined(__clang__) && defined(__linux__)
 #pragma clang section data = ""
 #endif
 // Register thousands of flags to bloat up the size of the registry.
 // This mimics real life production binaries.
-#define DEFINE_FLAG_0(name) ABSL_FLAG(int, name, 0, "");
-#define DEFINE_FLAG_1(name) DEFINE_FLAG_0(name##0) DEFINE_FLAG_0(name##1)
-#define DEFINE_FLAG_2(name) DEFINE_FLAG_1(name##0) DEFINE_FLAG_1(name##1)
-#define DEFINE_FLAG_3(name) DEFINE_FLAG_2(name##0) DEFINE_FLAG_2(name##1)
-#define DEFINE_FLAG_4(name) DEFINE_FLAG_3(name##0) DEFINE_FLAG_3(name##1)
-#define DEFINE_FLAG_5(name) DEFINE_FLAG_4(name##0) DEFINE_FLAG_4(name##1)
-#define DEFINE_FLAG_6(name) DEFINE_FLAG_5(name##0) DEFINE_FLAG_5(name##1)
-#define DEFINE_FLAG_7(name) DEFINE_FLAG_6(name##0) DEFINE_FLAG_6(name##1)
-#define DEFINE_FLAG_8(name) DEFINE_FLAG_7(name##0) DEFINE_FLAG_7(name##1)
-#define DEFINE_FLAG_9(name) DEFINE_FLAG_8(name##0) DEFINE_FLAG_8(name##1)
-#define DEFINE_FLAG_10(name) DEFINE_FLAG_9(name##0) DEFINE_FLAG_9(name##1)
-#define DEFINE_FLAG_11(name) DEFINE_FLAG_10(name##0) DEFINE_FLAG_10(name##1)
-#define DEFINE_FLAG_12(name) DEFINE_FLAG_11(name##0) DEFINE_FLAG_11(name##1)
-DEFINE_FLAG_12(bloat_flag_);
+#define BLOAT_FLAG(_unused1, _unused2, index) \
+  ABSL_FLAG(int, bloat_flag_##index, 0, "");
+REPLICATE_ALL(BLOAT_FLAG, _, _)
 
 namespace {
 
-#define BM_GetFlag(T)                                            \
-  void BM_GetFlag_##T(benchmark::State& state) {                 \
-    for (auto _ : state) {                                       \
-      benchmark::DoNotOptimize(absl::GetFlag(FLAGS_##T##_flag)); \
-    }                                                            \
-  }                                                              \
-  BENCHMARK(BM_GetFlag_##T)->ThreadRange(1, 16);
+#define FLAG_PTR(T, name, index) &FLAGS_##name##_##index,
+#define FLAG_PTR_ARR(T)                              \
+  static constexpr absl::Flag<T>* FlagPtrs_##T[] = { \
+      REPLICATE(FLAG_PTR, T, T##_flag)};
+BENCHMARKED_TYPES(FLAG_PTR_ARR)
 
-BENCHMARKED_TYPES(BM_GetFlag)
+#define BM_SingleGetFlag(T)                                    \
+  void BM_SingleGetFlag_##T(benchmark::State& state) {         \
+    for (auto _ : state) {                                     \
+      benchmark::DoNotOptimize(absl::GetFlag(SINGLE_FLAG(T))); \
+    }                                                          \
+  }                                                            \
+  BENCHMARK(BM_SingleGetFlag_##T)->ThreadRange(1, 16);
+
+BENCHMARKED_TYPES(BM_SingleGetFlag)
+
+template <typename T>
+struct Accumulator {
+  using type = T;
+};
+template <>
+struct Accumulator<String> {
+  using type = size_t;
+};
+template <>
+struct Accumulator<VectorOfStrings> {
+  using type = size_t;
+};
+template <>
+struct Accumulator<OptionalInt> {
+  using type = bool;
+};
+template <>
+struct Accumulator<OptionalString> {
+  using type = bool;
+};
+template <>
+struct Accumulator<UDT> {
+  using type = bool;
+};
+
+template <typename T>
+void Accumulate(typename Accumulator<T>::type& a, const T& f) {
+  a += f;
+}
+void Accumulate(bool& a, bool f) { a = a || f; }
+void Accumulate(size_t& a, const std::string& f) { a += f.size(); }
+void Accumulate(size_t& a, const std::vector<std::string>& f) { a += f.size(); }
+void Accumulate(bool& a, const OptionalInt& f) { a |= f.has_value(); }
+void Accumulate(bool& a, const OptionalString& f) { a |= f.has_value(); }
+void Accumulate(bool& a, const UDT& f) {
+  a |= reinterpret_cast<int64_t>(&f) & 0x1;
+}
+
+#define BM_ManyGetFlag(T)                            \
+  void BM_ManyGetFlag_##T(benchmark::State& state) { \
+    Accumulator<T>::type res = {};                   \
+    while (state.KeepRunningBatch(kNumFlags)) {      \
+      for (auto* flag_ptr : FlagPtrs_##T) {          \
+        Accumulate(res, absl::GetFlag(*flag_ptr));   \
+      }                                              \
+    }                                                \
+    benchmark::DoNotOptimize(res);                   \
+  }                                                  \
+  BENCHMARK(BM_ManyGetFlag_##T)->ThreadRange(1, 8);
+
+BENCHMARKED_TYPES(BM_ManyGetFlag)
 
 void BM_ThreadedFindCommandLineFlag(benchmark::State& state) {
   char dummy[] = "dummy";
@@ -150,17 +231,18 @@
   // is finalized.
   absl::ParseCommandLine(1, argv);
 
-  for (auto s : state) {
-    benchmark::DoNotOptimize(
-        absl::FindCommandLineFlag("bloat_flag_010101010101"));
+  while (state.KeepRunningBatch(kNumFlags)) {
+    for (auto* flag_ptr : FlagPtrs_bool) {
+      benchmark::DoNotOptimize(absl::FindCommandLineFlag(flag_ptr->Name()));
+    }
   }
 }
 BENCHMARK(BM_ThreadedFindCommandLineFlag)->ThreadRange(1, 16);
 
 }  // namespace
 
-#define InvokeGetFlag(T)                                               \
-  T AbslInvokeGetFlag##T() { return absl::GetFlag(FLAGS_##T##_flag); } \
+#define InvokeGetFlag(T)                                             \
+  T AbslInvokeGetFlag##T() { return absl::GetFlag(SINGLE_FLAG(T)); } \
   int odr##T = (benchmark::DoNotOptimize(AbslInvokeGetFlag##T), 1);
 
 BENCHMARKED_TYPES(InvokeGetFlag)
diff --git a/third_party/abseil-cpp/absl/hash/internal/hash.h b/third_party/abseil-cpp/absl/hash/internal/hash.h
index 69dbbc6..90627e0 100644
--- a/third_party/abseil-cpp/absl/hash/internal/hash.h
+++ b/third_party/abseil-cpp/absl/hash/internal/hash.h
@@ -856,8 +856,15 @@
   }
 
   ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {
+#if defined(__aarch64__)
+    // On AArch64, calculating a 128-bit product is inefficient, because it
+    // requires a sequence of two instructions to calculate the upper and lower
+    // halves of the result.
+    using MultType = uint64_t;
+#else
     using MultType =
         absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>;
+#endif
     // We do the addition in 64-bit space to make sure the 128-bit
     // multiplication is fast. If we were to do it as MultType the compiler has
     // to assume that the high word is non-zero and needs to perform 2
diff --git a/third_party/abseil-cpp/absl/random/internal/seed_material.cc b/third_party/abseil-cpp/absl/random/internal/seed_material.cc
index 7c1d9efa..c03cad85 100644
--- a/third_party/abseil-cpp/absl/random/internal/seed_material.cc
+++ b/third_party/abseil-cpp/absl/random/internal/seed_material.cc
@@ -57,6 +57,12 @@
 #define ABSL_RANDOM_USE_GET_ENTROPY 1
 #endif
 
+#if defined(__EMSCRIPTEN__)
+#include <sys/random.h>
+// Emscripten has getentropy, but it resides in a different header.
+#define ABSL_RANDOM_USE_GET_ENTROPY 1
+#endif
+
 #if defined(ABSL_RANDOM_USE_BCRYPT)
 #include <bcrypt.h>
 
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel
index 1cb5b3e..b70aac3 100644
--- a/third_party/abseil-cpp/absl/strings/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -269,10 +269,12 @@
     name = "cord_internal",
     srcs = [
         "internal/cord_internal.cc",
+        "internal/cord_rep_consume.cc",
         "internal/cord_rep_ring.cc",
     ],
     hdrs = [
         "internal/cord_internal.h",
+        "internal/cord_rep_consume.h",
         "internal/cord_rep_flat.h",
         "internal/cord_rep_ring.h",
         "internal/cord_rep_ring_reader.h",
@@ -292,6 +294,7 @@
         "//absl/container:compressed_tuple",
         "//absl/container:inlined_vector",
         "//absl/container:layout",
+        "//absl/functional:function_ref",
         "//absl/meta:type_traits",
     ],
 )
@@ -650,6 +653,22 @@
 )
 
 cc_test(
+    name = "cord_rep_consume_test",
+    size = "medium",
+    srcs = ["internal/cord_rep_consume_test.cc"],
+    copts = ABSL_TEST_COPTS,
+    visibility = ["//visibility:private"],
+    deps = [
+        ":cord_internal",
+        ":strings",
+        "//absl/base:config",
+        "//absl/base:core_headers",
+        "//absl/debugging:leak_check",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
+
+cc_test(
     name = "cord_ring_test",
     size = "medium",
     srcs = ["cord_ring_test.cc"],
diff --git a/third_party/abseil-cpp/absl/strings/BUILD.gn b/third_party/abseil-cpp/absl/strings/BUILD.gn
index 03866af..09042b71 100644
--- a/third_party/abseil-cpp/absl/strings/BUILD.gn
+++ b/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -120,10 +120,12 @@
 absl_source_set("cord_internal") {
   sources = [
     "internal/cord_internal.cc",
+    "internal/cord_rep_consume.cc",
     "internal/cord_rep_ring.cc",
   ]
   public = [
     "internal/cord_internal.h",
+    "internal/cord_rep_consume.h",
     "internal/cord_rep_flat.h",
     "internal/cord_rep_ring.h",
     "internal/cord_rep_ring_reader.h",
@@ -140,6 +142,7 @@
     "//third_party/abseil-cpp/absl/container:compressed_tuple",
     "//third_party/abseil-cpp/absl/container:inlined_vector",
     "//third_party/abseil-cpp/absl/container:layout",
+    "//third_party/abseil-cpp/absl/functional:function_ref",
     "//third_party/abseil-cpp/absl/meta:type_traits",
   ]
 }
@@ -420,6 +423,20 @@
   ]
 }
 
+absl_source_set("cord_rep_consume_test") {
+  testonly = true
+  sources = ["internal/cord_rep_consume_test.cc"]
+  deps = [
+    ":cord_internal",
+    ":strings",
+    "//third_party/abseil-cpp/absl/base:config",
+    "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/debugging:leak_check",
+    "//third_party/googletest:gmock",
+    "//third_party/googletest:gtest",
+  ]
+}
+
 absl_source_set("pow10_helper") {
   testonly = true
   sources = [ "internal/pow10_helper.cc" ]
diff --git a/third_party/abseil-cpp/absl/strings/CMakeLists.txt b/third_party/abseil-cpp/absl/strings/CMakeLists.txt
index 0246dc3..d79ef712 100644
--- a/third_party/abseil-cpp/absl/strings/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/strings/CMakeLists.txt
@@ -555,11 +555,13 @@
     cord_internal
   HDRS
     "internal/cord_internal.h"
+    "internal/cord_rep_consume.h"
     "internal/cord_rep_flat.h"
     "internal/cord_rep_ring.h"
     "internal/cord_rep_ring_reader.h"
   SRCS
     "internal/cord_internal.cc"
+    "internal/cord_rep_consume.cc"
     "internal/cord_rep_ring.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
@@ -904,6 +906,24 @@
 
 absl_cc_test(
   NAME
+    cord_rep_consume_test
+  SRCS
+    "internal/cord_rep_consume_test.cc"
+  COPTS
+    ${ABSL_TEST_COPTS}
+  DEPS
+    absl::base
+    absl::config
+    absl::cord_internal
+    absl::core_headers
+    absl::function_ref
+    absl::raw_logging_internal
+    absl::strings
+    GTest::gmock_main
+)
+
+absl_cc_test(
+  NAME
     cord_ring_test
   SRCS
     "cord_ring_test.cc"
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_internal.h b/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
index 1e2436b..bddc981596 100644
--- a/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_internal.h
@@ -150,22 +150,24 @@
 struct CordRepFlat;
 struct CordRepSubstring;
 class CordRepRing;
+class CordRepBtree;
 
 // Various representations that we allow
 enum CordRepKind {
   CONCAT = 0,
   SUBSTRING = 1,
-  RING = 2,
-  EXTERNAL = 3,
+  BTREE = 2,
+  RING = 3,
+  EXTERNAL = 4,
 
   // We have different tags for different sized flat arrays,
-  // starting with FLAT, and limited to MAX_FLAT_TAG. The 224 value is based on
+  // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on
   // the current 'size to tag' encoding of 8 / 32 bytes. If a new tag is needed
   // in the future, then 'FLAT' and 'MAX_FLAT_TAG' should be adjusted as well
   // as the Tag <---> Size logic so that FLAT stil represents the minimum flat
   // allocation size. (32 bytes as of now).
-  FLAT = 4,
-  MAX_FLAT_TAG = 224
+  FLAT = 5,
+  MAX_FLAT_TAG = 225
 };
 
 // There are various locations where we want to check if some rep is a 'plain'
@@ -175,8 +177,9 @@
 // so likewise align RING to EXTERNAL.
 // Note that we can leave this optimization to the compiler. The compiler will
 // DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`.
-static_assert(EXTERNAL == RING + 1, "RING and EXTERNAL values not consecutive");
-static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT values not consecutive");
+static_assert(RING == BTREE + 1, "BTREE and RING not consecutive");
+static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive");
+static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive");
 
 struct CordRep {
   CordRep() = default;
@@ -203,6 +206,9 @@
   inline CordRepFlat* flat();
   inline const CordRepFlat* flat() const;
 
+  inline CordRepBtree* btree();
+  inline const CordRepBtree* btree() const;
+
   // --------------------------------------------------------------------
   // Memory management
 
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc
new file mode 100644
index 0000000..8151454
--- /dev/null
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc
@@ -0,0 +1,129 @@
+// Copyright 2021 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/internal/cord_rep_consume.h"
+
+#include <array>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/functional/function_ref.h"
+#include "absl/strings/internal/cord_internal.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace cord_internal {
+
+namespace {
+
+// Unrefs the provided `substring`, and returns `substring->child`
+// Adds or assumes a reference on `substring->child`
+CordRep* ClipSubstring(CordRepSubstring* substring) {
+  CordRep* child = substring->child;
+  if (substring->refcount.IsOne()) {
+    delete substring;
+  } else {
+    CordRep::Ref(child);
+    CordRep::Unref(substring);
+  }
+  return child;
+}
+
+// Unrefs the provided `concat`, and returns `{concat->left, concat->right}`
+// Adds or assumes a reference on `concat->left` and `concat->right`.
+// Returns an array of 2 elements containing the left and right nodes.
+std::array<CordRep*, 2> ClipConcat(CordRepConcat* concat) {
+  std::array<CordRep*, 2> result{concat->left, concat->right};
+  if (concat->refcount.IsOne()) {
+    delete concat;
+  } else {
+    CordRep::Ref(result[0]);
+    CordRep::Ref(result[1]);
+    CordRep::Unref(concat);
+  }
+  return result;
+}
+
+void Consume(bool forward, CordRep* rep, ConsumeFn consume_fn) {
+  size_t offset = 0;
+  size_t length = rep->length;
+  struct Entry {
+    CordRep* rep;
+    size_t offset;
+    size_t length;
+  };
+  absl::InlinedVector<Entry, 40> stack;
+
+  for (;;) {
+    if (rep->tag == CONCAT) {
+      std::array<CordRep*, 2> res = ClipConcat(rep->concat());
+      CordRep* left = res[0];
+      CordRep* right = res[1];
+
+      if (left->length <= offset) {
+        // Don't need left node
+        offset -= left->length;
+        CordRep::Unref(left);
+        rep = right;
+        continue;
+      }
+
+      size_t length_left = left->length - offset;
+      if (length_left >= length) {
+        // Don't need right node
+        CordRep::Unref(right);
+        rep = left;
+        continue;
+      }
+
+      // Need both nodes
+      size_t length_right = length - length_left;
+      if (forward) {
+        stack.push_back({right, 0, length_right});
+        rep = left;
+        length = length_left;
+      } else {
+        stack.push_back({left, offset, length_left});
+        rep = right;
+        offset = 0;
+        length = length_right;
+      }
+    } else if (rep->tag == SUBSTRING) {
+      offset += rep->substring()->start;
+      rep = ClipSubstring(rep->substring());
+    } else {
+      consume_fn(rep, offset, length);
+      if (stack.empty()) return;
+
+      rep = stack.back().rep;
+      offset = stack.back().offset;
+      length = stack.back().length;
+      stack.pop_back();
+    }
+  }
+}
+
+}  // namespace
+
+void Consume(CordRep* rep, ConsumeFn consume_fn) {
+  return Consume(true, rep, std::move(consume_fn));
+}
+
+void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) {
+  return Consume(false, rep, std::move(consume_fn));
+}
+
+}  // namespace cord_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h
new file mode 100644
index 0000000..d46fca2
--- /dev/null
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.h
@@ -0,0 +1,50 @@
+// Copyright 2021 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_
+#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_
+
+#include <functional>
+
+#include "absl/functional/function_ref.h"
+#include "absl/strings/internal/cord_internal.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace cord_internal {
+
+// Functor for the Consume() and ReverseConsume() functions:
+//   void ConsumeFunc(CordRep* rep, size_t offset, size_t length);
+// See the Consume() and ReverseConsume() function comments for documentation.
+using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>;
+
+// Consume() and ReverseConsume() consume CONCAT based trees and invoke the
+// provided functor with the contained nodes in the proper forward or reverse
+// order, which is used to convert CONCAT trees into other tree or cord data.
+// All CONCAT and SUBSTRING nodes are processed internally. The 'offset`
+// parameter of the functor is non-zero for any nodes below SUBSTRING nodes.
+// It's up to the caller to form these back into SUBSTRING nodes or otherwise
+// store offset / prefix information. These functions are intended to be used
+// only for migration / transitional code where due to factors such as ODR
+// violations, we can not 100% guarantee that all code respects 'new format'
+// settings and flags, so we need to be able to parse old data on the fly until
+// all old code is deprecated / no longer the default format.
+void Consume(CordRep* rep, ConsumeFn consume_fn);
+void ReverseConsume(CordRep* rep, ConsumeFn consume_fn);
+
+}  // namespace cord_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume_test.cc b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume_test.cc
new file mode 100644
index 0000000..e507824b
--- /dev/null
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_consume_test.cc
@@ -0,0 +1,173 @@
+// Copyright 2021 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/internal/cord_rep_consume.h"
+
+#include <functional>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cord_rep_flat.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace cord_internal {
+namespace {
+
+using testing::InSequence;
+using testing::MockFunction;
+
+// Returns the depth of a node
+int Depth(const CordRep* rep) {
+  return (rep->tag == CONCAT) ? rep->concat()->depth() : 0;
+}
+
+// Creates a concatenation of the specified nodes.
+CordRepConcat* CreateConcat(CordRep* left, CordRep* right) {
+  auto* concat = new CordRepConcat();
+  concat->tag = CONCAT;
+  concat->left = left;
+  concat->right = right;
+  concat->length = left->length + right->length;
+  concat->set_depth(1 + (std::max)(Depth(left), Depth(right)));
+  return concat;
+}
+
+// Creates a flat with the length set to `length`
+CordRepFlat* CreateFlatWithLength(size_t length) {
+  auto* flat = CordRepFlat::New(length);
+  flat->length = length;
+  return flat;
+}
+
+// Creates a substring node on the specified child.
+CordRepSubstring* CreateSubstring(CordRep* child, size_t start, size_t length) {
+  auto* rep = new CordRepSubstring();
+  rep->length = length;
+  rep->tag = SUBSTRING;
+  rep->start = start;
+  rep->child = child;
+  return rep;
+}
+
+// Flats we use in the tests
+CordRep* flat[6];
+
+// Creates a test tree
+CordRep* CreateTestTree() {
+  flat[0] = CreateFlatWithLength(1);
+  flat[1] = CreateFlatWithLength(7);
+  CordRepConcat* left = CreateConcat(flat[0], CreateSubstring(flat[1], 2, 4));
+
+  flat[2] = CreateFlatWithLength(9);
+  flat[3] = CreateFlatWithLength(13);
+  CordRepConcat* right1 = CreateConcat(flat[2], flat[3]);
+
+  flat[4] = CreateFlatWithLength(15);
+  flat[5] = CreateFlatWithLength(19);
+  CordRepConcat* right2 = CreateConcat(flat[4], flat[5]);
+
+  CordRepConcat* right = CreateConcat(right1, CreateSubstring(right2, 5, 17));
+  return CreateConcat(left, right);
+}
+
+TEST(CordRepConsumeTest, Consume) {
+  InSequence in_sequence;
+  CordRep* tree = CreateTestTree();
+  MockFunction<void(CordRep*, size_t, size_t)> consume;
+  EXPECT_CALL(consume, Call(flat[0], 0, 1));
+  EXPECT_CALL(consume, Call(flat[1], 2, 4));
+  EXPECT_CALL(consume, Call(flat[2], 0, 9));
+  EXPECT_CALL(consume, Call(flat[3], 0, 13));
+  EXPECT_CALL(consume, Call(flat[4], 5, 10));
+  EXPECT_CALL(consume, Call(flat[5], 0, 7));
+  Consume(tree, consume.AsStdFunction());
+  for (CordRep* rep : flat) {
+    EXPECT_TRUE(rep->refcount.IsOne());
+    CordRep::Unref(rep);
+  }
+}
+
+TEST(CordRepConsumeTest, ConsumeShared) {
+  InSequence in_sequence;
+  CordRep* tree = CreateTestTree();
+  MockFunction<void(CordRep*, size_t, size_t)> consume;
+  EXPECT_CALL(consume, Call(flat[0], 0, 1));
+  EXPECT_CALL(consume, Call(flat[1], 2, 4));
+  EXPECT_CALL(consume, Call(flat[2], 0, 9));
+  EXPECT_CALL(consume, Call(flat[3], 0, 13));
+  EXPECT_CALL(consume, Call(flat[4], 5, 10));
+  EXPECT_CALL(consume, Call(flat[5], 0, 7));
+  Consume(CordRep::Ref(tree), consume.AsStdFunction());
+  for (CordRep* rep : flat) {
+    EXPECT_FALSE(rep->refcount.IsOne());
+    CordRep::Unref(rep);
+  }
+  CordRep::Unref(tree);
+}
+
+TEST(CordRepConsumeTest, Reverse) {
+  InSequence in_sequence;
+  CordRep* tree = CreateTestTree();
+  MockFunction<void(CordRep*, size_t, size_t)> consume;
+  EXPECT_CALL(consume, Call(flat[5], 0, 7));
+  EXPECT_CALL(consume, Call(flat[4], 5, 10));
+  EXPECT_CALL(consume, Call(flat[3], 0, 13));
+  EXPECT_CALL(consume, Call(flat[2], 0, 9));
+  EXPECT_CALL(consume, Call(flat[1], 2, 4));
+  EXPECT_CALL(consume, Call(flat[0], 0, 1));
+  ReverseConsume(tree, consume.AsStdFunction());
+  for (CordRep* rep : flat) {
+    EXPECT_TRUE(rep->refcount.IsOne());
+    CordRep::Unref(rep);
+  }
+}
+
+TEST(CordRepConsumeTest, ReverseShared) {
+  InSequence in_sequence;
+  CordRep* tree = CreateTestTree();
+  MockFunction<void(CordRep*, size_t, size_t)> consume;
+  EXPECT_CALL(consume, Call(flat[5], 0, 7));
+  EXPECT_CALL(consume, Call(flat[4], 5, 10));
+  EXPECT_CALL(consume, Call(flat[3], 0, 13));
+  EXPECT_CALL(consume, Call(flat[2], 0, 9));
+  EXPECT_CALL(consume, Call(flat[1], 2, 4));
+  EXPECT_CALL(consume, Call(flat[0], 0, 1));
+  ReverseConsume(CordRep::Ref(tree), consume.AsStdFunction());
+  for (CordRep* rep : flat) {
+    EXPECT_FALSE(rep->refcount.IsOne());
+    CordRep::Unref(rep);
+  }
+  CordRep::Unref(tree);
+}
+
+TEST(CordRepConsumeTest, UnreachableFlat) {
+  InSequence in_sequence;
+  CordRepFlat* flat1 = CreateFlatWithLength(10);
+  CordRepFlat* flat2 = CreateFlatWithLength(20);
+  CordRepConcat* concat = CreateConcat(flat1, flat2);
+  CordRepSubstring* tree = CreateSubstring(concat, 15, 10);
+  MockFunction<void(CordRep*, size_t, size_t)> consume;
+  EXPECT_CALL(consume, Call(flat2, 5, 10));
+  Consume(tree, consume.AsStdFunction());
+  EXPECT_TRUE(flat2->refcount.IsOne());
+  CordRep::Unref(flat2);
+}
+
+}  // namespace
+}  // namespace cord_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
index a98aa9d..cddb282 100644
--- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_flat.h
@@ -44,11 +44,11 @@
 static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead;
 
 constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) {
-  return static_cast<uint8_t>((size <= 1024) ? size / 8
-                                             : 128 + size / 32 - 1024 / 32);
+  return static_cast<uint8_t>((size <= 1024) ? size / 8 + 1
+                                             : 129 + size / 32 - 1024 / 32);
 }
 
-static_assert(kMinFlatSize / 8 >= FLAT, "");
+static_assert(kMinFlatSize / 8 + 1 >= FLAT, "");
 static_assert(AllocatedSizeToTagUnchecked(kMaxFlatSize) <= MAX_FLAT_TAG, "");
 
 // Helper functions for rounded div, and rounding to exact sizes.
@@ -73,7 +73,7 @@
 
 // Converts the provided tag to the corresponding allocated size
 constexpr size_t TagToAllocatedSize(uint8_t tag) {
-  return (tag <= 128) ? (tag * 8) : (1024 + (tag - 128) * 32);
+  return (tag <= 129) ? ((tag - 1) * 8) : (1024 + (tag - 129) * 32);
 }
 
 // Converts the provided tag to the corresponding available data length
@@ -82,7 +82,7 @@
 }
 
 // Enforce that kMaxFlatSize maps to a well-known exact tag value.
-static_assert(TagToAllocatedSize(224) == kMaxFlatSize, "Bad tag logic");
+static_assert(TagToAllocatedSize(225) == kMaxFlatSize, "Bad tag logic");
 
 struct CordRepFlat : public CordRep {
   // Creates a new flat node.
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc b/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc
index f78c94e1..20a6fc2 100644
--- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc
+++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc
@@ -26,6 +26,7 @@
 #include "absl/base/macros.h"
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cord_rep_consume.h"
 #include "absl/strings/internal/cord_rep_flat.h"
 
 namespace absl {
@@ -49,14 +50,6 @@
   }
 }
 
-// Removes a reference from `rep` only.
-// Asserts that the refcount after decrement is not zero.
-inline bool UnrefNeverOne(CordRep* rep) {
-  bool result = rep->refcount.Decrement();
-  assert(result);
-  return result;
-}
-
 // Creates a flat from the provided string data, allocating up to `extra`
 // capacity in the returned flat depending on kMaxFlatLength limitations.
 // Requires `len` to be less or equal to `kMaxFlatLength`
@@ -68,40 +61,6 @@
   return rep;
 }
 
-// Unrefs the provided `substring`, and returns `substring->child`
-// Adds or assumes a reference on `substring->child`
-CordRep* ClipSubstring(CordRepSubstring* substring) {
-  CordRep* child = substring->child;
-  if (substring->refcount.IsOne()) {
-    delete substring;
-  } else {
-    CordRep::Ref(child);
-    if (ABSL_PREDICT_FALSE(!substring->refcount.Decrement())) {
-      UnrefNeverOne(child);
-      delete substring;
-    }
-  }
-  return child;
-}
-
-// Unrefs the provided `concat`, and returns `{concat->left, concat->right}`
-// Adds or assumes a reference on `concat->left` and `concat->right`.
-std::pair<CordRep*, CordRep*> ClipConcat(CordRepConcat* concat) {
-  auto result = std::make_pair(concat->left, concat->right);
-  if (concat->refcount.IsOne()) {
-    delete concat;
-  } else {
-    CordRep::Ref(result.first);
-    CordRep::Ref(result.second);
-    if (ABSL_PREDICT_FALSE(!concat->refcount.Decrement())) {
-      UnrefNeverOne(result.first);
-      UnrefNeverOne(result.second);
-      delete concat;
-    }
-  }
-  return result;
-}
-
 // Unrefs the entries in `[head, tail)`.
 // Requires all entries to be a FLAT or EXTERNAL node.
 void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) {
@@ -117,79 +76,6 @@
   });
 }
 
-template <typename F>
-void Consume(Direction direction, CordRep* rep, F&& fn) {
-  size_t offset = 0;
-  size_t length = rep->length;
-  struct Entry {
-    CordRep* rep;
-    size_t offset;
-    size_t length;
-  };
-  absl::InlinedVector<Entry, 40> stack;
-
-  for (;;) {
-    if (rep->tag >= FLAT || rep->tag == EXTERNAL || rep->tag == RING) {
-      fn(rep, offset, length);
-      if (stack.empty()) return;
-
-      rep = stack.back().rep;
-      offset = stack.back().offset;
-      length = stack.back().length;
-      stack.pop_back();
-    } else if (rep->tag == SUBSTRING) {
-      offset += rep->substring()->start;
-      rep = ClipSubstring(rep->substring());
-    } else if (rep->tag == CONCAT) {
-      auto res = ClipConcat(rep->concat());
-      CordRep* left = res.first;
-      CordRep* right = res.second;
-
-      if (left->length <= offset) {
-        // Don't need left node
-        offset -= left->length;
-        CordRep::Unref(left);
-        rep = right;
-        continue;
-      }
-
-      size_t length_left = left->length - offset;
-      if (length_left >= length) {
-        // Don't need right node
-        CordRep::Unref(right);
-        rep = left;
-        continue;
-      }
-
-      // Need both nodes
-      size_t length_right = length - length_left;
-      if (direction == Direction::kReversed) {
-        stack.push_back({left, offset, length_left});
-        rep = right;
-        offset = 0;
-        length = length_right;
-      } else {
-        stack.push_back({right, 0, length_right});
-        rep = left;
-        length = length_left;
-      }
-    } else {
-      assert("Valid tag" == nullptr);
-      return;
-    }
-  }
-}
-
-template <typename F>
-void Consume(CordRep* rep, F&& fn) {
-  return Consume(Direction::kForward, rep, std::forward<F>(fn));
-}
-
-template <typename F>
-void RConsume(CordRep* rep, F&& fn) {
-  return Consume(Direction::kReversed, rep, std::forward<F>(fn));
-}
-
 }  // namespace
 
 std::ostream& operator<<(std::ostream& s, const CordRepRing& rep) {
@@ -581,7 +467,7 @@
 }
 
 CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) {
-  RConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
+  ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
     if (IsFlatOrExternal(child_arg)) {
       rep = PrependLeaf(rep, child_arg, offset, len);
     } else {
diff --git a/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h b/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
index 17c1bfe..e7664216 100644
--- a/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
+++ b/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h
@@ -64,7 +64,7 @@
   ConvertibleToStringView(const std::string& s)  // NOLINT(runtime/explicit)
       : value_(s) {}
 
-  // Matches rvalue strings and moves their data to a member.
+  // Disable conversion from rvalue strings.
   ConvertibleToStringView(std::string&& s) = delete;
   ConvertibleToStringView(const std::string&& s) = delete;
 
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index 38b18887..98930a66 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -52,7 +52,6 @@
     ??$?0AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z
     ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@X@?$__compressed_pair_elem@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@$0A@$0A@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@@Z
-    ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z
     ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
@@ -641,7 +640,6 @@
     ??$forward@AEAPEAPEBUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEBUCordRep@cord_internal@absl@@AEAPEAPEBU234@@Z
     ??$forward@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z
     ??$forward@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@YAAEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@01@AEAPEAU201@@Z
-    ??$forward@AEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z
     ??$forward@AEAPEAUPayload@status_internal@absl@@@__1@std@@YAAEAPEAUPayload@status_internal@absl@@AEAPEAU234@@Z
     ??$forward@AEAPEAUSubRange@absl@@@__1@std@@YAAEAPEAUSubRange@absl@@AEAPEAU23@@Z
     ??$forward@AEAPEAUThreadIdentity@base_internal@absl@@@__1@std@@YAAEAPEAUThreadIdentity@base_internal@absl@@AEAPEAU234@@Z
@@ -743,7 +741,6 @@
     ??$get@Vstring_view@absl@@V12@@?$__get_pair@$0A@@__1@std@@SAAEBVstring_view@absl@@AEBU?$pair@Vstring_view@absl@@V12@@12@@Z
     ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z
     ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z
-    ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -780,6 +777,7 @@
     ??$move@AEAUTransition@cctz@time_internal@absl@@@__1@std@@YA$$QEAUTransition@cctz@time_internal@absl@@AEAU2345@@Z
     ??$move@AEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YA$$QEAUTransitionType@cctz@time_internal@absl@@AEAU2345@@Z
     ??$move@AEAUViableSubstitution@strings_internal@absl@@@__1@std@@YA$$QEAUViableSubstitution@strings_internal@absl@@AEAU234@@Z
+    ??$move@AEAV?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@@__1@std@@YA$$QEAV?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@AEAV23@@Z
     ??$move@AEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@01@AEAV201@@Z
     ??$move@AEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@01@AEAV201@@Z
     ??$move@AEAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV201@@Z
@@ -1303,6 +1301,7 @@
     ??A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAAEBUPayload@status_internal@1@_K@Z
     ??A?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAAEBVFormatArgImpl@str_format_internal@1@_K@Z
     ??A?$Span@I@absl@@QEBAAEAI_K@Z
+    ??A?$array@PEAUCordRep@cord_internal@absl@@$01@__1@std@@QEAAAEAPEAUCordRep@cord_internal@absl@@_K@Z
     ??A?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEBAAEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@_K@Z
     ??A?$unordered_map@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??A?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAUTransition@cctz@time_internal@absl@@_K@Z
@@ -1441,6 +1440,7 @@
     ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z
     ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z
     ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@3@PEBU453@@Z@QEBA?A?<auto>@@XZ
+    ??R?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@QEBAXPEAUCordRep@cord_internal@1@_K1@Z
     ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QEBAXV?$Span@I@1@@Z
     ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QEBAXVstring_view@1@@Z
     ??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -1465,7 +1465,6 @@
     ??RByCivilTime@Transition@cctz@time_internal@absl@@QEBA_NAEBU1234@0@Z
     ??RByUnixTime@Transition@cctz@time_internal@absl@@QEBA_NAEBU1234@0@Z
     ??Sabsl@@YA?AVuint128@0@V10@@Z
-    ??Tabsl@@YA?AVuint128@0@V10@0@Z
     ??Uabsl@@YA?AVuint128@0@V10@0@Z
     ??Ustr_format_internal@absl@@YA?AW4Flags@01@W4201@0@Z
     ??XDuration@absl@@QEAAAEAV01@N@Z
@@ -1630,6 +1629,7 @@
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PEAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@3@@Z
+    ?Consume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?ConsumePrefix@absl@@YA_NPEAVstring_view@1@V21@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPEBDPEBD0PEAUUnboundConversion@12@PEAH@Z
     ?Contains@str_format_internal@absl@@YA_NW4FormatConversionCharSet@2@D@Z
@@ -2228,6 +2228,7 @@
     ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?RoundUp@cord_internal@absl@@YA_K_K0@Z
     ?RoundUpForTag@cord_internal@absl@@YA_K_K@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 2d3c6fca..11587fa0 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -269,6 +269,7 @@
     ?CompareSlowPath@Cord@absl@@AEBAHAEBV12@_K1@Z
     ?CompareSlowPath@Cord@absl@@AEBAHVstring_view@2@_K1@Z
     ?ConcatNodes@CordForest@absl@@QEAAPEAUCordRep@cord_internal@2@XZ
+    ?Consume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPEBDPEBD0PEAUUnboundConversion@12@PEAH@Z
     ?ConvertDateTime@absl@@YA?AUTimeConversion@1@_JHHHHHVTimeZone@1@@Z
     ?ConvertDeletedToEmptyAndFullToDeleted@container_internal@absl@@YAXPEAC_K@Z
@@ -612,6 +613,7 @@
     ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
     ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index 4376fb41..e843c5f 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -52,7 +52,6 @@
     ??$?0AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@23@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@12@@Z
     ??$?0AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@X@?$__compressed_pair_elem@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@$0A@$0A@@__1@std@@QEAA@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@12@@Z
-    ??$?0AEAPEAUCordRep@cord_internal@absl@@AEAPEAU012@$0A@@?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@__1@std@@QEAA@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@?$__compressed_pair@PEAUThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
     ??$?0AEAPEAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PEAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QEAA@AEAPEAUThreadIdentity@base_internal@absl@@@Z
     ??$?0AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QEAA@AEAPEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QEAU__default_init_tag@12@@Z
@@ -643,7 +642,6 @@
     ??$forward@AEAPEAPEBUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAPEBUCordRep@cord_internal@absl@@AEAPEAPEBU234@@Z
     ??$forward@AEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEAPEAPEBV23456@@Z
     ??$forward@AEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@YAAEAPEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@01@AEAPEAU201@@Z
-    ??$forward@AEAPEAUCordRep@cord_internal@absl@@@__1@std@@YAAEAPEAUCordRep@cord_internal@absl@@AEAPEAU234@@Z
     ??$forward@AEAPEAUPayload@status_internal@absl@@@__1@std@@YAAEAPEAUPayload@status_internal@absl@@AEAPEAU234@@Z
     ??$forward@AEAPEAUSubRange@absl@@@__1@std@@YAAEAPEAUSubRange@absl@@AEAPEAU23@@Z
     ??$forward@AEAPEAUThreadIdentity@base_internal@absl@@@__1@std@@YAAEAPEAUThreadIdentity@base_internal@absl@@AEAPEAU234@@Z
@@ -745,7 +743,6 @@
     ??$get@Vstring_view@absl@@V12@@?$__get_pair@$0A@@__1@std@@SAAEBVstring_view@absl@@AEBU?$pair@Vstring_view@absl@@V12@@12@@Z
     ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z
     ??$lower_bound@PEBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPEBUTransition@cctz@time_internal@absl@@PEBU2345@0AEBU2345@UByUnixTime@2345@@Z
-    ??$make_pair@AEAPEAUCordRep@cord_internal@absl@@AEAPEAU123@@__1@std@@YA?AU?$pair@PEAUCordRep@cord_internal@absl@@PEAU123@@01@AEAPEAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AEAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$max_size@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SA_KAEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -782,6 +779,7 @@
     ??$move@AEAUTransition@cctz@time_internal@absl@@@__1@std@@YA$$QEAUTransition@cctz@time_internal@absl@@AEAU2345@@Z
     ??$move@AEAUTransitionType@cctz@time_internal@absl@@@__1@std@@YA$$QEAUTransitionType@cctz@time_internal@absl@@AEAU2345@@Z
     ??$move@AEAUViableSubstitution@strings_internal@absl@@@__1@std@@YA$$QEAUViableSubstitution@strings_internal@absl@@AEAU234@@Z
+    ??$move@AEAV?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@@__1@std@@YA$$QEAV?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@AEAV23@@Z
     ??$move@AEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@01@AEAV201@@Z
     ??$move@AEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@01@AEAV201@@Z
     ??$move@AEAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QEAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AEAV201@@Z
@@ -1305,6 +1303,7 @@
     ??A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEBAAEBUPayload@status_internal@1@_K@Z
     ??A?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEBAAEBVFormatArgImpl@str_format_internal@1@_K@Z
     ??A?$Span@I@absl@@QEBAAEAI_K@Z
+    ??A?$array@PEAUCordRep@cord_internal@absl@@$01@__1@std@@QEAAAEAPEAUCordRep@cord_internal@absl@@_K@Z
     ??A?$unique_ptr@$$BY0A@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QEBAAEAPEAU?$__hash_node_base@PEAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PEAX@__1@std@@@12@_K@Z
     ??A?$unordered_map@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QEAAAEAPEBVImpl@time_zone@cctz@time_internal@absl@@AEBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??A?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAAEAUTransition@cctz@time_internal@absl@@_K@Z
@@ -1443,6 +1442,7 @@
     ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z
     ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPEAV123@PEAV123@0_K1@Z@QEBA?A?<auto>@@I@Z
     ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QEAAPEAUPayload@status_internal@3@PEBU453@@Z@QEBA?A?<auto>@@XZ
+    ??R?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@absl@@QEBAXPEAUCordRep@cord_internal@1@_K1@Z
     ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QEBAXV?$Span@I@1@@Z
     ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QEBAXVstring_view@1@@Z
     ??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -1631,6 +1631,7 @@
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PEBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PEAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PEAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QEAAXPEAV?$allocator@USubRange@absl@@@__1@std@@PEAUSubRange@3@@Z
+    ?Consume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?ConsumePrefix@absl@@YA_NPEAVstring_view@1@V21@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPEBDPEBD0PEAUUnboundConversion@12@PEAH@Z
     ?Contains@str_format_internal@absl@@YA_NW4FormatConversionCharSet@2@D@Z
@@ -2227,6 +2228,7 @@
     ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPEAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@_K@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?RoundUp@cord_internal@absl@@YA_K_K0@Z
     ?RoundUpForTag@cord_internal@absl@@YA_K_K@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def
index decfb738b..c2a5a18 100644
--- a/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -274,6 +274,7 @@
     ?CompareSlowPath@Cord@absl@@AEBAHAEBV12@_K1@Z
     ?CompareSlowPath@Cord@absl@@AEBAHVstring_view@2@_K1@Z
     ?ConcatNodes@CordForest@absl@@QEAAPEAUCordRep@cord_internal@2@XZ
+    ?Consume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPEBDPEBD0PEAUUnboundConversion@12@PEAH@Z
     ?ConvertDateTime@absl@@YA?AUTimeConversion@1@_JHHHHHVTimeZone@1@@Z
     ?ConvertDeletedToEmptyAndFullToDeleted@container_internal@absl@@YAXPEAC_K@Z
@@ -357,7 +358,6 @@
     ?Find@ByChar@absl@@QEBA?AVstring_view@2@V32@_K@Z
     ?Find@ByLength@absl@@QEBA?AVstring_view@2@V32@_K@Z
     ?Find@ByString@absl@@QEBA?AVstring_view@2@V32@_K@Z
-    ?FindFlatStartPiece@InlineRep@Cord@absl@@QEBA?AVstring_view@3@XZ
     ?FindPath@GraphCycles@synchronization_internal@absl@@QEBAHUGraphId@23@0HQEAU423@@Z
     ?FindSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z
     ?FindTailSlow@CordRepRing@cord_internal@absl@@AEBA?AUPosition@123@I_K@Z
@@ -617,6 +617,7 @@
     ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
     ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def
index 71e23e2b..4ee6864 100644
--- a/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -287,6 +287,7 @@
     ?CompareSlowPath@Cord@absl@@AEBAHAEBV12@_K1@Z
     ?CompareSlowPath@Cord@absl@@AEBAHVstring_view@2@_K1@Z
     ?ConcatNodes@CordForest@absl@@QEAAPEAUCordRep@cord_internal@2@XZ
+    ?Consume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPEBDPEBD0PEAUUnboundConversion@12@PEAH@Z
     ?ConvertDateTime@absl@@YA?AUTimeConversion@1@_JHHHHHVTimeZone@1@@Z
     ?ConvertDeletedToEmptyAndFullToDeleted@container_internal@absl@@YAXPEAC_K@Z
@@ -630,6 +631,7 @@
     ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPEAUCordRep@12@V?$FunctionRef@$$A6AXPEAUCordRep@cord_internal@absl@@_K1@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QEBA_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPEBD_K@Z
     ?SampleSlow@container_internal@absl@@YAPEAUHashtablezInfo@12@PEA_J@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index 22bb061..097dfd91 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -55,7 +55,6 @@
     ??$?0AAPAPBVImpl@time_zone@cctz@time_internal@absl@@X@?$__compressed_pair_elem@PAPBVImpl@time_zone@cctz@time_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
     ??$?0AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@12@@?$__compressed_pair@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@23@@__1@std@@QAE@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@12@@Z
     ??$?0AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@X@?$__compressed_pair_elem@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@$0A@$0A@@__1@std@@QAE@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@12@@Z
-    ??$?0AAPAUCordRep@cord_internal@absl@@AAPAU012@$0A@@?$pair@PAUCordRep@cord_internal@absl@@PAU123@@__1@std@@QAE@AAPAUCordRep@cord_internal@absl@@0@Z
     ??$?0AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@?$__compressed_pair@PAUThreadIdentity@base_internal@absl@@P6AXPAX@Z@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
     ??$?0AAPAUThreadIdentity@base_internal@absl@@X@?$__compressed_pair_elem@PAUThreadIdentity@base_internal@absl@@$0A@$0A@@__1@std@@QAE@AAPAUThreadIdentity@base_internal@absl@@@Z
     ??$?0AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U__default_init_tag@__1@std@@@?$__compressed_pair@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@QAE@AAPAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$QAU__default_init_tag@12@@Z
@@ -639,7 +638,6 @@
     ??$forward@AAPAPBUCordRep@cord_internal@absl@@@__1@std@@YAAAPAPBUCordRep@cord_internal@absl@@AAPAPBU234@@Z
     ??$forward@AAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@YAAAPAPBVImpl@time_zone@cctz@time_internal@absl@@AAPAPBV23456@@Z
     ??$forward@AAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@YAAAPAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@01@AAPAU201@@Z
-    ??$forward@AAPAUCordRep@cord_internal@absl@@@__1@std@@YAAAPAUCordRep@cord_internal@absl@@AAPAU234@@Z
     ??$forward@AAPAUPayload@status_internal@absl@@@__1@std@@YAAAPAUPayload@status_internal@absl@@AAPAU234@@Z
     ??$forward@AAPAUSubRange@absl@@@__1@std@@YAAAPAUSubRange@absl@@AAPAU23@@Z
     ??$forward@AAPAUThreadIdentity@base_internal@absl@@@__1@std@@YAAAPAUThreadIdentity@base_internal@absl@@AAPAU234@@Z
@@ -740,7 +738,6 @@
     ??$get@Vstring_view@absl@@V12@@?$__get_pair@$0A@@__1@std@@SAABVstring_view@absl@@ABU?$pair@Vstring_view@absl@@V12@@12@@Z
     ??$invoke@A6AXXZ$$V@base_internal@absl@@YAXA6AXXZ@Z
     ??$lower_bound@PBUTransition@cctz@time_internal@absl@@U1234@UByUnixTime@1234@@__1@std@@YAPBUTransition@cctz@time_internal@absl@@PBU2345@0ABU2345@UByUnixTime@2345@@Z
-    ??$make_pair@AAPAUCordRep@cord_internal@absl@@AAPAU123@@__1@std@@YA?AU?$pair@PAUCordRep@cord_internal@absl@@PAU123@@01@AAPAUCordRep@cord_internal@absl@@0@Z
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@$$V@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@XZ
     ??$make_unique@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@AAV12@@__1@std@@YA?AV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@Z
     ??$max_size@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@X@?$allocator_traits@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@SAIABV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
@@ -777,6 +774,7 @@
     ??$move@AAUTransition@cctz@time_internal@absl@@@__1@std@@YA$$QAUTransition@cctz@time_internal@absl@@AAU2345@@Z
     ??$move@AAUTransitionType@cctz@time_internal@absl@@@__1@std@@YA$$QAUTransitionType@cctz@time_internal@absl@@AAU2345@@Z
     ??$move@AAUViableSubstitution@strings_internal@absl@@@__1@std@@YA$$QAUViableSubstitution@strings_internal@absl@@AAU234@@Z
+    ??$move@AAV?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@absl@@@__1@std@@YA$$QAV?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@absl@@AAV23@@Z
     ??$move@AAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@01@AAV201@@Z
     ??$move@AAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@__1@std@@YA$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@01@AAV201@@Z
     ??$move@AAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@__1@std@@@__1@std@@YA$$QAV?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@@__1@std@@@01@AAV201@@Z
@@ -1300,6 +1298,7 @@
     ??A?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QBEABUPayload@status_internal@1@I@Z
     ??A?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QBEABVFormatArgImpl@str_format_internal@1@I@Z
     ??A?$Span@I@absl@@QBEAAII@Z
+    ??A?$array@PAUCordRep@cord_internal@absl@@$01@__1@std@@QAEAAPAUCordRep@cord_internal@absl@@I@Z
     ??A?$unique_ptr@$$BY0A@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@__1@std@@@__1@std@@@23@@__1@std@@QBEAAPAU?$__hash_node_base@PAU?$__hash_node@U?$__hash_value_type@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@PAX@__1@std@@@12@I@Z
     ??A?$unordered_map@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@U?$hash@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@U?$equal_to@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@@23@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@23@@__1@std@@QAEAAPBVImpl@time_zone@cctz@time_internal@absl@@ABV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@12@@Z
     ??A?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEAAUTransition@cctz@time_internal@absl@@I@Z
@@ -1438,6 +1437,7 @@
     ??R<lambda_2>@?0???$AddRing@$00@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z
     ??R<lambda_2>@?0???$AddRing@$0A@@CordRepRing@cord_internal@absl@@CAPAV123@PAV123@0II@Z@QBE?A?<auto>@@I@Z
     ??R<lambda_2>@?0??erase@?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__1@std@@@absl@@QAEPAUPayload@status_internal@3@PBU453@@Z@QBE?A?<auto>@@XZ
+    ??R?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@absl@@QBEXPAUCordRep@cord_internal@1@II@Z
     ??R?$FunctionRef@$$A6AXV?$Span@I@absl@@@Z@absl@@QBEXV?$Span@I@1@@Z
     ??R?$FunctionRef@$$A6AXVstring_view@absl@@@Z@absl@@QBEXVstring_view@1@@Z
     ??R?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__1@std@@@__1@std@@QAEXPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
@@ -1625,6 +1625,7 @@
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@PBUPayload@status_internal@absl@@@inlined_vector_internal@absl@@QAEXPAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__1@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@QAEXPAV?$allocator@UPayload@status_internal@absl@@@__1@std@@PAUPayload@status_internal@3@@Z
     ?ConstructNext@?$IteratorValueAdapter@V?$allocator@USubRange@absl@@@__1@std@@V?$move_iterator@PAUSubRange@absl@@@23@@inlined_vector_internal@absl@@QAEXPAV?$allocator@USubRange@absl@@@__1@std@@PAUSubRange@3@@Z
+    ?Consume@cord_internal@absl@@YAXPAUCordRep@12@V?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@2@@Z
     ?ConsumePrefix@absl@@YA_NPAVstring_view@1@V21@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPBDPBD0PAUUnboundConversion@12@PAH@Z
     ?Contains@str_format_internal@absl@@YA_NW4FormatConversionCharSet@2@D@Z
@@ -2221,6 +2222,7 @@
     ?Resize@?$ResizeUninitializedTraits@V?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@X@strings_internal@absl@@SAXPAV?$basic_string@DU?$char_traits@D@__1@std@@V?$allocator@D@23@@__1@std@@I@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPAUCordRep@12@V?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@2@@Z
     ?RoundUp@cord_internal@absl@@YAIII@Z
     ?RoundUpForTag@cord_internal@absl@@YAII@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QBE_NXZ
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 9a393c3..9d3a3d9 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -270,6 +270,7 @@
     ?CompareSlowPath@Cord@absl@@ABEHABV12@II@Z
     ?CompareSlowPath@Cord@absl@@ABEHVstring_view@2@II@Z
     ?ConcatNodes@CordForest@absl@@QAEPAUCordRep@cord_internal@2@XZ
+    ?Consume@cord_internal@absl@@YAXPAUCordRep@12@V?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@2@@Z
     ?ConsumeUnboundConversion@str_format_internal@absl@@YAPBDPBD0PAUUnboundConversion@12@PAH@Z
     ?ConvertDateTime@absl@@YA?AUTimeConversion@1@_JHHHHHVTimeZone@1@@Z
     ?ConvertDeletedToEmptyAndFullToDeleted@container_internal@absl@@YAXPACI@Z
@@ -353,7 +354,6 @@
     ?Find@ByChar@absl@@QBE?AVstring_view@2@V32@I@Z
     ?Find@ByLength@absl@@QBE?AVstring_view@2@V32@I@Z
     ?Find@ByString@absl@@QBE?AVstring_view@2@V32@I@Z
-    ?FindFlatStartPiece@InlineRep@Cord@absl@@QBE?AVstring_view@3@XZ
     ?FindPath@GraphCycles@synchronization_internal@absl@@QBEHUGraphId@23@0HQAU423@@Z
     ?FindSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z
     ?FindTailSlow@CordRepRing@cord_internal@absl@@ABE?AUPosition@123@II@Z
@@ -613,6 +613,7 @@
     ?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AAE_NABV?$duration@_JV?$ratio@$00$00@__1@std@@@chrono@__1@std@@@Z
     ?ResourceExhaustedError@absl@@YA?AVStatus@1@Vstring_view@1@@Z
     ?Rethrow@variant_internal@absl@@YAXXZ
+    ?ReverseConsume@cord_internal@absl@@YAXPAUCordRep@12@V?$FunctionRef@$$A6AXPAUCordRep@cord_internal@absl@@II@Z@2@@Z
     ?SafeToDelete@CordzHandle@cord_internal@absl@@QBE_NXZ
     ?SafeWriteToStderr@raw_logging_internal@absl@@YAXPBDI@Z
     ?SampleSlow@container_internal@absl@@YAPAUHashtablezInfo@12@PA_J@Z
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index fb5d6de..65b8e71 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -1026,7 +1026,12 @@
 // When enabled, allow dropping alpha on media streams for rendering sinks if
 // other sinks connected do not use alpha.
 const base::Feature kAllowDropAlphaForMediaStream{
-    "AllowDropAlphaForMediaStream", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AllowDropAlphaForMediaStream", base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Enables partitioning of third party storage (IndexedDB, CacheStorage, etc.)
+// by the top level site to reduce fingerprinting.
+const base::Feature kThirdPartyStoragePartitioning{
+    "ThirdPartyStoragePartitioning", base::FEATURE_DISABLED_BY_DEFAULT};
 
 }  // namespace features
 }  // namespace blink
diff --git a/third_party/blink/common/storage_key/storage_key.cc b/third_party/blink/common/storage_key/storage_key.cc
index 116f509..83148ca 100644
--- a/third_party/blink/common/storage_key/storage_key.cc
+++ b/third_party/blink/common/storage_key/storage_key.cc
@@ -7,8 +7,10 @@
 #include <cctype>
 #include <ostream>
 
+#include "base/feature_list.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/strcat.h"
+#include "third_party/blink/public/common/features.h"
 #include "url/gurl.h"
 
 namespace blink {
@@ -26,6 +28,11 @@
   return result.value_or(StorageKey());
 }
 
+// static
+bool StorageKey::IsThirdPartyStoragePartitioningEnabled() {
+  return base::FeatureList::IsEnabled(features::kThirdPartyStoragePartitioning);
+}
+
 std::string StorageKey::Serialize() const {
   DCHECK(!origin_.opaque());
   return origin_.GetURL().spec();
diff --git a/third_party/blink/common/storage_key/storage_key_unittest.cc b/third_party/blink/common/storage_key/storage_key_unittest.cc
index 6d18961..83b9968 100644
--- a/third_party/blink/common/storage_key/storage_key_unittest.cc
+++ b/third_party/blink/common/storage_key/storage_key_unittest.cc
@@ -4,8 +4,11 @@
 
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 
+#include "base/feature_list.h"
+#include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/features.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -188,4 +191,12 @@
   }
 }
 
+TEST(StorageKeyTest, IsThirdPartyStoragePartitioningEnabled) {
+  EXPECT_FALSE(StorageKey::IsThirdPartyStoragePartitioningEnabled());
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      features::kThirdPartyStoragePartitioning);
+  EXPECT_TRUE(StorageKey::IsThirdPartyStoragePartitioningEnabled());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index c6b92861..a264ef99 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -100,6 +100,7 @@
   out->hide_scrollbars = data.hide_scrollbars();
   out->accelerated_2d_canvas_enabled = data.accelerated_2d_canvas_enabled();
   out->new_canvas_2d_api_enabled = data.new_canvas_2d_api_enabled();
+  out->canvas_2d_layers_enabled = data.canvas_2d_layers_enabled();
   out->antialiased_2d_canvas_disabled = data.antialiased_2d_canvas_disabled();
   out->antialiased_clips_2d_canvas_enabled =
       data.antialiased_clips_2d_canvas_enabled();
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index ad0b0e96..73c6b7ee 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -439,6 +439,8 @@
 // other sinks connected do not use alpha.
 BLINK_COMMON_EXPORT extern const base::Feature kAllowDropAlphaForMediaStream;
 
+BLINK_COMMON_EXPORT extern const base::Feature kThirdPartyStoragePartitioning;
+
 }  // namespace features
 }  // namespace blink
 
diff --git a/third_party/blink/public/common/storage_key/storage_key.h b/third_party/blink/public/common/storage_key/storage_key.h
index 53172f3..0ba7b04 100644
--- a/third_party/blink/public/common/storage_key/storage_key.h
+++ b/third_party/blink/public/common/storage_key/storage_key.h
@@ -49,6 +49,9 @@
   // For use in tests only.
   static StorageKey CreateFromStringForTesting(const std::string& origin);
 
+  // Returns true if ThirdPartyStoragePartitioning feature flag is enabled.
+  static bool IsThirdPartyStoragePartitioningEnabled();
+
   // Serializes the `StorageKey` into a string.
   // This function will return the spec url of the underlying Origin. Do not
   // call if `this` is opaque.
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
index 0313bac2..9dbbb581 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -233,6 +233,11 @@
     return r.new_canvas_2d_api_enabled;
   }
 
+  static bool canvas_2d_layers_enabled(
+      const blink::web_pref::WebPreferences& r) {
+    return r.canvas_2d_layers_enabled;
+  }
+
   static bool antialiased_2d_canvas_disabled(
       const blink::web_pref::WebPreferences& r) {
     return r.antialiased_2d_canvas_disabled;
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index dc12af1..c3f3b8b 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3261,6 +3261,8 @@
   kDifferentPerspectiveCBOrParent = 3946,
   kWebkitImageSet = 3947,
   kRTCPeerConnectionWithBlockingCsp = 3948,
+  kSanitizerAPISanitizeFor = 3949,
+  kSanitizerAPIElementSetSanitized = 3950,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
index 121ea7b..eaecb8c 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -154,6 +154,7 @@
   bool hide_scrollbars;
   bool accelerated_2d_canvas_enabled;
   bool new_canvas_2d_api_enabled;
+  bool canvas_2d_layers_enabled;
   bool antialiased_2d_canvas_disabled;
   bool antialiased_clips_2d_canvas_enabled;
   bool accelerated_filters_enabled;
diff --git a/third_party/blink/public/public_features.gni b/third_party/blink/public/public_features.gni
index bd2d650..94d2e5e 100644
--- a/third_party/blink/public/public_features.gni
+++ b/third_party/blink/public/public_features.gni
@@ -36,3 +36,8 @@
 
 # Use Minikin hyphenation engine.
 use_minikin_hyphenation = !is_mac
+
+# Forward the request for naming to cppgc.
+if (enable_additional_blink_object_names) {
+  cppgc_enable_object_names = true
+}
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn
index 46443a6..cd7db8de 100644
--- a/third_party/blink/renderer/bindings/BUILD.gn
+++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -12,58 +12,9 @@
 import("//third_party/blink/renderer/bindings/idl_in_extensions_chromeos.gni")
 import("//third_party/blink/renderer/bindings/idl_in_modules.gni")
 import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
-import("//third_party/blink/renderer/build/scripts/scripts.gni")
-import("//third_party/blink/renderer/core/core_idl_files.gni")
-import("//third_party/blink/renderer/modules/modules_idl_files.gni")
 
 visibility = [ "//third_party/blink/renderer/*" ]
 
-action("interfaces_info") {
-  script = "$bindings_scripts_dir/compute_interfaces_info_overall.py"
-
-  inputs = [
-    "$bindings_core_output_dir/interfaces_info_core.pickle",
-    "$bindings_modules_output_dir/interfaces_info_modules.pickle",
-  ]
-  outputs = [ "$bindings_output_dir/interfaces_info.pickle" ]
-
-  args = [
-    "--",
-    rebase_path("$bindings_core_output_dir/interfaces_info_core.pickle",
-                root_build_dir),
-    rebase_path("$bindings_modules_output_dir/interfaces_info_modules.pickle",
-                root_build_dir),
-    rebase_path("$bindings_output_dir/interfaces_info.pickle", root_build_dir),
-  ]
-
-  public_deps = [
-    "//third_party/blink/renderer/bindings/core:interfaces_info_core",
-    "//third_party/blink/renderer/bindings/modules:interfaces_info_modules",
-  ]
-}
-
-if (use_blink_v8_binding_new_idl_interface) {
-  group("global_constructors_idls") {
-  }
-} else {
-  generate_global_constructors("global_constructors_idls") {
-    sources =
-        core_interface_idl_files_core_only +
-        core_interface_idl_files_modules_dependent +
-        core_buffer_source_type_idl_files + core_callback_interface_idl_files
-    global_objects_file =
-        "$bindings_modules_output_dir/global_objects_modules.pickle"
-    interfaces = modules_core_global_constructors_original_interfaces
-    basenames = modules_core_global_constructors_original_interface_basenames
-    component = "core"
-    output_dir = blink_modules_output_dir
-    deps = [
-      "//third_party/blink/renderer/bindings/modules:modules_global_constructors_idls",
-      "//third_party/blink/renderer/bindings/modules:modules_global_objects",
-    ]
-  }
-}
-
 template("collect_idl_files") {
   action_with_pydeps(target_name) {
     script = "${bindings_scripts_dir}/collect_idl_files.py"
diff --git a/third_party/blink/renderer/bindings/core/BUILD.gn b/third_party/blink/renderer/bindings/core/BUILD.gn
deleted file mode 100644
index 5d32b25..0000000
--- a/third_party/blink/renderer/bindings/core/BUILD.gn
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
-import("//third_party/blink/renderer/core/core_idl_files.gni")
-
-visibility = [ "//third_party/blink/*" ]
-
-compute_interfaces_info("interfaces_info_core") {
-  sources =
-      core_static_interface_idl_files + core_static_dependency_idl_files +
-      core_generated_interface_idl_files + core_generated_dependency_idl_files
-  interfaces_info_file = "$bindings_core_output_dir/interfaces_info_core.pickle"
-  component_info_file = "$bindings_core_output_dir/component_info_core.pickle"
-  deps = [
-    "//third_party/blink/renderer/bindings/core:core_global_constructors_idls",
-    "//third_party/blink/renderer/core:generated_testing_idls_internal_runtime_flags",
-    "//third_party/blink/renderer/core:generated_testing_idls_settings",
-  ]
-}
-
-compute_global_objects("core_global_objects") {
-  sources =
-      core_interface_idl_files_core_only +
-      core_interface_idl_files_modules_dependent +
-      core_buffer_source_type_idl_files + core_callback_interface_idl_files
-  sources_generated = []
-  output_file = "$bindings_core_output_dir/global_objects_core.pickle"
-  deps = []
-}
-
-if (use_blink_v8_binding_new_idl_interface) {
-  group("core_global_constructors_idls") {
-  }
-} else {
-  generate_global_constructors("core_global_constructors_idls") {
-    sources =
-        core_interface_idl_files_core_only +
-        core_interface_idl_files_modules_dependent +
-        core_buffer_source_type_idl_files + core_callback_interface_idl_files
-    global_objects_file = "$bindings_core_output_dir/global_objects_core.pickle"
-    interfaces = core_global_constructors_original_interfaces
-    basenames = core_global_constructors_original_interface_basenames
-    component = "core"
-    output_dir = blink_core_output_dir
-    deps = [ ":core_global_objects" ]
-  }
-}
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 1dba6a57..0679ac6 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -1537,8 +1537,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_cssvariablereferencevalue_string.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_element.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_document_element.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_documenttimeline_scrolltimeline.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index e8db4683..d5e25cda 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -1591,6 +1591,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system_sync.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dynamics_compressor_node.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dynamics_compressor_node.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_element.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_element.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index c0e5c7bf..968214da 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -629,6 +629,7 @@
           "//third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.idl",
           "//third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.idl",
           "//third_party/blink/renderer/modules/remoteplayback/remote_playback.idl",
+          "//third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl",
           "//third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl",
           "//third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl",
           "//third_party/blink/renderer/modules/scheduler/scheduler.idl",
diff --git a/third_party/blink/renderer/bindings/modules/BUILD.gn b/third_party/blink/renderer/bindings/modules/BUILD.gn
deleted file mode 100644
index 101e3ef..0000000
--- a/third_party/blink/renderer/bindings/modules/BUILD.gn
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
-
-compute_interfaces_info("interfaces_info_modules") {
-  sources = modules_static_interface_idl_files + modules_definition_idl_files +
-            modules_static_dependency_idl_files +
-            modules_generated_dependency_idl_files
-
-  interfaces_info_file =
-      "$bindings_modules_output_dir/interfaces_info_modules.pickle"
-  component_info_file =
-      "$bindings_modules_output_dir/component_info_modules.pickle"
-  deps = [
-    ":modules_global_constructors_idls",
-    "//third_party/blink/renderer/bindings:global_constructors_idls",
-  ]
-}
-
-compute_global_objects("modules_global_objects") {
-  sources = modules_idl_files
-  sources_generated = [ "$bindings_core_output_dir/global_objects_core.pickle" ]
-  output_file = "$bindings_modules_output_dir/global_objects_modules.pickle"
-  deps = [ "//third_party/blink/renderer/bindings/core:core_global_objects" ]
-}
-
-if (use_blink_v8_binding_new_idl_interface) {
-  group("modules_global_constructors_idls") {
-  }
-} else {
-  generate_global_constructors("modules_global_constructors_idls") {
-    sources = modules_idl_files
-    global_objects_file =
-        "$bindings_modules_output_dir/global_objects_modules.pickle"
-    interfaces = modules_global_constructors_original_interfaces
-    basenames = modules_global_constructors_original_interface_basenames
-    component = "modules"
-    output_dir = blink_modules_output_dir
-    deps = [ ":modules_global_objects" ]
-  }
-}
diff --git a/third_party/blink/renderer/bindings/modules/v8/BUILD.gn b/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
index 30ff88b..49ceb53 100644
--- a/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
+++ b/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
@@ -2,11 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/config/python.gni")
 import("//third_party/blink/renderer/bindings/generated_in_modules.gni")
-import("//third_party/blink/renderer/bindings/modules/v8/v8.gni")
 import("//third_party/blink/renderer/modules/modules.gni")
-import("//third_party/blink/renderer/modules/modules_idl_files.gni")
 
 visibility = [ "//third_party/blink/renderer/*" ]
 
@@ -24,7 +21,6 @@
       generated_typedef_sources_in_modules + generated_union_sources_in_modules
 
   deps = [
-    ":generate_mojo_bindings",
     ":generated",
     "//third_party/blink/renderer/platform",
     "//v8",
@@ -63,26 +59,3 @@
   public_deps =
       [ "//third_party/blink/renderer/bindings:generate_bindings_all" ]
 }
-
-# Note that this intentionally depends on the generator target of the mojom
-# target instead of the mojom target itself directly. This is to ensure that the
-# dependencies are header-only and don't link against any bindings code.
-group("generate_mojo_bindings") {
-  visibility = []  # Allow re-assignment of list.
-  visibility = [ ":*" ]
-
-  deps = [
-    "//device/gamepad/public/mojom:mojom_blink_headers",
-    "//device/vr/public/mojom:vr_service_blink_headers",
-    "//media/capture/mojom:image_capture_blink_headers",
-    "//media/midi:mojo_blink_headers",
-    "//services/device/public/mojom:generic_sensor_headers",
-    "//services/device/public/mojom:mojom_blink_headers",
-    "//services/device/public/mojom:usb_blink_headers",
-    "//services/shape_detection/public/mojom:mojom_blink_headers",
-
-    # IndexedDB Mojom Blink headers are provided by the mojom_modules
-    # target.
-    "//third_party/blink/public/mojom:mojom_modules_blink_headers",
-  ]
-}
diff --git a/third_party/blink/renderer/bindings/scripts/BUILD.gn b/third_party/blink/renderer/bindings/scripts/BUILD.gn
deleted file mode 100644
index ced0779..0000000
--- a/third_party/blink/renderer/bindings/scripts/BUILD.gn
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/blink/renderer/bindings/bindings.gni")
-import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
-import("//third_party/blink/renderer/bindings/templates/templates.gni")
-
-visibility = [ "//third_party/blink/*" ]
-
-# This separate pre-caching step is required to use lex/parse table
-# caching in PLY, since PLY itself does not check if the cache is
-# valid, and thus may end up using a stale cache if this step hasn't
-# been run to update it.
-#
-# This action's dependencies *is* the cache validation.
-action("cached_lex_yacc_tables") {
-  script = "blink_idl_parser.py"
-
-  inputs = idl_lexer_parser_files
-  outputs = [ "$bindings_scripts_output_dir/parsetab.pickle" ]
-
-  args = [ rebase_path(bindings_scripts_output_dir, root_build_dir) ]
-}
-
-# A separate pre-caching step is *required* to use bytecode caching in
-# Jinja (which improves speed significantly), as the bytecode cache is
-# not concurrency-safe on write; details in code_generator_v8.py.
-action("cached_jinja_templates") {
-  script = "code_generator.py"
-
-  inputs = jinja_module_files + [ "code_generator.py" ] +
-           code_generator_template_files
-
-  # Dummy file to track dependency.
-  stamp_file = "$bindings_scripts_output_dir/cached_jinja_templates.stamp"
-  outputs = [ stamp_file ]
-
-  args = [
-    rebase_path(bindings_scripts_output_dir, root_build_dir),
-    rebase_path(stamp_file, root_build_dir),
-  ]
-}
diff --git a/third_party/blink/renderer/bindings/scripts/scripts.gni b/third_party/blink/renderer/bindings/scripts/scripts.gni
index eb796d6..e636739 100644
--- a/third_party/blink/renderer/bindings/scripts/scripts.gni
+++ b/third_party/blink/renderer/bindings/scripts/scripts.gni
@@ -4,108 +4,10 @@
 
 import("//build/config/python.gni")
 import("//third_party/blink/renderer/build/scripts/scripts.gni")
-import("//third_party/blink/renderer/core/core_idl_files.gni")
-import("//third_party/blink/renderer/modules/modules_idl_files.gni")
 
 bindings_scripts_dir = get_path_info(".", "abspath")
 bindings_scripts_output_dir = get_path_info(".", "gen_dir")
 
-jinja_module_files = [
-  "//third_party/jinja2/__init__.py",
-  "//third_party/markupsafe/__init__.py",  # jinja2 dep
-]
-
-idl_lexer_parser_files = get_path_info([
-                                         # PLY (Python Lex-Yacc)
-                                         "//third_party/ply/lex.py",
-                                         "//third_party/ply/yacc.py",
-
-                                         # Web IDL lexer/parser (base parser)
-                                         "//tools/idl_parser/idl_lexer.py",
-                                         "//tools/idl_parser/idl_node.py",
-                                         "//tools/idl_parser/idl_parser.py",
-
-                                         # Blink IDL lexer/parser/constructor
-                                         "blink_idl_lexer.py",
-                                         "blink_idl_parser.py",
-                                       ],
-                                       "abspath")
-idl_compiler_files = get_path_info(
-        [
-          "idl_compiler.py",
-
-          # Blink IDL front end (ex-lexer/parser)
-          "idl_definitions.py",
-          "idl_reader.py",
-          "idl_types.py",
-          "idl_validator.py",
-          "interface_dependency_resolver.py",
-
-          # V8 code generator
-          "code_generator.py",
-          "code_generator_v8.py",
-          "v8_attributes.py",
-          "v8_callback_function.py",
-          "v8_callback_interface.py",
-          "v8_dictionary.py",
-          "v8_globals.py",
-          "v8_interface.py",
-          "v8_methods.py",
-          "v8_types.py",
-          "v8_union.py",
-          "v8_utilities.py",
-          "//third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py",
-        ],
-        "abspath")
-
-# Calls the compute_interfaces_info_individual script.
-#
-# Parameters:
-#   sources = list of IDL files to pass as inputs
-#   interfaces_info_file = output pickle file for interfaces info.
-#   component_info_file = output pickle file for component wide info.
-#   deps = dependencies
-template("compute_interfaces_info") {
-  action(target_name) {
-    script = "$bindings_scripts_dir/compute_interfaces_info_individual.py"
-    if (defined(invoker.visibility)) {
-      visibility = invoker.visibility
-    }
-
-    build_scripts_output_dir =
-        "$root_gen_dir/third_party/blink/renderer/build/scripts"
-    runtime_enabled_features_file =
-        "$build_scripts_output_dir/runtime_enabled_features.pickle"
-    inputs = [
-               "$bindings_scripts_dir/utilities.py",
-               runtime_enabled_features_file,
-             ] + idl_compiler_files + invoker.sources
-    outputs = [
-      invoker.interfaces_info_file,
-      invoker.component_info_file,
-    ]
-
-    response_file_contents = rebase_path(invoker.sources, root_build_dir)
-    args = [
-      "--cache-directory",
-      rebase_path(bindings_scripts_output_dir, root_build_dir),
-      "--idl-files-list",
-      "{{response_file_name}}",
-      "--interfaces-info-file",
-      rebase_path(invoker.interfaces_info_file, root_build_dir),
-      "--component-info-file",
-      rebase_path(invoker.component_info_file, root_build_dir),
-      "--runtime-enabled-features-file",
-      rebase_path(runtime_enabled_features_file, root_build_dir),
-    ]
-
-    deps = [
-             "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables",
-             "//third_party/blink/renderer/platform:runtime_enabled_features",
-           ] + invoker.deps
-  }
-}
-
 # Calls generate_event_interfaces
 #
 # Parameters:
@@ -144,335 +46,3 @@
     }
   }
 }
-
-# Runs the idl_compiler script over a list of sources.
-#
-# Parameters:
-#   sources = list of IDL files to compile
-#   output_dir = string containing the directory to put the output files.
-#   output_name_suffix = a suffix after the basename of the output file names.
-#   target_component = component to generate code for.
-template("idl_compiler") {
-  output_dir = invoker.output_dir
-  output_name_suffix = invoker.output_name_suffix
-
-  # TODO(brettw): we used to add a "-S" before the script name to skip
-  # "import site" to speed up startup. Figure out if we need this and do
-  # something similar (not really expressible in GN now).
-  _script = "//third_party/blink/renderer/bindings/scripts/idl_compiler.py"
-  _inputs =
-      idl_lexer_parser_files + idl_compiler_files  # to be explicit (covered by
-                                                   # parsetab)
-  _inputs += [
-    "$bindings_scripts_output_dir/parsetab.pickle",
-    "$bindings_scripts_output_dir/cached_jinja_templates.stamp",
-    "$bindings_dir/IDLExtendedAttributes.txt",
-
-    # If the dependency structure or public interface info (e.g.,
-    # [ImplementedAs]) changes, we rebuild all files, since we're not
-    # computing dependencies file-by-file in the build.
-    # This data is generally stable.
-    "$bindings_output_dir/interfaces_info.pickle",
-  ]
-
-  # Further, if any dependency (partial interface or implemented
-  # interface) changes, rebuild everything, since every IDL potentially
-  # depends on them, because we're not computing dependencies
-  # file-by-file.
-  # FIXME: This is too conservative, and causes excess rebuilds:
-  # compute this file-by-file.  http://crbug.com/341748
-  # This should theoretically just be the IDL files passed in.
-  _inputs += core_all_dependency_idl_files + modules_all_dependency_idl_files
-
-  _public_deps = [
-    "//third_party/blink/renderer/bindings:global_constructors_idls",
-    "//third_party/blink/renderer/bindings:interfaces_info",
-    "//third_party/blink/renderer/bindings/core:core_global_constructors_idls",
-    "//third_party/blink/renderer/bindings/modules:modules_global_constructors_idls",
-    "//third_party/blink/renderer/bindings/scripts:cached_jinja_templates",
-    "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables",
-    "//third_party/blink/renderer/core:generated_testing_idls",
-  ]
-
-  # Spawning a python process per IDL file is slow. Use a single action
-  # instead (crbug.com/821256).
-  action(target_name) {
-    script = _script
-    inputs = _inputs
-    public_deps = _public_deps
-
-    sources = invoker.sources
-    outputs = []
-    foreach(_source, sources) {
-      _name_part = get_path_info(_source, "name")
-      outputs += [
-        "$output_dir/v8_${_name_part}${output_name_suffix}.cc",
-        "$output_dir/v8_${_name_part}${output_name_suffix}.h",
-      ]
-    }
-
-    idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
-    write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir))
-    inputs += [ idl_files_list ]
-
-    args = [
-      "--cache-dir",
-      rebase_path(bindings_scripts_output_dir, root_build_dir),
-      "--output-dir",
-      rebase_path(output_dir, root_build_dir),
-      "--info-dir",
-      rebase_path("$bindings_output_dir", root_build_dir),
-      "--target-component",
-      invoker.target_component,
-      "--read-idl-list-from-file",
-      rebase_path(idl_files_list, root_build_dir),
-    ]
-  }
-}
-
-# Runs idl_compiler.py to generate IDL dictionary impl files, unions and
-# callback functions.
-#
-# Parameters:
-#   dict_idls = a list of dictionary IDL files to process. the callback and
-#               union IDL file names are already known and do not need to be
-#               specified.
-#   non_dict_outputs = a list of files generated from callback functions and
-#                      unions. the list of files generated from |dict_idls| is
-#                      added automatically and does not need to be specified.
-#   non_dict_output_dir = the directory to put the non-dict output files.
-#   target_component = component to generate code for
-template("idl_impl") {
-  dictionary_impl_output_dir = "$root_gen_dir/third_party/blink/renderer/"
-
-  action(target_name) {
-    script = "//third_party/blink/renderer/bindings/scripts/idl_compiler.py"
-    idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
-    write_file(idl_files_list, rebase_path(invoker.dict_idls, root_build_dir))
-
-    inputs =
-        idl_lexer_parser_files + idl_compiler_files  # to be explicit (covered
-                                                     # by parsetab)
-    inputs += [
-      "$bindings_scripts_output_dir/parsetab.pickle",
-      "$bindings_scripts_output_dir/cached_jinja_templates.stamp",
-      "$bindings_dir/IDLExtendedAttributes.txt",
-    ]
-    inputs += [ idl_files_list ] + invoker.dict_idls
-    outputs = invoker.non_dict_outputs
-
-    # Derive the names of the generated dictionary impl files. Contrary to
-    # generated interfaces, callbacks and unions, these files go to
-    # $root_gen_dir/third_party/blink/renderer/{core,modules}/<module name>/<IDLName>.{cpp,h}.
-    foreach(dict_idl, invoker.dict_idls) {
-      rel_path = rebase_path(dict_idl, "//third_party/blink/renderer")
-      impl_dir = get_path_info(rel_path, "dir")
-      idl_name = get_path_info(rel_path, "name")
-      outputs += [
-        "${dictionary_impl_output_dir}$impl_dir/$idl_name.cc",
-        "${dictionary_impl_output_dir}$impl_dir/$idl_name.h",
-      ]
-    }
-
-    args = [
-      "--cache-dir",
-      rebase_path(bindings_scripts_output_dir, root_build_dir),
-      "--output-dir",
-      rebase_path(invoker.non_dict_output_dir, root_build_dir),
-      "--impl-output-dir",
-      rebase_path(dictionary_impl_output_dir, root_build_dir),
-      "--info-dir",
-      rebase_path("$bindings_output_dir", root_build_dir),
-      "--target-component",
-      invoker.target_component,
-      "--generate-impl",
-    ]
-    if (use_blink_v8_binding_new_idl_callback_function) {
-      args += [ "--generate-impl-skip-callback-function" ]
-    }
-    args += [ rebase_path(idl_files_list, root_build_dir) ]
-
-    deps = [
-      "//third_party/blink/renderer/bindings:interfaces_info",
-      "//third_party/blink/renderer/bindings/scripts:cached_jinja_templates",
-      "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables",
-    ]
-  }
-}
-
-# Calls the aggregate_generated_bindings script.
-#
-# Parameters:
-#   sources = a list of source IDL files.
-#   component = a name of directory for these files (one word, no slashes).
-#   outputs = a name of file to write to.
-template("aggregate_generated_bindings") {
-  action(target_name) {
-    script = "//third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py"
-
-    inputs = invoker.sources
-    outputs = invoker.outputs
-
-    response_file_contents = rebase_path(inputs, root_build_dir)
-    args = [
-      "--component",
-      invoker.component,
-      "{{response_file_name}}",
-    ]
-    args += rebase_path(outputs, root_build_dir)
-
-    public_deps = invoker.public_deps
-  }
-}
-
-# Calls the compute_global_objects script.
-#
-# Parameters:
-#   sources = a list of source IDL files.
-#   sources_generated = a list of generated pickle sources.
-#   output_file = a pickle file to write to (need to specify directory)
-#
-template("compute_global_objects") {
-  action(target_name) {
-    script = "//third_party/blink/renderer/bindings/scripts/compute_global_objects.py"
-
-    # Write the file list to a unique temp file to avoid blowing out the
-    # command line length limit.
-    idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
-    write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir))
-
-    inputs = [
-               "//third_party/blink/renderer/bindings/scripts/utilities.py",
-               idl_files_list,
-             ] + invoker.sources_generated + invoker.sources
-
-    outputs = [ invoker.output_file ]
-
-    args = [
-      "--idl-files-list",
-      rebase_path(idl_files_list, root_build_dir),
-    ]
-    foreach(component, invoker.sources_generated) {
-      args += [
-        "--global-objects-component-files",
-        rebase_path(component, root_build_dir),
-      ]
-    }
-    args += [ rebase_path(invoker.output_file, root_build_dir) ]
-
-    deps = invoker.deps
-  }
-}
-
-# Calls the generate_global_constructors script.
-#
-# Parameters:
-#   sources = a list of source IDL files.
-#   global_objects_file = a global objects file generated by compute_global_objects
-#   interfaces = interfaces to generate global constructors for.
-#   component = component to generate global constructors for.
-#   output_dir = output directory to generate idl files and header files.
-#   deps = dependencies
-#
-template("generate_global_constructors") {
-  action(target_name) {
-    script = "//third_party/blink/renderer/bindings/scripts/generate_global_constructors.py"
-
-    # Write the file list to a unique temp file to avoid blowing out the
-    # command line length limit.
-    idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
-    write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir))
-
-    inputs = [
-               "//third_party/blink/renderer/bindings/scripts/utilities.py",
-               idl_files_list,
-               invoker.global_objects_file,
-             ] + invoker.sources
-
-    args = [
-      "--idl-files-list",
-      rebase_path(idl_files_list, root_build_dir),
-      "--global-objects-file",
-      rebase_path(invoker.global_objects_file, root_build_dir),
-      "--",
-    ]
-
-    output_dir = invoker.output_dir
-    component = invoker.component
-
-    # generate outputs from invoker.interfaces and invoker.basenames.
-    output_idl_files = []
-    output_header_files = []
-
-    # Need a variable due to a GN sytax restriction. We can't do "invoker.basenames[i]".
-    basename_list = invoker.basenames
-    i = 0
-    foreach(interface, invoker.interfaces) {
-      basename = basename_list[i]
-      args += [ interface ]
-      output_idl_file = "$output_dir/${basename}_${component}_constructors.idl"
-      args += [ rebase_path(output_idl_file, root_build_dir) ]
-      output_idl_files += [ output_idl_file ]
-      output_header_files +=
-          [ "$output_dir/${basename}_${component}_constructors.h" ]
-      i += 1
-    }
-
-    outputs = output_idl_files + output_header_files
-    if (defined(invoker.deps)) {
-      deps = invoker.deps
-    }
-    if (defined(invoker.public_deps)) {
-      public_deps = invoker.public_deps
-    }
-  }
-}
-
-# Calls the generate_origin_trial_features script.
-#
-# Parameters:
-#   sources = a list of source IDL files.
-#   component = component for which to generate origin trial feature bindings
-#       ("core" or "modules")
-#   output_dir = output directory to generate cpp file and header file.
-#   deps = dependencies
-#
-template("generate_origin_trial_features") {
-  action(target_name) {
-    script = "//third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py"
-
-    # Write the file list to a unique temp file to avoid blowing out the
-    # command line length limit.
-    idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
-    write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir))
-
-    inputs = [
-               "//third_party/blink/renderer/bindings/scripts/utilities.py",
-               "//third_party/blink/renderer/bindings/templates/origin_trial_features_for_${invoker.component}.cc.tmpl",
-               "//third_party/blink/renderer/bindings/templates/origin_trial_features_for_${invoker.component}.h.tmpl",
-               "$bindings_output_dir/interfaces_info.pickle",
-               idl_files_list,
-             ] + invoker.sources
-
-    args = [
-      "--output-directory",
-      rebase_path(invoker.output_dir, root_build_dir),
-      "--info-dir",
-      rebase_path("$bindings_output_dir", root_build_dir),
-      "--cache-dir",
-      rebase_path(bindings_scripts_output_dir, root_build_dir),
-      "--target-component",
-      invoker.component,
-      "--idl-files-list",
-      rebase_path(idl_files_list, root_build_dir),
-    ]
-
-    outputs = [
-      "${invoker.output_dir}/origin_trial_features_for_${invoker.component}.cc",
-      "${invoker.output_dir}/origin_trial_features_for_${invoker.component}.h",
-    ]
-
-    deps = [ "//third_party/blink/renderer/bindings:interfaces_info" ] +
-           invoker.deps
-  }
-}
diff --git a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
index ff4532ce..0089249e 100644
--- a/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
+++ b/third_party/blink/renderer/build/scripts/core/style/templates/computed_style_base.h.tmpl
@@ -143,10 +143,6 @@
 
   void InheritFrom(const ComputedStyleBase& other,
                                       IsAtShadowBoundary isAtShadowBoundary);
-  void InheritCustomPropertiesFrom(const ComputedStyleBase& other) {
-    inherited_variables_data_ = other.inherited_variables_data_;
-  }
-
   void CopyNonInheritedFromCached(
       const ComputedStyleBase& other);
 
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 500225f..98795571 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -65,7 +65,6 @@
 import("//third_party/blink/renderer/core/workers/build.gni")
 import("//third_party/blink/renderer/core/xml/build.gni")
 import("//third_party/blink/renderer/core/xmlhttprequest/build.gni")
-import("//third_party/blink/renderer/modules/modules_idl_files.gni")
 import("//third_party/blink/renderer/platform/platform_generated.gni")
 import("//third_party/protobuf/proto_library.gni")
 
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index b88b1dd..e3cfa01 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -1053,24 +1053,14 @@
   // Lazy evaluation of the before change style. We only need to update where
   // we are transitioning from if the final destination is changing.
   if (!state.before_change_style) {
-    ElementAnimations* element_animations =
-        state.animating_element.GetElementAnimations();
-    if (element_animations) {
-      const ComputedStyle* base_style = element_animations->BaseComputedStyle();
-      if (base_style) {
-        state.before_change_style =
-            CalculateBeforeChangeStyle(state.animating_element, *base_style);
-      }
-    }
-    // Use the style from the previous frame if no base style is found.
-    // Elements that have not been animated will not have a base style.
-    // Elements that were previously animated, but where all previously running
-    // animations have stopped may also be missing a base style. In both cases,
-    // the old style is equivalent to the base computed style.
-    if (!state.before_change_style) {
-      state.before_change_style =
-          CalculateBeforeChangeStyle(state.animating_element, state.old_style);
-    }
+    // By calling GetBaseComputedStyleOrThis, we're using the style from the
+    // previous frame if no base style is found. Elements that have not been
+    // animated will not have a base style. Elements that were previously
+    // animated, but where all previously running animations have stopped may
+    // also be missing a base style. In both cases, the old style is equivalent
+    // to the base computed style.
+    state.before_change_style = CalculateBeforeChangeStyle(
+        state.animating_element, *state.old_style.GetBaseComputedStyleOrThis());
   }
 
   if (ComputedValuesEqual(property, *state.before_change_style, state.style)) {
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
index ff399b71..5112f4fd 100644
--- a/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
@@ -99,6 +99,7 @@
   return CreateInterpolableColor(identifier_value->GetValueID());
 }
 
+// Spec link: https://www.w3.org/TR/css-color-4/#interpolation-alpha
 Color CSSColorInterpolationType::GetRGBA(const InterpolableValue& value) {
   const InterpolableList& list = To<InterpolableList>(value);
   DCHECK_GE(list.length(), kAlpha);
@@ -107,6 +108,9 @@
     const InterpolableValue& current_value = *(list.Get(i));
     color[i] = To<InterpolableNumber>(current_value).Value();
   }
+  // Prevent dividing 0
+  if (color[kAlpha] == 0)
+    return Color::kTransparent;
   return Color(MakeRGBA(std::round(color[kRed] / color[kAlpha]),
                         std::round(color[kGreen] / color[kAlpha]),
                         std::round(color[kBlue] / color[kAlpha]),
diff --git a/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc b/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc
index 3cc0c4ee..03540ef2 100644
--- a/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc
+++ b/third_party/blink/renderer/core/animation/css_color_interpolation_type_test.cc
@@ -29,4 +29,10 @@
                 *CSSColorInterpolationType::CreateInterpolableColor(color)));
 }
 
+TEST(CSSColorInterpolationTypeTest, GetRGBA4) {
+  Color color(35, 140, 10, 0);
+  EXPECT_EQ(Color(MakeRGBA(0, 0, 0, 0)),
+            CSSColorInterpolationType::GetRGBA(
+                *CSSColorInterpolationType::CreateInterpolableColor(color)));
+}
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/element_animations.cc b/third_party/blink/renderer/core/animation/element_animations.cc
index fa1b980..7447df77 100644
--- a/third_party/blink/renderer/core/animation/element_animations.cc
+++ b/third_party/blink/renderer/core/animation/element_animations.cc
@@ -124,29 +124,6 @@
   visitor->Trace(worklet_animations_);
 }
 
-const ComputedStyle* ElementAnimations::BaseComputedStyle() const {
-  return base_computed_style_.get();
-}
-
-const CSSBitset* ElementAnimations::BaseImportantSet() const {
-  if (IsAnimationStyleChange())
-    return base_important_set_.get();
-  return nullptr;
-}
-
-void ElementAnimations::UpdateBaseComputedStyle(
-    const ComputedStyle* computed_style,
-    std::unique_ptr<CSSBitset> base_important_set) {
-  DCHECK(computed_style);
-  base_computed_style_ = ComputedStyle::Clone(*computed_style);
-  base_important_set_ = std::move(base_important_set);
-}
-
-void ElementAnimations::ClearBaseComputedStyle() {
-  base_computed_style_ = nullptr;
-  base_important_set_ = nullptr;
-}
-
 bool ElementAnimations::UpdateBoxSizeAndCheckTransformAxisAlignment(
     const FloatSize& box_size) {
   bool preserves_axis_alignment = true;
diff --git a/third_party/blink/renderer/core/animation/element_animations.h b/third_party/blink/renderer/core/animation/element_animations.h
index debe9bc..e6e2cf4 100644
--- a/third_party/blink/renderer/core/animation/element_animations.h
+++ b/third_party/blink/renderer/core/animation/element_animations.h
@@ -83,12 +83,6 @@
   }
   bool IsAnimationStyleChange() const { return animation_style_change_; }
 
-  const ComputedStyle* BaseComputedStyle() const;
-  const CSSBitset* BaseImportantSet() const;
-  void UpdateBaseComputedStyle(const ComputedStyle*,
-                               std::unique_ptr<CSSBitset> base_important_set);
-  void ClearBaseComputedStyle();
-
   bool UpdateBoxSizeAndCheckTransformAxisAlignment(const FloatSize& box_size);
   bool IsIdentityOrTranslation() const;
 
@@ -106,22 +100,9 @@
   // style, we store a cached value of the 'base' computed style (e.g. with no
   // change from the running animations) and use that during style recalc,
   // applying only the animation changes on top of it.
+  //
+  // See also StyleBaseData.
   bool animation_style_change_;
-  scoped_refptr<ComputedStyle> base_computed_style_;
-  // Keeps track of the !important declarations used to build the base
-  // computed style. These declarations must not be overwritten by animation
-  // effects, hence we have to disable the base computed style optimization when
-  // !important declarations conflict with active animations.
-  //
-  // If there were no !important declarations in the base style, this field
-  // will be nullptr.
-  //
-  // TODO(andruud): We should be able to simply skip applying the animation
-  // for properties in this set instead of disabling the optimization.
-  // However, we currently need the cascade to handle the case where
-  // an !important declaration appears in a :visited selector.
-  // See https://crbug.com/1062217.
-  std::unique_ptr<CSSBitset> base_important_set_;
 
   FRIEND_TEST_ALL_PREFIXES(StyleEngineTest, PseudoElementBaseComputedStyle);
 };
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
deleted file mode 100644
index 2c9774d8..0000000
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/blink/renderer/bindings/bindings.gni")
-import("//third_party/blink/renderer/core/core.gni")
-
-# The paths in this file are absolute since this file is imported and the
-# file lists must be valid from multple "current directories".
-
-bindings_core_output_dir = "$bindings_output_dir/core"
-
-# Global constructors
-core_global_constructors_original_interfaces = [
-  "DedicatedWorkerGlobalScope",
-  "LayoutWorkletGlobalScope",
-  "SharedWorkerGlobalScope",
-  "Window",
-]
-
-# The size and the order in the following list must match to the previous one.
-if (use_blink_v8_binding_new_idl_interface) {
-  core_global_constructors_original_interface_basenames = []
-} else {
-  core_global_constructors_original_interface_basenames = [
-    "dedicated_worker_global_scope",
-    "layout_worklet_global_scope",
-    "shared_worker_global_scope",
-    "window",
-  ]
-}
-
-# The interfaces aren't technically files, but we can treat them as file names
-# to get process_file_template to generate lists of IDL files corresponding
-# to each interface.
-core_global_constructors_generated_idl_files =
-    process_file_template(
-        core_global_constructors_original_interface_basenames,
-        [ "$blink_core_output_dir/{{source_name_part}}_core_constructors.idl" ])
-
-# IDL interfaces that do not have any dependency to modules/ (partial
-# interfaces, mixins, partial mixins).
-core_interface_idl_files_core_only = []
-
-# IDL interfaces that depend on partial definitions in modules/ (partial
-# interfaces, mixins, partial mixins).
-core_interface_idl_files_modules_dependent = []
-
-# IDL partial definitions (partial interfaces, mixins, partial mixins).
-core_partial_definition_idl_files = []
-
-core_buffer_source_type_idl_files =
-    get_path_info([
-                    "typed_arrays/array_buffer.idl",
-                    "typed_arrays/array_buffer_view.idl",
-                    "typed_arrays/big_int_64_array.idl",
-                    "typed_arrays/big_uint_64_array.idl",
-                    "typed_arrays/data_view.idl",
-                    "typed_arrays/float32_array.idl",
-                    "typed_arrays/float64_array.idl",
-                    "typed_arrays/int16_array.idl",
-                    "typed_arrays/int32_array.idl",
-                    "typed_arrays/int8_array.idl",
-                    "typed_arrays/shared_array_buffer.idl",
-                    "typed_arrays/uint16_array.idl",
-                    "typed_arrays/uint32_array.idl",
-                    "typed_arrays/uint8_array.idl",
-                    "typed_arrays/uint8_clamped_array.idl",
-                  ],
-                  "abspath")
-
-# IDL files that only have typedefs/enums.
-core_typedefs_enums_only_idl_files = []
-
-core_callback_function_idl_files = []
-
-core_callback_interface_idl_files = []
-
-core_dictionary_idl_files = []
-
-core_testing_dictionary_idl_files = []
-
-webcore_testing_idl_files = []
-
-# Testing IDL files that have partial interfaces in modules.
-webcore_testing_idl_with_modules_dependency_files = []
-
-webcore_testing_dependency_idl_files = []
-
-generated_webcore_testing_idl_files = []
-
-core_definition_idl_files =
-    core_interface_idl_files_core_only +
-    core_interface_idl_files_modules_dependent +
-    core_buffer_source_type_idl_files + core_callback_interface_idl_files +
-    core_dictionary_idl_files
-
-core_testing_definition_idl_files =
-    core_testing_dictionary_idl_files + webcore_testing_idl_files +
-    webcore_testing_idl_with_modules_dependency_files
-
-# Static IDL files
-core_static_interface_idl_files =
-    core_definition_idl_files + core_testing_definition_idl_files +
-    core_callback_function_idl_files + core_typedefs_enums_only_idl_files
-
-core_static_dependency_idl_files =
-    core_partial_definition_idl_files + webcore_testing_dependency_idl_files
-
-# Generated IDL files
-core_generated_interface_idl_files =
-    generated_webcore_testing_idl_files  # interfaces
-core_generated_dependency_idl_files =
-    core_global_constructors_generated_idl_files  # partial interfaces
-
-# Dependency IDL files: don't generate individual bindings, but do process
-# in IDL dependency computation, and count as build dependencies
-# 'core_dependency_idl_files' is already used in Source/core, so avoid
-# collision
-core_all_dependency_idl_files =
-    core_static_dependency_idl_files + core_generated_dependency_idl_files
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.cc b/third_party/blink/renderer/core/css/css_crossfade_value.cc
index d092b4b..2b6ca62 100644
--- a/third_party/blink/renderer/core/css/css_crossfade_value.cc
+++ b/third_party/blink/renderer/core/css/css_crossfade_value.cc
@@ -25,6 +25,7 @@
 
 #include "third_party/blink/renderer/core/css/css_crossfade_value.h"
 
+#include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
@@ -63,10 +64,60 @@
          DataEquivalent(percentage_value_, other.percentage_value_);
 }
 
+class CSSCrossfadeValue::ObserverProxy final
+    : public GarbageCollected<CSSCrossfadeValue::ObserverProxy>,
+      public ImageResourceObserver {
+ public:
+  explicit ObserverProxy(CSSCrossfadeValue* owner) : owner_(owner) {}
+
+  void ImageChanged(ImageResourceContent*,
+                    CanDeferInvalidation defer) override {
+    for (const ImageResourceObserver* const_observer : Clients().Keys()) {
+      auto* observer = const_cast<ImageResourceObserver*>(const_observer);
+      observer->ImageChanged(static_cast<WrappedImagePtr>(owner_), defer);
+    }
+  }
+
+  bool WillRenderImage() override {
+    for (const ImageResourceObserver* const_observer : Clients().Keys()) {
+      auto* observer = const_cast<ImageResourceObserver*>(const_observer);
+      if (observer->WillRenderImage())
+        return true;
+    }
+    return false;
+  }
+
+  bool GetImageAnimationPolicy(
+      mojom::blink::ImageAnimationPolicy& animation_policy) override {
+    for (const ImageResourceObserver* const_observer : Clients().Keys()) {
+      auto* observer = const_cast<ImageResourceObserver*>(const_observer);
+      if (observer->GetImageAnimationPolicy(animation_policy))
+        return true;
+    }
+    return false;
+  }
+
+  String DebugName() const override { return "CrossfadeObserverProxy"; }
+
+  void Trace(Visitor* visitor) const { visitor->Trace(owner_); }
+
+ private:
+  const ClientSizeCountMap& Clients() const { return owner_->Clients(); }
+
+  Member<CSSCrossfadeValue> owner_;
+};
+
+ImageResourceObserver* CSSCrossfadeValue::GetObserverProxy() {
+  if (!observer_proxy_)
+    observer_proxy_ = MakeGarbageCollected<ObserverProxy>(this);
+  return observer_proxy_;
+}
+
 void CSSCrossfadeValue::TraceAfterDispatch(Visitor* visitor) const {
   visitor->Trace(from_value_);
   visitor->Trace(to_value_);
   visitor->Trace(percentage_value_);
+  visitor->Trace(observer_proxy_);
   CSSImageGeneratorValue::TraceAfterDispatch(visitor);
 }
 
diff --git a/third_party/blink/renderer/core/css/css_crossfade_value.h b/third_party/blink/renderer/core/css/css_crossfade_value.h
index 602b843..afccbc7 100644
--- a/third_party/blink/renderer/core/css/css_crossfade_value.h
+++ b/third_party/blink/renderer/core/css/css_crossfade_value.h
@@ -33,6 +33,8 @@
 
 namespace blink {
 
+class ImageResourceObserver;
+
 namespace cssvalue {
 
 class CORE_EXPORT CSSCrossfadeValue final : public CSSImageGeneratorValue {
@@ -46,6 +48,9 @@
   CSSValue& To() const { return *to_value_; }
   CSSPrimitiveValue& Percentage() const { return *percentage_value_; }
 
+  bool HasClients() const { return !Clients().IsEmpty(); }
+  ImageResourceObserver* GetObserverProxy();
+
   String CustomCSSText() const;
   bool HasFailedOrCanceledSubresources() const;
   bool Equals(const CSSCrossfadeValue&) const;
@@ -53,9 +58,12 @@
   void TraceAfterDispatch(Visitor*) const;
 
  private:
+  class ObserverProxy;
+
   Member<CSSValue> from_value_;
   Member<CSSValue> to_value_;
   Member<CSSPrimitiveValue> percentage_value_;
+  Member<ObserverProxy> observer_proxy_;
 };
 
 }  // namespace cssvalue
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index b8854b44..bb31ab5 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -994,6 +994,7 @@
     },
     {
       name: "forced-color-adjust",
+      field_group: "*",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       inherited: true,
       runtime_flag: "ForcedColors",
@@ -2799,6 +2800,7 @@
     {
       name: "math-shift",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      field_group: "*",
       field_template: "keyword",
       inherited: true,
       keywords: ["normal", "compact"],
@@ -2809,6 +2811,7 @@
     {
       name: "math-style",
       property_methods: ["CSSValueFromComputedStyleInternal"],
+      field_group: "*",
       field_template: "keyword",
       inherited: true,
       keywords: ["normal", "compact"],
@@ -6307,7 +6310,7 @@
       visited_property_for: "caret-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_auto_color.h"],
       default_value: "StyleAutoColor::AutoColor()",
@@ -6324,7 +6327,7 @@
       name: "-internal-visited-column-rule-color",
       visited_property_for: "column-rule-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*->multi-col",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6337,7 +6340,7 @@
       name: "-internal-visited-background-color",
       visited_property_for: "background-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor(Color::kTransparent)",
@@ -6357,7 +6360,7 @@
       name: "-internal-visited-border-left-color",
       visited_property_for: "border-left-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6375,7 +6378,7 @@
       name: "-internal-visited-border-right-color",
       visited_property_for: "border-right-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6393,7 +6396,7 @@
       name: "-internal-visited-border-top-color",
       visited_property_for: "border-top-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6411,7 +6414,7 @@
       name: "-internal-visited-border-bottom-color",
       visited_property_for: "border-bottom-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6487,7 +6490,7 @@
       name: "-internal-visited-outline-color",
       visited_property_for: "outline-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6519,7 +6522,7 @@
       name: "-internal-visited-text-decoration-color",
       visited_property_for: "text-decoration-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6537,7 +6540,7 @@
       visited_property_for: "-webkit-text-emphasis-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6552,7 +6555,7 @@
       visited_property_for: "-webkit-text-fill-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6567,7 +6570,7 @@
       visited_property_for: "-webkit-text-stroke-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_visited",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6582,7 +6585,7 @@
     {
       name: "-internal-forced-background-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->forced_colors",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/layout/layout_theme.h"],
       default_value: "StyleColor(CSSValueID::kCanvas)",
@@ -6600,7 +6603,7 @@
     {
       name: "-internal-forced-border-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->forced_colors",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6614,7 +6617,7 @@
       name: "-internal-forced-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_forced_colors",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/layout/layout_theme.h"],
       default_value: "StyleColor(CSSValueID::kCanvastext)",
@@ -6629,7 +6632,7 @@
     {
       name: "-internal-forced-outline-color",
       property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "ColorIncludingFallback"],
-      field_group: "*",
+      field_group: "*->forced_colors",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/css/style_color.h"],
       default_value: "StyleColor::CurrentColor()",
@@ -6644,7 +6647,7 @@
       visited_property_for: "-internal-forced-color",
       property_methods: ["ParseSingleValue", "ColorIncludingFallback"],
       inherited: true,
-      field_group: "*",
+      field_group: "*->inherited_forced_colors",
       field_template: "external",
       include_paths: ["third_party/blink/renderer/core/layout/layout_theme.h"],
       default_value: "StyleColor(CSSValueID::kCanvastext)",
diff --git a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
index 08ce6c9..46bd4fb 100644
--- a/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
+++ b/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -129,6 +129,10 @@
     DCHECK_EQ(identifier_value->GetValueID(), CSSValueID::kNone);
     return nullptr;
   }
+  // Reject paint() functions. They make assumptions about the client (being
+  // a LayoutObject) that we can't meet with the current implementation.
+  if (IsA<CSSPaintValue>(value))
+    return nullptr;
   return Load(value, FetchParameters::kNone, cross_origin);
 }
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
index 047bcae..74e4578 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -269,6 +269,7 @@
   style.SetTextEmphasisMark(TextEmphasisMark::kNone);
   style.SetVerticalAlign(EVerticalAlign ::kMiddle);
   style.SetWordBreak(EWordBreak::kKeepAll);
+  style.SetWordSpacing(0.0f);
   style.SetWritingMode(WritingMode::kHorizontalTb);
 
   style.ClearAppliedTextDecorations();
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index f87707f..19f0509 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -129,6 +129,12 @@
           state.GetAnimatingElement()->HasAnimations());
 }
 
+bool IsAnimationStyleChange(Element& element) {
+  if (auto* element_animations = element.GetElementAnimations())
+    return element_animations->IsAnimationStyleChange();
+  return false;
+}
+
 bool ShouldComputeBaseComputedStyle(const ComputedStyle* base_computed_style) {
 #if DCHECK_IS_ON()
   // The invariant in the base computed style optimization is that as long as
@@ -199,6 +205,25 @@
 #endif  // DCHECK_IS_ON()
 }
 
+void PreserveTextAutosizingMultiplierIfNeeded(
+    StyleResolverState& state,
+    const StyleRequest& style_request) {
+  const ComputedStyle* old_style = state.GetElement().GetComputedStyle();
+  if (!style_request.IsPseudoStyleRequest() && old_style) {
+    state.Style()->SetTextAutosizingMultiplier(
+        old_style->TextAutosizingMultiplier());
+  }
+}
+
+bool TextAutosizingMultiplierChanged(const StyleResolverState& state,
+                                     const ComputedStyle& base_computed_style) {
+  // Note that |old_style| can be a style replaced by
+  // TextAutosizer::ApplyMultiplier.
+  const ComputedStyle* old_style = state.GetElement().GetComputedStyle();
+  return old_style && (old_style->TextAutosizingMultiplier() !=
+                       base_computed_style.TextAutosizingMultiplier());
+}
+
 }  // namespace
 
 static CSSPropertyValueSet* LeftToRightDeclaration() {
@@ -690,40 +715,19 @@
   return state.GetAnimatingElement()->GetElementAnimations();
 }
 
-static const ComputedStyle* CachedAnimationBaseComputedStyle(
-    StyleResolverState& state) {
-  ElementAnimations* element_animations = GetElementAnimations(state);
-  if (!element_animations)
+static StyleBaseData* GetBaseData(const StyleResolverState& state) {
+  Element* animating_element = state.GetAnimatingElement();
+  if (!animating_element)
     return nullptr;
-
-  return element_animations->BaseComputedStyle();
+  auto* old_style = animating_element->GetComputedStyle();
+  return old_style ? old_style->BaseData().get() : nullptr;
 }
 
-static void UpdateAnimationBaseComputedStyle(StyleResolverState& state,
-                                             StyleCascade& cascade,
-                                             bool forced_update) {
-  if (!state.GetAnimatingElement())
-    return;
-
-  if (!state.CanCacheBaseStyle())
-    return;
-
-  if (forced_update)
-    state.GetAnimatingElement()->EnsureElementAnimations();
-
-  ElementAnimations* element_animations =
-      state.GetAnimatingElement()->GetElementAnimations();
-  if (!element_animations)
-    return;
-
-  if (element_animations->IsAnimationStyleChange() &&
-      element_animations->BaseComputedStyle()) {
-    return;
-  }
-
-  std::unique_ptr<CSSBitset> important_set = cascade.GetImportantSet();
-  element_animations->UpdateBaseComputedStyle(state.Style(),
-                                              std::move(important_set));
+static const ComputedStyle* CachedAnimationBaseComputedStyle(
+    StyleResolverState& state) {
+  if (auto* base_data = GetBaseData(state))
+    return base_data->GetBaseComputedStyle();
+  return nullptr;
 }
 
 static void IncrementResolvedStyleCounters(const StyleRequest& style_request,
@@ -958,16 +962,11 @@
       return;
     }
 
-    if (!style_request.IsPseudoStyleRequest() && element->GetComputedStyle() &&
-        element->GetComputedStyle()->TextAutosizingMultiplier() !=
-            state.Style()->TextAutosizingMultiplier()) {
-      // Preserve the text autosizing multiplier on style recalc. Autosizer will
-      // update it during layout if needed.
-      // NOTE: this must occur before ApplyMatchedProperties for correct
-      // computation of font-relative lengths.
-      state.Style()->SetTextAutosizingMultiplier(
-          element->GetComputedStyle()->TextAutosizingMultiplier());
-    }
+    // Preserve the text autosizing multiplier on style recalc. Autosizer will
+    // update it during layout if needed.
+    // NOTE: This must occur before CascadeAndApplyMatchedProperties for correct
+    // computation of font-relative lengths.
+    PreserveTextAutosizingMultiplierIfNeeded(state, style_request);
 
     CascadeAndApplyMatchedProperties(state, cascade);
 
@@ -989,6 +988,8 @@
   if (base_is_usable) {
     DCHECK(animation_base_computed_style);
     state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
+    state.StyleRef().SetBaseData(
+        scoped_refptr<StyleBaseData>(GetBaseData(state)));
     state.Style()->SetStyleType(style_request.pseudo_id);
     if (!state.ParentStyle()) {
       state.SetParentStyle(InitialStyleForElement());
@@ -1241,12 +1242,13 @@
   DCHECK(animating_element == &element ||
          animating_element->ParentOrShadowHostElement() == element);
 
-  if (!HasAnimationsOrTransitions(state)) {
-    // Ensure that the base computed style is not stale even if not currently
-    // running an animation or transition. This ensures that any new transitions
-    // use the correct starting point based on the "before change" style.
-    UpdateAnimationBaseComputedStyle(state, cascade, false);
+  if (!HasAnimationsOrTransitions(state))
     return false;
+
+  if (!IsAnimationStyleChange(*animating_element) ||
+      !state.StyleRef().BaseData()) {
+    state.StyleRef().SetBaseData(StyleBaseData::Create(
+        ComputedStyle::Clone(state.StyleRef()), cascade.GetImportantSet()));
   }
 
   CSSAnimations::CalculateAnimationUpdate(
@@ -1261,10 +1263,7 @@
   CSSAnimations::SnapshotCompositorKeyframes(
       element, state.AnimationUpdate(), *state.Style(), state.ParentStyle());
 
-  bool has_update = !state.AnimationUpdate().IsEmpty();
-  UpdateAnimationBaseComputedStyle(state, cascade, has_update);
-
-  if (!has_update)
+  if (state.AnimationUpdate().IsEmpty())
     return false;
 
   const ActiveInterpolationsMap& animations =
@@ -1436,10 +1435,11 @@
     return false;
 
   ElementAnimations* element_animations = GetElementAnimations(state);
-  if (!element_animations || !element_animations->BaseComputedStyle())
+  if (!element_animations || !element_animations->IsAnimationStyleChange())
     return false;
 
-  if (!element_animations->IsAnimationStyleChange())
+  StyleBaseData* base_data = GetBaseData(state);
+  if (!base_data || !base_data->GetBaseComputedStyle())
     return false;
 
   // Animating a custom property can have side effects on other properties
@@ -1457,10 +1457,8 @@
   // animation. We cannot use the base computed style optimization in such
   // cases.
   if (CSSAnimations::IsAnimatingFontAffectingProperties(element_animations)) {
-    if (element_animations->BaseComputedStyle() &&
-        element_animations->BaseComputedStyle()->HasFontRelativeUnits()) {
+    if (base_data->GetBaseComputedStyle()->HasFontRelativeUnits())
       return false;
-    }
   }
 
   // Normally, we apply all active animation effects on top of the style created
@@ -1470,11 +1468,16 @@
   // style, we disable the base computed style optimization.
   // [1] https://drafts.csswg.org/css-cascade-4/#cascade-origin
   if (CSSAnimations::IsAnimatingStandardProperties(
-          element_animations, element_animations->BaseImportantSet(),
+          element_animations, base_data->GetBaseImportantSet(),
           KeyframeEffect::kDefaultPriority)) {
     return false;
   }
 
+  if (TextAutosizingMultiplierChanged(state,
+                                      *base_data->GetBaseComputedStyle())) {
+    return false;
+  }
+
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
index a33c037..3c4f41f 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -88,13 +88,14 @@
   animations.SetAnimationStyleChange(true);
 
   StyleResolver& resolver = GetStyleEngine().GetStyleResolver();
-  ASSERT_TRUE(resolver.ResolveStyle(div, StyleRecalcContext()));
-  EXPECT_EQ(20, resolver.ResolveStyle(div, StyleRecalcContext())->FontSize());
-  ASSERT_TRUE(animations.BaseComputedStyle());
-  EXPECT_EQ(20, animations.BaseComputedStyle()->FontSize());
+  auto style1 = resolver.ResolveStyle(div, StyleRecalcContext());
+  ASSERT_TRUE(style1);
+  EXPECT_EQ(20, style1->FontSize());
+  ASSERT_TRUE(style1->GetBaseComputedStyle());
+  EXPECT_EQ(20, style1->GetBaseComputedStyle()->FontSize());
 
-  // Getting style with customized parent style should not affect cached
-  // animation base computed style.
+  // Getting style with customized parent style should not affect previously
+  // produced animation base computed style.
   const ComputedStyle* parent_style =
       GetDocument().documentElement()->GetComputedStyle();
   StyleRequest style_request;
@@ -102,8 +103,8 @@
   style_request.layout_parent_override = parent_style;
   EXPECT_EQ(10, resolver.ResolveStyle(div, StyleRecalcContext(), style_request)
                     ->FontSize());
-  ASSERT_TRUE(animations.BaseComputedStyle());
-  EXPECT_EQ(20, animations.BaseComputedStyle()->FontSize());
+  ASSERT_TRUE(style1->GetBaseComputedStyle());
+  EXPECT_EQ(20, style1->GetBaseComputedStyle()->FontSize());
   EXPECT_EQ(20, resolver.ResolveStyle(div, StyleRecalcContext())->FontSize());
 }
 
@@ -134,9 +135,6 @@
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
   StyleForId("div");
 
-  ASSERT_TRUE(div->GetElementAnimations());
-  EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
-
   StyleResolverState state(GetDocument(), *div);
   EXPECT_TRUE(StyleResolver::CanReuseBaseComputedStyle(state));
 }
@@ -164,13 +162,12 @@
 
   div->SetNeedsAnimationStyleRecalc();
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
-  StyleForId("div");
+  auto style = StyleForId("div");
 
-  ASSERT_TRUE(div->GetElementAnimations());
-  const CSSBitset* bitset = div->GetElementAnimations()->BaseImportantSet();
+  const CSSBitset* bitset = style->GetBaseImportantSet();
   EXPECT_FALSE(CSSAnimations::IsAnimatingStandardProperties(
       div->GetElementAnimations(), bitset, KeyframeEffect::kDefaultPriority));
-  EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+  EXPECT_TRUE(style->GetBaseComputedStyle());
   EXPECT_FALSE(bitset && bitset->Has(CSSPropertyID::kWidth));
   EXPECT_TRUE(bitset && bitset->Has(CSSPropertyID::kHeight));
 }
@@ -235,11 +232,10 @@
 
   div->SetNeedsAnimationStyleRecalc();
   GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
-  StyleForId("div");
+  auto style = StyleForId("div");
 
-  ASSERT_TRUE(div->GetElementAnimations());
-  EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
-  EXPECT_TRUE(div->GetElementAnimations()->BaseImportantSet());
+  EXPECT_TRUE(style->GetBaseComputedStyle());
+  EXPECT_TRUE(style->GetBaseImportantSet());
 
   StyleResolverState state(GetDocument(), *div);
   EXPECT_FALSE(StyleResolver::CanReuseBaseComputedStyle(state));
@@ -294,53 +290,6 @@
             ComputedValue("font-size", *StyleForId("target")));
 }
 
-TEST_F(StyleResolverTest, NonCachableStyleCheckDoesNotAffectBaseComputedStyle) {
-  GetDocument().documentElement()->setInnerHTML(R"HTML(
-    <style>
-      .adjust { color: rgb(0, 0, 0); }
-    </style>
-    <div>
-      <div style="color: rgb(0, 128, 0)">
-        <div id="target" style="transition: color 1s linear"></div>
-      </div>
-    </div>
-  )HTML");
-  UpdateAllLifecyclePhasesForTest();
-
-  Element* target = GetDocument().getElementById("target");
-
-  EXPECT_EQ("rgb(0, 128, 0)", ComputedValue("color", *StyleForId("target")));
-
-  // Trigger a transition on an inherited property.
-  target->setAttribute(html_names::kClassAttr, "adjust");
-  UpdateAllLifecyclePhasesForTest();
-  ElementAnimations* element_animations = target->GetElementAnimations();
-  EXPECT_TRUE(element_animations);
-  Animation* transition = (*element_animations->Animations().begin()).key;
-  EXPECT_TRUE(transition);
-
-  // Advance to the midpoint of the transition.
-  transition->setCurrentTime(MakeGarbageCollected<V8CSSNumberish>(500),
-                             ASSERT_NO_EXCEPTION);
-  UpdateAllLifecyclePhasesForTest();
-  EXPECT_EQ("rgb(0, 64, 0)", ComputedValue("color", *StyleForId("target")));
-  EXPECT_TRUE(element_animations->BaseComputedStyle());
-
-  element_animations->ClearBaseComputedStyle();
-
-  // Perform a non-cacheable style resolution, and ensure that the base computed
-  // style is not updated.
-  StyleRequest style_request;
-  style_request.matching_behavior = kMatchAllRulesExcludingSMIL;
-  GetStyleEngine().GetStyleResolver().ResolveStyle(target, StyleRecalcContext(),
-                                                   style_request);
-  EXPECT_FALSE(element_animations->BaseComputedStyle());
-
-  // Computing the style with default args updates the base computed style.
-  EXPECT_EQ("rgb(0, 64, 0)", ComputedValue("color", *StyleForId("target")));
-  EXPECT_TRUE(element_animations->BaseComputedStyle());
-}
-
 class StyleResolverFontRelativeUnitTest
     : public testing::WithParamInterface<const char*>,
       public StyleResolverTest {};
@@ -363,8 +312,7 @@
   auto computed_style = StyleForId("div");
 
   EXPECT_TRUE(computed_style->HasFontRelativeUnits());
-  ASSERT_TRUE(div->GetElementAnimations());
-  EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+  EXPECT_TRUE(computed_style->GetBaseComputedStyle());
 
   StyleResolverState state(GetDocument(), *div);
   EXPECT_FALSE(StyleResolver::CanReuseBaseComputedStyle(state));
@@ -388,8 +336,7 @@
   auto computed_style = StyleForId("div");
 
   EXPECT_TRUE(computed_style->HasFontRelativeUnits());
-  ASSERT_TRUE(div->GetElementAnimations());
-  EXPECT_TRUE(div->GetElementAnimations()->BaseComputedStyle());
+  EXPECT_TRUE(computed_style->GetBaseComputedStyle());
 
   StyleResolverState state(GetDocument(), *div);
   EXPECT_TRUE(StyleResolver::CanReuseBaseComputedStyle(state));
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index fd36ed7..e2cf015 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2534,18 +2534,21 @@
   before->SetNeedsAnimationStyleRecalc();
   UpdateAllLifecyclePhases();
 
-  scoped_refptr<ComputedStyle> base_computed_style =
-      animations->base_computed_style_;
+  ASSERT_TRUE(before->GetComputedStyle());
+  const ComputedStyle* base_computed_style =
+      before->GetComputedStyle()->GetBaseComputedStyle();
   EXPECT_TRUE(base_computed_style);
 
   before->SetNeedsAnimationStyleRecalc();
   UpdateAllLifecyclePhases();
 
-  EXPECT_TRUE(animations->base_computed_style_);
+  ASSERT_TRUE(before->GetComputedStyle());
+  EXPECT_TRUE(before->GetComputedStyle()->GetBaseComputedStyle());
 #if !DCHECK_IS_ON()
   // When DCHECK is enabled, BaseComputedStyle() returns null and we repeatedly
   // create new instances which means the pointers will be different here.
-  EXPECT_EQ(base_computed_style, animations->base_computed_style_);
+  EXPECT_EQ(base_computed_style,
+            before->GetComputedStyle()->GetBaseComputedStyle());
 #endif
 }
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 58c0aa6..836647f7 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -4574,6 +4574,8 @@
       load_event_progress_ == kLoadEventInProgress) {
     EnqueueResizeEvent();
     EnqueueVisualViewportResizeEvent();
+    if (GetFrame()->IsMainFrame() && !Printing())
+      probe::DidResizeMainFrame(GetFrame());
   }
   if (!HasViewportUnits())
     return;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 5e886a8..601069e 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2781,7 +2781,6 @@
         element_animations->CssAnimations().Cancel();
         element_animations->SetAnimationStyleChange(false);
       }
-      element_animations->ClearBaseComputedStyle();
     }
   }
 
diff --git a/third_party/blink/renderer/core/editing/finder/find_task_controller.h b/third_party/blink/renderer/core/editing/finder/find_task_controller.h
index 9e8d427..48827e02 100644
--- a/third_party/blink/renderer/core/editing/finder/find_task_controller.h
+++ b/third_party/blink/renderer/core/editing/finder/find_task_controller.h
@@ -9,9 +9,6 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/editing/position.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
-#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_controller.h"
-#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
 #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 7c07904..e4bf32d 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1479,6 +1479,9 @@
   RuntimeEnabledFeatures::SetNewCanvas2DAPIEnabled(
       prefs.new_canvas_2d_api_enabled);
 
+  RuntimeEnabledFeatures::SetCanvas2dLayersEnabled(
+      prefs.canvas_2d_layers_enabled);
+
   // Disable antialiasing for 2d canvas if requested on the command line.
   settings->SetAntialiased2dCanvasEnabled(
       !prefs.antialiased_2d_canvas_disabled);
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc
index ae969dd..ffa854c9 100644
--- a/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -617,6 +617,9 @@
               "errors when attempting to parse the a=extmap-allow-mixed "
               "line in the SDP remove the line from the SDP during "
               "signalling."};
+    case WebFeature::kXHRJSONEncodingDetection:
+      return {"XHRJSONEncodingDetection", kM93,
+              "UTF-16 is not supported by response json in XMLHttpRequest"};
     // Features that aren't deprecated don't have a deprecation message.
     default:
       return {"NotDeprecated", kUnknown, ""};
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 11d1afb..014d070 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -3853,10 +3853,8 @@
   if (!document || !document->IsActive())
     return;
   document->LayoutViewportWasResized();
-  if (frame_->IsMainFrame()) {
+  if (frame_->IsMainFrame())
     TextAutosizer::UpdatePageInfoInAllFrames(frame_);
-    probe::DidResizeMainFrame(frame_.Get());
-  }
 }
 
 void LocalFrameView::DidChangeScrollOffset() {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
index 9f9ad06..932a700 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_performance_monitor.cc
@@ -79,7 +79,7 @@
     return;
 
   key_.set<IsOffscreenField>(context->Host()->IsOffscreenCanvas());
-  key_.set<IsOffscreenField>(context->IsAccelerated());
+  key_.set<IsAcceleratedField>(context->IsAccelerated());
   key_.set<ContextTypeField>(context->GetContextType());
   // The padding field ensures at least one bit is set in the key in order
   // to avoid a key == 0, which is not supported by WTF::HashSet
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css
index e9bc734..93f608e 100644
--- a/third_party/blink/renderer/core/html/resources/html.css
+++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -645,20 +645,15 @@
 /* TODO(crbug.com/880258): Use different styles for
   `-internal-autofill-previewed` and `-internal-autofill-selected`. */
 input:-internal-autofill-previewed,
-textarea:-internal-autofill-previewed,
-select:-internal-autofill-previewed,
 input:-internal-autofill-selected,
+textarea:-internal-autofill-previewed,
 textarea:-internal-autofill-selected,
+select:-internal-autofill-previewed,
 select:-internal-autofill-selected {
   appearance: menulist-button;
   background-image:none !important;
-  color: -internal-light-dark(black, white) !important;
-}
-
-select:-internal-autofill-previewed,
-select:-internal-autofill-selected {
-  /* The background color of <input> and <textarea> are determined by the native theme. */
   background-color: -internal-light-dark(#E8F0FE, rgba(70,90,126,0.4)) !important;
+  color: -internal-light-dark(black, white) !important;
 }
 
 input[type="radio" i],
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index a71e7ce9..f61bb8e0 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1619,7 +1619,8 @@
   // above will return true if the *used* value of transform-style is
   // preserve-3d, so to estimate compat we need to count if the line below is
   // reached.
-  if (style->TransformStyle3D() == ETransformStyle3D::kPreserve3d) {
+  if (style->TransformStyle3D() == ETransformStyle3D::kPreserve3d &&
+      (!IsInline() || IsAtomicInlineLevel())) {
     UseCounter::Count(
         GetDocument(),
         WebFeature::kTransformStyleContainingBlockComputedUsedMismatch);
@@ -2812,16 +2813,6 @@
   }
 }
 
-void LayoutObject::ClearBaseComputedStyle() {
-  NOT_DESTROYED();
-  auto* element = DynamicTo<Element>(GetNode());
-  if (!element)
-    return;
-
-  if (ElementAnimations* animations = element->GetElementAnimations())
-    animations->ClearBaseComputedStyle();
-}
-
 static bool AreNonIdenticalCursorListsEqual(const ComputedStyle* a,
                                             const ComputedStyle* b) {
   DCHECK_NE(a->Cursors(), b->Cursors());
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 0b8f195..930ce9f 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2272,8 +2272,6 @@
   void SetModifiedStyleOutsideStyleRecalc(scoped_refptr<const ComputedStyle>,
                                           ApplyStyleChanges);
 
-  void ClearBaseComputedStyle();
-
   // This function returns an enclosing non-anonymous LayoutBlock for this
   // element. This function is not always returning the containing block as
   // defined by CSS. In particular:
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 500edbbb..dbcbc108 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -893,24 +893,50 @@
     const auto* const text_combine = DynamicTo<LayoutNGTextCombine>(Parent());
     const NGPhysicalBoxFragment* container_fragment = nullptr;
     PhysicalOffset point_in_container_fragment;
-    for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
-      DCHECK(&cursor.ContainerFragment());
-      if (container_fragment != &cursor.ContainerFragment()) {
-        container_fragment = &cursor.ContainerFragment();
-        point_in_container_fragment =
-            point_in_contents - container_fragment->OffsetFromOwnerLayoutBox();
-        if (UNLIKELY(text_combine)) {
+    if (!IsSVGInlineText()) {
+      for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
+        DCHECK(&cursor.ContainerFragment());
+        if (container_fragment != &cursor.ContainerFragment()) {
+          container_fragment = &cursor.ContainerFragment();
           point_in_container_fragment =
-              text_combine->AdjustOffsetForHitTest(point_in_container_fragment);
+              point_in_contents -
+              container_fragment->OffsetFromOwnerLayoutBox();
+          if (UNLIKELY(text_combine)) {
+            point_in_container_fragment = text_combine->AdjustOffsetForHitTest(
+                point_in_container_fragment);
+          }
+        }
+        if (!EnclosingIntRect(cursor.Current().RectInContainerFragment())
+                 .Contains(FlooredIntPoint(point_in_container_fragment)))
+          continue;
+        if (auto position_with_affinity =
+                cursor.PositionForPointInChild(point_in_container_fragment)) {
+          // Note: Due by Bidi adjustment, |position_with_affinity| isn't
+          // relative to this.
+          return AdjustForEditingBoundary(position_with_affinity);
         }
       }
-      point_in_container_fragment = cursor.CurrentItem()->MapPointInContainer(
-          point_in_container_fragment);
-      if (!EnclosingIntRect(cursor.Current().RectInContainerFragment())
-               .Contains(FlooredIntPoint(point_in_container_fragment)))
-        continue;
-      if (auto position_with_affinity =
-              cursor.PositionForPointInChild(point_in_container_fragment)) {
+    } else {
+      NGInlineCursor last_hit_cursor;
+      for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
+        DCHECK(&cursor.ContainerFragment());
+        if (container_fragment != &cursor.ContainerFragment()) {
+          container_fragment = &cursor.ContainerFragment();
+          point_in_container_fragment =
+              point_in_contents -
+              container_fragment->OffsetFromOwnerLayoutBox();
+        }
+        point_in_container_fragment = cursor.CurrentItem()->MapPointInContainer(
+            point_in_container_fragment);
+        if (!cursor.Current().RectInContainerFragment().Contains(
+                point_in_container_fragment))
+          continue;
+        if (cursor.PositionForPointInChild(point_in_container_fragment))
+          last_hit_cursor = cursor;
+      }
+      if (last_hit_cursor) {
+        auto position_with_affinity = last_hit_cursor.PositionForPointInChild(
+            point_in_container_fragment);
         // Note: Due by Bidi adjustment, |position_with_affinity| isn't relative
         // to this.
         return AdjustForEditingBoundary(position_with_affinity);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
index 15cd89d..2e27405 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -920,8 +920,14 @@
   LayoutUnit width = Size().width;
   LayoutUnit height = Size().height;
   if (Type() == kSvgText) {
-    width = LayoutUnit(SvgFragmentData()->rect.Size().Width());
-    height = LayoutUnit(SvgFragmentData()->rect.Size().Height());
+    const NGSvgFragmentData& data = *SvgFragmentData();
+    if (IsHorizontal()) {
+      width = LayoutUnit(data.rect.Size().Width() / data.length_adjust_scale);
+      height = LayoutUnit(data.rect.Size().Height());
+    } else {
+      width = LayoutUnit(data.rect.Size().Width());
+      height = LayoutUnit(data.rect.Size().Height() / data.length_adjust_scale);
+    }
   }
   if (start_offset == StartOffset() && end_offset == EndOffset()) {
     return {LayoutUnit(), LayoutUnit(), width, height};
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
index 77e8acf..294db3e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -1581,4 +1581,25 @@
       << "We paint combined text '0' without scaling in X-axis.";
 }
 
+// http://crbug.com/1226930
+TEST_F(NGInlineNodeTest, TextCombineWordSpacing) {
+  ScopedLayoutNGTextCombineForTest enable_layout_ng_text_combine(true);
+  LoadAhem();
+  InsertStyleElement(
+      "div {"
+      "  font: 10px/20px Ahem;"
+      "  letter-spacing: 1px;"
+      "  text-combine-upright: all;"
+      "  word-spacing: 1px;"
+      "  writing-mode: vertical-rl;"
+      "}");
+  SetBodyInnerHTML("<div id=t1>ab</div>");
+  const auto& text =
+      *To<Text>(GetElementById("t1")->firstChild())->GetLayoutObject();
+  const auto& font_description = text.StyleRef().GetFont().GetFontDescription();
+
+  EXPECT_EQ(0, font_description.LetterSpacing());
+  EXPECT_EQ(0, font_description.WordSpacing());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
index 8ceb8d14..821fa98 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -113,12 +113,14 @@
     needs_text_metrics_update_ = false;
   }
 
+  FloatRect old_boundaries = ObjectBoundingBox();
+
   UpdateNGBlockLayout();
   needs_update_bounding_box_ = true;
 
-  // TODO(crbug.com/1179585): Pass |bounds_changed|, and check the return value
-  // of the function.
-  UpdateTransformAfterLayout(true);
+  // If our bounds changed, notify the parents.
+  if (UpdateTransformAfterLayout(old_boundaries != ObjectBoundingBox()))
+    SetNeedsBoundariesUpdate();
 }
 
 bool LayoutNGSVGText::IsObjectBoundingBoxValid() const {
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc
index c37fd886..0f2f89c6 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -1266,8 +1266,6 @@
 
   if (multiplier != 1)
     page_info_.has_autosized_ = true;
-
-  layout_object->ClearBaseComputedStyle();
 }
 
 bool TextAutosizer::IsWiderOrNarrowerDescendant(Cluster* cluster) {
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
index 8ef0186..5ea8502 100644
--- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
+++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -31,56 +31,19 @@
   static bool ObjectRequiresPrePaint(const LayoutObject&);
   static bool ObjectRequiresTreeBuilderContext(const LayoutObject&);
 
-  struct PrePaintTreeWalkContext {
+  // This provides a default base copy constructor for PrePaintTreeWalkContext.
+  // It contains all fields except for tree_builder_context which needs special
+  // treatment in the copy constructor.
+  struct PrePaintTreeWalkContextBase {
     STACK_ALLOCATED();
 
+   protected:
+    PrePaintTreeWalkContextBase() = default;
+    PrePaintTreeWalkContextBase(const PrePaintTreeWalkContextBase&) = default;
+
    public:
-    PrePaintTreeWalkContext() {
-      tree_builder_context.emplace();
-    }
-    PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context,
-                            bool needs_tree_builder_context)
-        : paint_invalidator_context(parent_context.paint_invalidator_context),
-          ancestor_scroll_container_paint_layer(
-              parent_context.ancestor_scroll_container_paint_layer),
-          inside_blocking_touch_event_handler(
-              parent_context.inside_blocking_touch_event_handler),
-          effective_allowed_touch_action_changed(
-              parent_context.effective_allowed_touch_action_changed),
-          inside_blocking_wheel_event_handler(
-              parent_context.inside_blocking_wheel_event_handler),
-          blocking_wheel_event_handler_changed(
-              parent_context.blocking_wheel_event_handler_changed),
-          clip_changed(parent_context.clip_changed),
-          paint_invalidation_container(
-              parent_context.paint_invalidation_container),
-          paint_invalidation_container_for_stacked_contents(
-              parent_context
-                  .paint_invalidation_container_for_stacked_contents) {
-      if (needs_tree_builder_context || DCHECK_IS_ON()) {
-        DCHECK(parent_context.tree_builder_context);
-        tree_builder_context.emplace(*parent_context.tree_builder_context);
-      }
-#if DCHECK_IS_ON()
-      if (needs_tree_builder_context)
-        DCHECK(parent_context.tree_builder_context->is_actually_needed);
-      tree_builder_context->is_actually_needed = needs_tree_builder_context;
-#endif
-    }
-
-    absl::optional<PaintPropertyTreeBuilderContext> tree_builder_context;
-
     PaintInvalidatorContext paint_invalidator_context;
 
-    bool NeedsTreeBuilderContext() const {
-#if DCHECK_IS_ON()
-      DCHECK(tree_builder_context);
-      return tree_builder_context->is_actually_needed;
-#else
-      return tree_builder_context.has_value();
-#endif
-    }
-
     // The ancestor in the PaintLayer tree which is a scroll container. Note
     // that it is tree ancestor, not containing block or stacking ancestor.
     PaintLayer* ancestor_scroll_container_paint_layer = nullptr;
@@ -110,6 +73,37 @@
         paint_invalidation_container_for_stacked_contents = nullptr;
   };
 
+  struct PrePaintTreeWalkContext : public PrePaintTreeWalkContextBase {
+    PrePaintTreeWalkContext() { tree_builder_context.emplace(); }
+    PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context,
+                            bool needs_tree_builder_context)
+        : PrePaintTreeWalkContextBase(parent_context) {
+      if (needs_tree_builder_context || DCHECK_IS_ON()) {
+        DCHECK(parent_context.tree_builder_context);
+        tree_builder_context.emplace(*parent_context.tree_builder_context);
+      }
+#if DCHECK_IS_ON()
+      if (needs_tree_builder_context)
+        DCHECK(parent_context.tree_builder_context->is_actually_needed);
+      tree_builder_context->is_actually_needed = needs_tree_builder_context;
+#endif
+    }
+
+    PrePaintTreeWalkContext(const PrePaintTreeWalkContext&) = delete;
+    PrePaintTreeWalkContext& operator=(const PrePaintTreeWalkContext&) = delete;
+
+    bool NeedsTreeBuilderContext() const {
+#if DCHECK_IS_ON()
+      DCHECK(tree_builder_context);
+      return tree_builder_context->is_actually_needed;
+#else
+      return tree_builder_context.has_value();
+#endif
+    }
+
+    absl::optional<PaintPropertyTreeBuilderContext> tree_builder_context;
+  };
+
   static bool ContextRequiresChildPrePaint(const PrePaintTreeWalkContext&);
   static bool ContextRequiresChildTreeBuilderContext(
       const PrePaintTreeWalkContext&);
diff --git a/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
index c7bc87a..c1a73e1 100644
--- a/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
+++ b/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// This is only used when the new C++ implementation is enabled.
-
 // https://streams.spec.whatwg.org/#ws-default-controller-class-definition
+[
+    Exposed=(Window,Worker,Worklet)
+]
 interface WritableStreamDefaultController {
     [CallWith=ScriptState] void error(optional any e);
 };
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni
index 69c290a0..667c628 100644
--- a/third_party/blink/renderer/core/style/build.gni
+++ b/third_party/blink/renderer/core/style/build.gni
@@ -60,6 +60,8 @@
   "shape_clip_path_operation.h",
   "shape_value.h",
   "style_aspect_ratio.h",
+  "style_base_data.h",
+  "style_base_data.cc",
   "style_cached_data.h",
   "style_content_alignment_data.h",
   "style_crossfade_image.cc",
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 0c3f385..0aab0ada 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -106,8 +106,8 @@
   }
 
  private:
-  void* data_refs[9];
-  unsigned bitfields[6];
+  void* data_refs[8];
+  unsigned bitfields[5];
 };
 
 struct SameSizeAsComputedStyle : public SameSizeAsComputedStyleBase,
@@ -370,8 +370,11 @@
 void ComputedStyle::PropagateIndependentInheritedProperties(
     const ComputedStyle& parent_style) {
   ComputedStyleBase::PropagateIndependentInheritedProperties(parent_style);
-  if (!HasVariableReference() && !HasVariableDeclaration())
-    InheritCustomPropertiesFrom(parent_style);
+  if (!HasVariableReference() && !HasVariableDeclaration() &&
+      (InheritedVariables() != parent_style.InheritedVariables())) {
+    MutableInheritedVariablesInternal() =
+        parent_style.InheritedVariablesInternal();
+  }
 }
 
 StyleSelfAlignmentData ResolvedSelfAlignment(
@@ -591,6 +594,18 @@
     cached_data_->pseudo_element_styles_->clear();
 }
 
+const ComputedStyle* ComputedStyle::GetBaseComputedStyle() const {
+  if (auto* base_data = BaseData().get())
+    return base_data->GetBaseComputedStyle();
+  return nullptr;
+}
+
+const CSSBitset* ComputedStyle::GetBaseImportantSet() const {
+  if (auto* base_data = BaseData().get())
+    return base_data->GetBaseImportantSet();
+  return nullptr;
+}
+
 bool ComputedStyle::InheritedEqual(const ComputedStyle& other) const {
   return IndependentInheritedEqual(other) &&
          NonIndependentInheritedEqual(other);
@@ -2099,6 +2114,9 @@
 }
 
 void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
+  if (TextAutosizingMultiplier() == multiplier)
+    return;
+
   SetTextAutosizingMultiplierInternal(multiplier);
 
   float size = SpecifiedFontSize();
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 8273271..eea8a243 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -31,6 +31,7 @@
 #include "base/types/pass_key.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
+#include "third_party/blink/renderer/core/css/properties/css_bitset.h"
 #include "third_party/blink/renderer/core/css/properties/css_property.h"
 #include "third_party/blink/renderer/core/css/style_auto_color.h"
 #include "third_party/blink/renderer/core/css/style_color.h"
@@ -396,6 +397,22 @@
       scoped_refptr<const ComputedStyle>) const;
   void ClearCachedPseudoElementStyles() const;
 
+  // If this ComputedStyle is affected by animation/transitions, then the
+  // unanimated "base" style can be retrieved with this function.
+  //
+  // If this function returns nullptr, then this ComputedStyle is not
+  // affected by animations, and *is* the base style.
+  CORE_EXPORT const ComputedStyle* GetBaseComputedStyle() const;
+
+  // Indicates which properties are !important in the base style.
+  CORE_EXPORT const CSSBitset* GetBaseImportantSet() const;
+
+  CORE_EXPORT const ComputedStyle* GetBaseComputedStyleOrThis() const {
+    if (auto* base = GetBaseComputedStyle())
+      return base;
+    return this;
+  }
+
   /**
    * ComputedStyle properties
    *
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
index b1fced4..e7ed32a 100644
--- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
+++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -88,6 +88,7 @@
     {
       name: "InForcedColorsMode",
       field_template: "primitive",
+      field_group: "inherited",
       default_value: "false",
       type_name: "bool",
       inherited: true,
@@ -499,7 +500,7 @@
       include_paths: ["third_party/blink/renderer/core/style/style_inherited_variables.h"],
       default_value: "nullptr",
       wrapper_pointer_name: "scoped_refptr",
-      field_group: "InheritedVariables",
+      field_group: "inherited",
       computed_style_custom_functions: ["getter", "setter"],
     },
     {
@@ -759,7 +760,7 @@
       name: "HasAutoColumnWidth",
       field_template: "primitive",
       type_name: "bool",
-      field_group: "*->multi-col",
+      field_group: "*",
       default_value: "true",
       computed_style_custom_functions: ["setter"],
     },
@@ -767,7 +768,7 @@
       name: "HasAutoColumnCount",
       field_template: "primitive",
       type_name: "bool",
-      field_group: "*->multi-col",
+      field_group: "*",
       default_value: "true",
       computed_style_custom_functions: ["setter"],
     },
@@ -933,12 +934,14 @@
     {
       name: "MayHaveMargin",
       field_template: "monotonic_flag",
+      field_group: "surround",
       default_value: "false",
       custom_compare: true,
     },
     {
       name: "MayHavePadding",
       field_template: "monotonic_flag",
+      field_group: "surround",
       default_value: "false",
       custom_compare: true,
     },
@@ -1007,7 +1010,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathBaseline",
     },
     {
@@ -1016,7 +1019,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathFractionBarThickness",
     },
     {
@@ -1025,7 +1028,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathLSpace",
     },
     {
@@ -1034,7 +1037,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathRSpace",
     },
     {
@@ -1043,7 +1046,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathPaddedVOffset",
     },
     {
@@ -1052,17 +1055,16 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathPaddedDepth",
     },
-
     {
       name: "MathMinSize",
       field_template: "external",
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathMinSize",
     },
     {
@@ -1071,7 +1073,7 @@
       default_value: "Length()",
       include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
       type_name: "Length",
-      field_group: "*",
+      field_group: "*->math",
       getter: "GetMathMaxSize",
     },
     {
@@ -1111,5 +1113,17 @@
       field_group: "*",
       default_value: "false",
     },
+    {
+      name: "BaseData",
+      inherited: false,
+      field_group: "*",
+      field_template: "external",
+      type_name: "StyleBaseData",
+      include_paths: ["third_party/blink/renderer/core/style/style_base_data.h"],
+      default_value: "nullptr",
+      wrapper_pointer_name: "scoped_refptr",
+      custom_compare: true,
+      custom_copy: true,
+    },
   ],
 }
diff --git a/third_party/blink/renderer/core/style/style_base_data.cc b/third_party/blink/renderer/core/style/style_base_data.cc
new file mode 100644
index 0000000..476b3a4
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_base_data.cc
@@ -0,0 +1,14 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/style_base_data.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+StyleBaseData::StyleBaseData(scoped_refptr<const ComputedStyle> style,
+                             std::unique_ptr<CSSBitset> set)
+    : computed_style_(style), important_set_(std::move(set)) {}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_base_data.h b/third_party/blink/renderer/core/style/style_base_data.h
new file mode 100644
index 0000000..eb547b19
--- /dev/null
+++ b/third_party/blink/renderer/core/style/style_base_data.h
@@ -0,0 +1,54 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_BASE_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_BASE_DATA_H_
+
+#include "third_party/blink/renderer/core/css/properties/css_bitset.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+
+namespace blink {
+
+class ComputedStyle;
+
+class CORE_EXPORT StyleBaseData : public RefCounted<StyleBaseData> {
+  USING_FAST_MALLOC(StyleBaseData);
+
+ public:
+  static scoped_refptr<StyleBaseData> Create(
+      scoped_refptr<const ComputedStyle> style,
+      std::unique_ptr<CSSBitset> important_set) {
+    return base::AdoptRef(new StyleBaseData(style, std::move(important_set)));
+  }
+
+  const ComputedStyle* GetBaseComputedStyle() const {
+    return computed_style_.get();
+  }
+  const CSSBitset* GetBaseImportantSet() const { return important_set_.get(); }
+
+ private:
+  StyleBaseData(scoped_refptr<const ComputedStyle>, std::unique_ptr<CSSBitset>);
+
+  scoped_refptr<const ComputedStyle> computed_style_;
+
+  // Keeps track of the !important declarations used to build the base
+  // computed style. These declarations must not be overwritten by animation
+  // effects, hence we have to disable the base computed style optimization when
+  // !important declarations conflict with active animations.
+  //
+  // If there were no !important declarations in the base style, this field
+  // will be nullptr.
+  //
+  // TODO(andruud): We should be able to simply skip applying the animation
+  // for properties in this set instead of disabling the optimization.
+  // However, we currently need the cascade to handle the case where
+  // an !important declaration appears in a :visited selector.
+  // See https://crbug.com/1062217.
+  std::unique_ptr<CSSBitset> important_set_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_BASE_DATA_H_
diff --git a/third_party/blink/renderer/core/style/style_crossfade_image.cc b/third_party/blink/renderer/core/style/style_crossfade_image.cc
index 602f840..e625580 100644
--- a/third_party/blink/renderer/core/style/style_crossfade_image.cc
+++ b/third_party/blink/renderer/core/style/style_crossfade_image.cc
@@ -17,14 +17,12 @@
   is_crossfade_ = true;
 }
 
-StyleCrossfadeImage::~StyleCrossfadeImage() {
-  DCHECK(clients_.IsEmpty());
-}
+StyleCrossfadeImage::~StyleCrossfadeImage() = default;
 
 bool StyleCrossfadeImage::IsEqual(const StyleImage& other) const {
-  // Since this object is used as a listener, and contains a listener set, we
-  // need to consider each instance unique.
-  return this == &other;
+  if (!other.IsCrossfadeImage())
+    return false;
+  return original_value_ == To<StyleCrossfadeImage>(other).original_value_;
 }
 
 CSSValue* StyleCrossfadeImage::CssValue() const {
@@ -98,24 +96,26 @@
 }
 
 void StyleCrossfadeImage::AddClient(ImageResourceObserver* observer) {
-  const bool clients_was_empty = clients_.IsEmpty();
-  clients_.insert(observer);
-  if (!clients_was_empty)
+  const bool had_clients = original_value_->HasClients();
+  original_value_->AddClient(observer);
+  if (had_clients)
     return;
+  ImageResourceObserver* proxy_observer = original_value_->GetObserverProxy();
   if (from_image_)
-    from_image_->AddClient(this);
+    from_image_->AddClient(proxy_observer);
   if (to_image_)
-    to_image_->AddClient(this);
+    to_image_->AddClient(proxy_observer);
 }
 
 void StyleCrossfadeImage::RemoveClient(ImageResourceObserver* observer) {
-  clients_.erase(observer);
-  if (!clients_.IsEmpty())
+  original_value_->RemoveClient(observer);
+  if (original_value_->HasClients())
     return;
+  ImageResourceObserver* proxy_observer = original_value_->GetObserverProxy();
   if (from_image_)
-    from_image_->RemoveClient(this);
+    from_image_->RemoveClient(proxy_observer);
   if (to_image_)
-    to_image_->RemoveClient(this);
+    to_image_->RemoveClient(proxy_observer);
 }
 
 scoped_refptr<Image> StyleCrossfadeImage::GetImage(
@@ -129,9 +129,11 @@
     return Image::NullImage();
   const FloatSize resolved_size =
       ImageSize(style.EffectiveZoom(), target_size, kRespectImageOrientation);
+  const ImageResourceObserver* proxy_observer =
+      original_value_->GetObserverProxy();
   return CrossfadeGeneratedImage::Create(
-      from_image_->GetImage(*this, document, style, target_size),
-      to_image_->GetImage(*this, document, style, target_size),
+      from_image_->GetImage(*proxy_observer, document, style, target_size),
+      to_image_->GetImage(*proxy_observer, document, style, target_size),
       original_value_->Percentage().GetFloatValue(), resolved_size);
 }
 
@@ -145,33 +147,6 @@
          to_image_ && to_image_->KnownToBeOpaque(document, style);
 }
 
-void StyleCrossfadeImage::ImageChanged(ImageResourceContent*,
-                                       CanDeferInvalidation defer) {
-  for (auto& entry : clients_)
-    entry.key->ImageChanged(Data(), defer);
-}
-
-bool StyleCrossfadeImage::WillRenderImage() {
-  for (auto& entry : clients_) {
-    if (entry.key->WillRenderImage())
-      return true;
-  }
-  return false;
-}
-
-bool StyleCrossfadeImage::GetImageAnimationPolicy(
-    mojom::blink::ImageAnimationPolicy& animation_policy) {
-  for (auto& entry : clients_) {
-    if (entry.key->GetImageAnimationPolicy(animation_policy))
-      return true;
-  }
-  return false;
-}
-
-String StyleCrossfadeImage::DebugName() const {
-  return "StyleCrossfadeImage";
-}
-
 void StyleCrossfadeImage::Trace(Visitor* visitor) const {
   visitor->Trace(original_value_);
   visitor->Trace(from_image_);
diff --git a/third_party/blink/renderer/core/style/style_crossfade_image.h b/third_party/blink/renderer/core/style/style_crossfade_image.h
index f9d47f9..dad4122 100644
--- a/third_party/blink/renderer/core/style/style_crossfade_image.h
+++ b/third_party/blink/renderer/core/style/style_crossfade_image.h
@@ -5,7 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_CROSSFADE_IMAGE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_CROSSFADE_IMAGE_H_
 
-#include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
 #include "third_party/blink/renderer/core/style/style_image.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 
@@ -16,8 +15,7 @@
 }
 
 // This class represents a <cross-fade()> <image> function.
-class StyleCrossfadeImage final : public StyleImage,
-                                  public ImageResourceObserver {
+class StyleCrossfadeImage final : public StyleImage {
  public:
   StyleCrossfadeImage(cssvalue::CSSCrossfadeValue&,
                       StyleImage* from_image,
@@ -55,13 +53,6 @@
  private:
   bool IsEqual(const StyleImage&) const override;
 
-  // ImageResourceObserver:
-  void ImageChanged(ImageResourceContent*, CanDeferInvalidation) override;
-  bool WillRenderImage() override;
-  bool GetImageAnimationPolicy(mojom::blink::ImageAnimationPolicy&) override;
-  String DebugName() const override;
-
-  HashCountedSet<ImageResourceObserver*> clients_;
   Member<cssvalue::CSSCrossfadeValue> original_value_;
   Member<StyleImage> from_image_;
   Member<StyleImage> to_image_;
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 83035084..c808f20 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -323,6 +323,15 @@
 v8::Local<v8::String> XMLHttpRequest::ResponseJSONSource() {
   DCHECK_EQ(response_type_code_, kResponseTypeJSON);
 
+  const auto& head = response_body_head_;
+  if (state_ == kDone && !error_ && head.size() >= 2) {
+    if ((head[0] == 0xfe && head[1] == 0xff) ||
+        (head[0] == 0xff && head[1] == 0xfe)) {
+      Deprecation::CountDeprecation(GetExecutionContext(),
+                                    WebFeature::kXHRJSONEncodingDetection);
+    }
+  }
+
   if (error_ || state_ != kDone)
     return v8::Local<v8::String>();
   return response_text_.V8Value(isolate_);
@@ -1720,13 +1729,6 @@
   if (decoder_) {
     auto text = decoder_->Flush();
 
-    if (response_type_code_ == kResponseTypeJSON) {
-      // See https://crbug.com/1189627: We want to deprecate the BOM sniffing.
-      if (decoder_->Encoding() != UTF8Encoding()) {
-        GetExecutionContext()->CountUse(WebFeature::kXHRJSONEncodingDetection);
-      }
-    }
-
     if (!text.IsEmpty() && !response_text_overflow_) {
       response_text_.Concat(isolate_, text);
       response_text_overflow_ = response_text_.IsEmpty();
@@ -1848,11 +1850,9 @@
 }
 
 std::unique_ptr<TextResourceDecoder> XMLHttpRequest::CreateDecoder() const {
-  const TextResourceDecoderOptions decoder_options_for_utf8_plain_text(
-      TextResourceDecoderOptions::kPlainTextContent, UTF8Encoding());
   if (response_type_code_ == kResponseTypeJSON) {
-    return std::make_unique<TextResourceDecoder>(
-        decoder_options_for_utf8_plain_text);
+    return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
+        TextResourceDecoderOptions::CreateUTF8Decode()));
   }
 
   WTF::TextEncoding final_response_charset = FinalResponseCharset();
@@ -1876,8 +1876,9 @@
         return std::make_unique<TextResourceDecoder>(decoder_options_for_xml);
       FALLTHROUGH;
     case kResponseTypeText:
-      return std::make_unique<TextResourceDecoder>(
-          decoder_options_for_utf8_plain_text);
+      return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
+          TextResourceDecoderOptions::kPlainTextContent, UTF8Encoding()));
+
     case kResponseTypeDocument:
       if (ResponseIsHTML()) {
         return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
@@ -1912,6 +1913,13 @@
   if (!len)
     return;
 
+  // Store the first few bytes of the response body so that we can check the BOM
+  // later.
+  for (wtf_size_t i = 0;
+       i < len && response_body_head_.size() < kResponseBodyHeadSize; ++i) {
+    response_body_head_.push_back(static_cast<uint8_t>(data[i]));
+  }
+
   if (response_type_code_ == kResponseTypeDocument && ResponseIsHTML()) {
     ParseDocumentChunk(data, len);
   } else if (response_type_code_ == kResponseTypeDefault ||
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
index f925d68..7e6ec5a 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h
@@ -315,6 +315,10 @@
 
   std::unique_ptr<TextResourceDecoder> decoder_;
 
+  // TODO(crbug.com/1226775): Remove these on M96.
+  static constexpr size_t kResponseBodyHeadSize = 2;
+  Vector<uint8_t, kResponseBodyHeadSize> response_body_head_;
+
   // Avoid using a flat WTF::String here and rather use a traced v8::String
   // which internally builds a string rope.
   TraceWrapperV8String response_text_;
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn
index 8cae1fb..f6e59cf 100644
--- a/third_party/blink/renderer/modules/BUILD.gn
+++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -9,7 +9,6 @@
 import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
 import("//third_party/blink/renderer/build/scripts/scripts.gni")
 import("//third_party/blink/renderer/modules/modules.gni")
-import("//third_party/blink/renderer/modules/modules_idl_files.gni")
 import("//third_party/webrtc/webrtc.gni")
 
 if (is_android) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_media_element.cc b/third_party/blink/renderer/modules/accessibility/ax_media_element.cc
index 482f14b3..4715a48 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_media_element.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_media_element.cc
@@ -61,24 +61,6 @@
   return AXNodeObject::Restriction();
 }
 
-bool AccessibilityMediaElement::HasControls() const {
-  if (IsDetached())
-    return false;
-  if (!IsA<HTMLMediaElement>(GetNode()) || !GetNode()->isConnected()) {
-    NOTREACHED() << "Accessible media element not ready: " << GetNode()
-                 << "  isConnected? " << GetNode()->isConnected();
-    return false;
-  }
-  return To<HTMLMediaElement>(GetNode())->ShouldShowControls();
-}
-
-bool AccessibilityMediaElement::HasEmptySource() const {
-  if (IsDetached())
-    return false;
-  return To<HTMLMediaElement>(GetNode())->getNetworkState() ==
-         HTMLMediaElement::kNetworkEmpty;
-}
-
 bool AccessibilityMediaElement::IsUnplayable() const {
   if (IsDetached())
     return true;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_media_element.h b/third_party/blink/renderer/modules/accessibility/ax_media_element.h
index afa2cea7..e58ceb9 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_media_element.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_media_element.h
@@ -34,8 +34,6 @@
   AXRestriction Restriction() const override;
 
  protected:
-  bool HasControls() const;
-  bool HasEmptySource() const;
   bool IsUnplayable() const;
 
   DISALLOW_COPY_AND_ASSIGN(AccessibilityMediaElement);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 9424437..0d164be0 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -67,6 +67,7 @@
 #include "third_party/blink/renderer/core/html/html_table_row_element.h"
 #include "third_party/blink/renderer/core/html/html_table_section_element.h"
 #include "third_party/blink/renderer/core/html/html_title_element.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
 #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
@@ -2478,6 +2479,14 @@
       return true;
   }
 
+  // The ignored state of media controls can change without a layout update.
+  // Keep them in the tree at all times so that the serializer isn't
+  // accidentally working with unincluded nodes, which is not allowed.
+  if (node->IsInUserAgentShadowRoot() &&
+      IsA<HTMLMediaElement>(node->OwnerShadowHost())) {
+    return true;
+  }
+
   Element* element = GetElement();
   if (!element)
     return false;
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 289fb858..4ea0187 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
@@ -1115,7 +1115,6 @@
   DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id));
   node_object_mapping_.Set(node, ax_id);
   new_obj->Init(parent);
-  MaybeNewRelationTarget(*node, new_obj);
 
   return new_obj;
 }
@@ -1233,8 +1232,6 @@
   const AXID axid = AssociateAXID(new_obj, use_axid);
   layout_object_mapping_.Set(layout_object, axid);
   new_obj->Init(parent);
-  if (node)  // There may not be a node, e.g. for an anonymous block.
-    MaybeNewRelationTarget(*node, new_obj);
 
   return new_obj;
 }
@@ -2891,6 +2888,8 @@
     HandleUseMapAttributeChangedWithCleanLayout(element);
   } else if (attr_name == html_names::kNameAttr) {
     HandleNameAttributeChangedWithCleanLayout(element);
+  } else if (attr_name == html_names::kControlsAttr) {
+    ChildrenChangedWithCleanLayout(element);
   }
 
   if (!attr_name.LocalName().StartsWith("aria-"))
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 b024f34..d6ff495 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
@@ -264,6 +264,7 @@
   // Counts the number of times the document has been modified. Some attribute
   // values are cached as long as the modification count hasn't changed.
   int ModificationCount() const { return modification_count_; }
+  void IncrementModificationCount() { ++modification_count_; }
 
   void PostNotification(const LayoutObject*, ax::mojom::blink::Event);
   // Creates object if necessary.
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 042fe47..bd8e155 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -166,8 +166,11 @@
 }
 
 void AXRelationCache::UnmapOwnedChildren(const AXObject* owner,
-                                         const Vector<AXID> child_ids) {
-  for (AXID removed_child_id : child_ids) {
+                                         const Vector<AXID>& removed_child_ids,
+                                         const Vector<AXID>& newly_owned_ids) {
+  DCHECK(owner);
+  DCHECK(!owner->IsDetached());
+  for (AXID removed_child_id : removed_child_ids) {
     // Find the AXObject for the child that this owner no longer owns.
     AXObject* removed_child = ObjectFromAXID(removed_child_id);
 
@@ -186,16 +189,28 @@
       // parent and calling childrenChanged on its real parent.
       removed_child->DetachFromParent();
       // Recompute the real parent and cache it.
-      if (AXObject* real_parent = RestoreParentOrPrune(removed_child))
-        ChildrenChanged(real_parent);
+      // Don't do this if it's also in the newly owned ids, as it's about to
+      // get a new parent, and we want to avoid accidentally pruning it.
+      if (!newly_owned_ids.Contains(removed_child_id)) {
+        if (AXObject* real_parent = RestoreParentOrPrune(removed_child))
+          ChildrenChanged(real_parent);
+        // Now that the child is not owned, it's "included in tree" state must
+        // be recomputed because while owned children are always included in the
+        // tree, unowned children may not be included.
+        removed_child->UpdateCachedAttributeValuesIfNeeded(false);
+      }
     }
   }
 }
 
 void AXRelationCache::MapOwnedChildren(const AXObject* owner,
-                                       const Vector<AXID> child_ids) {
+                                       const Vector<AXID>& child_ids) {
+  DCHECK(owner);
+  DCHECK(!owner->IsDetached());
   for (AXID added_child_id : child_ids) {
     AXObject* added_child = ObjectFromAXID(added_child_id);
+    DCHECK(added_child);
+    DCHECK(!added_child->IsDetached());
 
     // Add this child to the mapping from child to owner.
     aria_owned_child_to_owner_mapping_.Set(added_child_id, owner->AXObjectID());
@@ -209,6 +224,9 @@
       if (original_parent)
         ChildrenChanged(original_parent);
     }
+    // Now that the child is owned, it's "included in tree" state must be
+    // recomputed because owned children are always included in the tree.
+    added_child->UpdateCachedAttributeValuesIfNeeded(false);
   }
 }
 
@@ -342,20 +360,26 @@
 
   // Compare this to the current list of owned children, and exit early if
   // there are no changes.
-  Vector<AXID> current_child_axids =
+  Vector<AXID> previously_owned_child_ids =
       aria_owner_to_children_mapping_.at(owner->AXObjectID());
 
   // Only force the refresh if there was or will be owned children; otherwise,
   // there is nothing to refresh even for a new AXObject replacing an old owner.
-  if (current_child_axids == validated_owned_child_axids &&
-      (!force || current_child_axids.IsEmpty())) {
+  if (previously_owned_child_ids == validated_owned_child_axids &&
+      (!force || previously_owned_child_ids.IsEmpty())) {
     return;
   }
 
+  // Incrementing the modification count ensures that cached "included in tree"
+  // state is recomputed on objects with changed ownership -- owned children
+  // must always be included in the tree.
+  object_cache_->IncrementModificationCount();
+
   // The list of owned children has changed. Even if they were just reordered,
   // to be safe and handle all cases we remove all of the current owned
   // children and add the new list of owned children.
-  UnmapOwnedChildren(owner, current_child_axids);
+  UnmapOwnedChildren(owner, previously_owned_child_ids,
+                     validated_owned_child_axids);
   MapOwnedChildren(owner, validated_owned_child_axids);
 
 #if DCHECK_IS_ON()
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 f5c5d3d..5d00269 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -107,8 +107,11 @@
   void UpdateRelatedText(Node*);
 
   bool IsValidOwnsRelation(AXObject* owner, AXObject* child) const;
-  void UnmapOwnedChildren(const AXObject* owner, Vector<AXID>);
-  void MapOwnedChildren(const AXObject* owner, Vector<AXID>);
+  void UnmapOwnedChildren(const AXObject* owner,
+                          const Vector<AXID>& removed_child_ids,
+                          const Vector<AXID>& newly_owned_ids);
+
+  void MapOwnedChildren(const AXObject* owner, const Vector<AXID>&);
   void GetReverseRelated(Node*, HeapVector<Member<AXObject>>& sources);
 
   // Set the parent of |child| to its natural parent, without any aria-owns.
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
index 1ebbd11..cc4c1e8e 100644
--- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
+++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc
@@ -10,7 +10,6 @@
 #include "third_party/blink/renderer/core/events/pointer_event.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/visual_viewport.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
 #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
@@ -33,48 +32,39 @@
                                                        LocalFrame* frame)
     : presentation_area_(element), local_frame_(frame) {}
 
-void ThrowException(v8::Isolate* isolate,
-                    ExceptionCode code,
-                    const String& error_message) {
-  ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
-                                 "DelegatedInkTrailPresenter",
-                                 "updateInkTrailStatePoint");
-  exception_state.ThrowException(code, error_message);
-}
-
 void DelegatedInkTrailPresenter::updateInkTrailStartPoint(
     ScriptState* state,
     PointerEvent* evt,
-    InkTrailStyle* style) {
+    InkTrailStyle* style,
+    ExceptionState& exception_state) {
   DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled());
 
   if (!state->ContextIsValid()) {
-    ThrowException(state->GetIsolate(),
-                   ToExceptionCode(DOMExceptionCode::kInvalidStateError),
-                   "The object is no longer associated with a window.");
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kInvalidStateError,
+        "The object is no longer associated with a window.");
     return;
   }
 
   if (!evt->isTrusted()) {
-    ThrowException(state->GetIsolate(),
-                   ToExceptionCode(DOMExceptionCode::kNotAllowedError),
-                   "Only trusted pointerevents are accepted.");
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kNotAllowedError,
+        "Only trusted pointerevents are accepted.");
     return;
   }
 
   // If diameter is less than or equal to 0, then nothing is going to be
   // displayed anyway, so just bail early and save the effort.
-  if (style->diameter() <= 0) {
-    ThrowException(state->GetIsolate(),
-                   ToExceptionCode(DOMExceptionCode::kNotSupportedError),
-                   "Delegated ink trail diameter must be greater than 0.");
+  if (!(style->diameter() > 0)) {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kNotSupportedError,
+        "Delegated ink trail diameter must be greater than 0.");
     return;
   }
 
   Color color;
   if (!CSSParser::ParseColor(color, style->color(), true /*strict*/)) {
-    ThrowException(state->GetIsolate(),
-                   ToExceptionCode(ESErrorType::kTypeError), "Unknown color.");
+    exception_state.ThrowTypeError("Unknown color.");
     return;
   }
 
@@ -86,8 +76,7 @@
   physical_point.Scale(effective_zoom);
   physical_point = layout_view->LocalToAbsolutePoint(
       physical_point, kTraverseDocumentBoundaries);
-  gfx::PointF point(physical_point.left.ToFloat(),
-                    physical_point.top.ToFloat());
+  gfx::PointF point = FloatPoint(physical_point);
 
   LayoutBox* layout_box = nullptr;
   if (presentation_area_) {
@@ -128,10 +117,7 @@
   border_box_rect_absolute.Intersect(PhysicalRect(
       local_frame_->GetPage()->GetVisualViewport().VisibleContentRect()));
 
-  gfx::RectF area(border_box_rect_absolute.X().ToFloat(),
-                  border_box_rect_absolute.Y().ToFloat(),
-                  border_box_rect_absolute.Width().ToFloat(),
-                  border_box_rect_absolute.Height().ToFloat());
+  gfx::RectF area = FloatRect(border_box_rect_absolute);
 
   // This is used to know if the user starts inking with the pointer down or
   // not, so that we can stop drawing delegated ink trails as quickly as
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
index 439a57f..1d7d05f 100644
--- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
+++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h
@@ -11,6 +11,7 @@
 namespace blink {
 
 class Element;
+class ExceptionState;
 class InkTrailStyle;
 class LocalFrame;
 class PointerEvent;
@@ -33,7 +34,8 @@
   DelegatedInkTrailPresenter(Element* element, LocalFrame* frame);
   void updateInkTrailStartPoint(ScriptState* state,
                                 PointerEvent* evt,
-                                InkTrailStyle* style);
+                                InkTrailStyle* style,
+                                ExceptionState& exception_state);
   uint32_t expectedImprovement() const { return expected_improvement_; }
   Element* presentationArea() const { return presentation_area_; }
 
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
index d0f2b65..1aa54b7a 100644
--- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
+++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl
@@ -8,8 +8,8 @@
     RuntimeEnabled=DelegatedInkTrails,
     Exposed=Window
 ] interface DelegatedInkTrailPresenter {
-    [CallWith=ScriptState] void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style);
+    [CallWith=ScriptState, RaisesException] void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style);
 
     readonly attribute Element? presentationArea;
     readonly attribute unsigned long expectedImprovement;
-};
\ No newline at end of file
+};
diff --git a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
index 1e7c3d5..4570b77 100644
--- a/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
+++ b/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc
@@ -172,10 +172,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorBLUE);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(100, 100);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(GetDocument().GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ true), &style, exception_state);
   expected_metadata.SetHovering(true);
   expected_metadata.SetPoint(pt);
 
@@ -233,10 +234,11 @@
   expected_metadata.SetDiameter(style.diameter() * kZoom);
   expected_metadata.SetColor(SK_ColorMAGENTA);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(87, 113);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(GetDocument().GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ true), &style, exception_state);
   expected_metadata.SetHovering(true);
   pt.Scale(kZoom);
   expected_metadata.SetPoint(pt);
@@ -298,10 +300,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorRED);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(380, 175);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(GetDocument().GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ false), &style, exception_state);
   expected_metadata.SetHovering(false);
   expected_metadata.SetPoint(pt);
 
@@ -397,10 +400,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorCYAN);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(380, 375);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ false), &style, exception_state);
   expected_metadata.SetHovering(false);
   expected_metadata.SetPoint(
       gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
@@ -524,10 +528,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorYELLOW);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(350, 375);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ true), &style, exception_state);
   expected_metadata.SetHovering(true);
   expected_metadata.SetPoint(gfx::PointF(pt.x() + kInnerIframeLeftOffset,
                                          pt.y() + kInnerIframeTopOffset));
@@ -608,10 +613,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorWHITE);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(380, 375);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ true), &style, exception_state);
   expected_metadata.SetHovering(true);
   expected_metadata.SetPoint(
       gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
@@ -643,10 +649,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorYELLOW);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(70, 109);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(GetDocument().GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ false), &style, exception_state);
   expected_metadata.SetHovering(false);
   expected_metadata.SetPoint(pt);
 
@@ -728,10 +735,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorGREEN);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(102, 67);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ false), &style, exception_state);
   expected_metadata.SetHovering(false);
   expected_metadata.SetPoint(
       gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
@@ -819,10 +827,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorGREEN);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(102, 67);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ true), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ true), &style, exception_state);
   expected_metadata.SetHovering(true);
   expected_metadata.SetPoint(
       gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset));
@@ -941,10 +950,11 @@
   expected_metadata.SetDiameter(style.diameter());
   expected_metadata.SetColor(SK_ColorRED);
 
+  DummyExceptionStateForTesting exception_state;
   gfx::PointF pt(357, 401);
   presenter->updateInkTrailStartPoint(
       ToScriptStateForMainWorld(iframe_document->GetFrame()),
-      CreatePointerMoveEvent(pt, /*hovering*/ false), &style);
+      CreatePointerMoveEvent(pt, /*hovering*/ false), &style, exception_state);
   expected_metadata.SetHovering(false);
   expected_metadata.SetPoint(gfx::PointF(pt.x() + kInnerIframeLeftOffset,
                                          pt.y() + kInnerIframeTopOffset));
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
index aa352a0..f56afee2 100644
--- a/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "media/base/audio_sample_types.h"
 #include "media/base/audio_timestamp_helper.h"
 
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc
index 5e2131e3b..3b74195 100644
--- a/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc
@@ -4,8 +4,8 @@
 
 #include "third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.h"
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
-#include "base/stl_util.h"
 #include "media/base/audio_sample_types.h"
 #include "media/base/audio_timestamp_helper.h"
 
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
deleted file mode 100644
index 326751f1..0000000
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//third_party/blink/renderer/bindings/bindings.gni")
-import("//third_party/blink/renderer/config.gni")
-
-# The paths in this file are absolute since this file is imported and the
-# file lists must be valid from multiple "current directories".
-
-# IDL files for a module are defined by idls.gni in the module's corresponding
-# directory. idls.gni can define certain variables to add additional IDL files
-# to the build.
-#
-#   modules_idl_files = [
-#     # IDL files that don't fit in one of the below categories. Typically
-#     # (but not required to) defines interfaces.
-#     # Spec reference: https://heycam.github.io/webidl/#idl-interfaces
-#   ]
-#
-#   modules_callback_function_idl_files = [
-#     # IDL files that only define callback functions (note: these are distinct
-#     # from callback interfaces).
-#     # Spec reference: https://heycam.github.io/webidl/#dfn-callback-function).
-#     # TODO(dcheng): Figure out why this is its own category.
-#   ]
-#
-#   modules_dictionary_idl_files = [
-#     # IDL files that define dictionaries and any supporting types (such as
-#     # enums) for the dictionaries.
-#     # Spec reference: https://heycam.github.io/webidl/#idl-dictionaries
-#   ]
-#
-#   modules_dependency_idl_files = [
-#     # IDL files that either define partial interfaces or target (right side
-#     # of) `includes`.
-#     # Spec reference: https://heycam.github.io/webidl/#dfn-partial-interface
-#     # Spec reference: https://heycam.github.io/webidl/#idl-interface-mixins
-#   ]
-#
-#   modules_testing_dependency_idl_files = [
-#     # Similar to |modules_dependency_idl_files| but limited to things that are
-#     # exposed only for testing.
-#   ]
-#
-#   modules_typedefs_enums_only_idl_files = [
-#     # IDL files that only have typedefs/enums.
-#   ]
-_idl_imports = []
-
-# Do not add IDL files directly to these lists. See _idl_imports above instead
-# on how to add IDL files for a module.
-modules_idl_files =
-    get_path_info(
-        [
-          # This variable is effectively no longer used, but it's not easy to
-          # remove this or make this empty.  So, put a dummy entry for the time
-          # being.  The file doesn't make any sense.
-          # TODO(yukishiino): Remove the build settings of the old bindings
-          # generator entirely.
-          "//third_party/blink/renderer/core/dom/common_definitions.idl",
-        ],
-        "abspath")
-modules_callback_function_idl_files = []
-modules_dictionary_idl_files = []
-modules_dependency_idl_files = []
-modules_testing_dependency_idl_files = []
-modules_typedefs_enums_only_idl_files = []
-
-foreach(idl_import, _idl_imports) {
-  # Avoid reassignment error by assigning to empty scope first.
-  _imported = {
-  }
-  _imported = read_file(idl_import, "scope")
-
-  # Paths are potentially relative to the location of the .gni. Rebase them
-  # relative to "." so get_path_info() works as expected.
-  gni_dir = get_path_info(idl_import, "dir")
-
-  if (defined(_imported.modules_idl_files)) {
-    modules_idl_files +=
-        get_path_info(rebase_path(_imported.modules_idl_files, ".", gni_dir),
-                      "abspath")
-  }
-
-  if (defined(_imported.modules_callback_function_idl_files)) {
-    modules_callback_function_idl_files +=
-        get_path_info(rebase_path(_imported.modules_callback_function_idl_files,
-                                  ".",
-                                  gni_dir),
-                      "abspath")
-  }
-
-  if (defined(_imported.modules_dictionary_idl_files)) {
-    modules_dictionary_idl_files +=
-        get_path_info(
-            rebase_path(_imported.modules_dictionary_idl_files, ".", gni_dir),
-            "abspath")
-  }
-
-  if (defined(_imported.modules_dependency_idl_files)) {
-    modules_dependency_idl_files +=
-        get_path_info(
-            rebase_path(_imported.modules_dependency_idl_files, ".", gni_dir),
-            "abspath")
-  }
-
-  if (defined(_imported.modules_testing_dependency_idl_files)) {
-    modules_testing_dependency_idl_files +=
-        get_path_info(
-            rebase_path(_imported.modules_testing_dependency_idl_files,
-                        ".",
-                        gni_dir),
-            "abspath")
-  }
-
-  if (defined(_imported.modules_typedefs_enums_only_idl_files)) {
-    modules_typedefs_enums_only_idl_files +=
-        get_path_info(
-            rebase_path(_imported.modules_typedefs_enums_only_idl_files,
-                        ".",
-                        gni_dir),
-            "abspath")
-  }
-}
-
-bindings_modules_output_dir = "$bindings_output_dir/modules"
-blink_modules_output_dir = "$root_gen_dir/third_party/blink/renderer/modules"
-
-modules_core_global_constructors_original_interfaces = [
-  "AnimationWorkletGlobalScope",
-  "AudioWorkletGlobalScope",
-  "PaintWorkletGlobalScope",
-  "ServiceWorkerGlobalScope",
-]
-
-# The size and the order in the following list must match to the previous one.
-modules_core_global_constructors_original_interface_basenames = [
-  "animation_worklet_global_scope",
-  "audio_worklet_global_scope",
-  "paint_worklet_global_scope",
-  "service_worker_global_scope",
-]
-
-modules_global_constructors_original_interfaces = [
-  "AnimationWorkletGlobalScope",
-  "AudioWorkletGlobalScope",
-  "DedicatedWorkerGlobalScope",
-  "PaintWorkletGlobalScope",
-  "ServiceWorkerGlobalScope",
-  "SharedWorkerGlobalScope",
-  "Window",
-]
-
-# The size and the order in the following list must match to the previous one.
-modules_global_constructors_original_interface_basenames = [
-  "animation_worklet_global_scope",
-  "audio_worklet_global_scope",
-  "dedicated_worker_global_scope",
-  "paint_worklet_global_scope",
-  "service_worker_global_scope",
-  "shared_worker_global_scope",
-  "window",
-]
-
-# The interfaces aren't technically files, but we can treat them as file names
-# to get process_file_template to generate lists of IDL files corresponding
-# to each interface.
-modules_core_global_constructors_generated_idl_files = process_file_template(
-        modules_core_global_constructors_original_interface_basenames,
-        [ "$blink_modules_output_dir/{{source_name_part}}_core_constructors.idl" ])
-modules_global_constructors_generated_idl_files = process_file_template(
-        modules_global_constructors_original_interface_basenames,
-        [ "$blink_modules_output_dir/{{source_name_part}}_modules_constructors.idl" ])
-
-modules_definition_idl_files = modules_dictionary_idl_files + modules_idl_files
-
-# Static IDL files
-modules_static_interface_idl_files =
-    modules_callback_function_idl_files + modules_typedefs_enums_only_idl_files
-
-modules_static_dependency_idl_files =
-    modules_dependency_idl_files + modules_testing_dependency_idl_files
-
-if (use_blink_v8_binding_new_idl_interface) {
-  modules_generated_dependency_idl_files = []
-} else {
-  modules_generated_dependency_idl_files =
-      modules_core_global_constructors_generated_idl_files +
-      modules_global_constructors_generated_idl_files
-}
-
-# 'modules_dependency_idl_files' is already used in Source/modules, so avoid
-# collision
-modules_all_dependency_idl_files =
-    modules_static_dependency_idl_files + modules_generated_dependency_idl_files
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
index d10c8fe..5656fa4e 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc
@@ -549,7 +549,7 @@
         list->Append(std::move(report).value());
     }
 
-    if (!list->empty()) {
+    if (!list->GetList().empty()) {
       PostCrossThreadTask(
           *main_thread_.get(), FROM_HERE,
           CrossThreadBindOnce(&InternalLegacyStatsObserver::OnCompleteImpl,
@@ -573,7 +573,7 @@
       std::unique_ptr<base::ListValue> list,
       int lid,
       CrossThreadOnceFunction<void(int, base::Value)> completion_callback) {
-    DCHECK(!list->empty());
+    DCHECK(!list->GetList().empty());
     std::move(completion_callback).Run(lid, std::move(*list.get()));
   }
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 2079f94a..b0d5daed 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -1267,23 +1267,26 @@
 void RTCPeerConnection::NoteCallSetupStateEventPending(
     RTCPeerConnection::SetSdpOperationType operation,
     const RTCSessionDescriptionInit& description) {
+  if (!description.hasType())
+    return;
+
   switch (operation) {
     case RTCPeerConnection::SetSdpOperationType::kSetLocalDescription:
-      if (description.type() == "offer") {
+      if (description.type() == V8RTCSdpType::Enum::kOffer) {
         call_setup_state_tracker_.NoteOffererStateEvent(
             OffererState::kSetLocalOfferPending, HasDocumentMedia());
-      } else if (description.type() == "answer" ||
-                 description.type() == "pranswer") {
+      } else if (description.type() == V8RTCSdpType::Enum::kAnswer ||
+                 description.type() == V8RTCSdpType::Enum::kPranswer) {
         call_setup_state_tracker_.NoteAnswererStateEvent(
             AnswererState::kSetLocalAnswerPending, HasDocumentMedia());
       }
       break;
     case RTCPeerConnection::SetSdpOperationType::kSetRemoteDescription:
-      if (description.type() == "offer") {
+      if (description.type() == V8RTCSdpType::Enum::kOffer) {
         call_setup_state_tracker_.NoteAnswererStateEvent(
             AnswererState::kSetRemoteOfferPending, HasDocumentMedia());
-      } else if (description.type() == "answer" ||
-                 description.type() == "pranswer") {
+      } else if (description.type() == V8RTCSdpType::Enum::kAnswer ||
+                 description.type() == V8RTCSdpType::Enum::kPranswer) {
         call_setup_state_tracker_.NoteOffererStateEvent(
             OffererState::kSetRemoteAnswerPending, HasDocumentMedia());
       }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index bf483ca5..039362c0 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -67,10 +67,12 @@
 }
 
 MediaStreamTrack* RTCRtpReceiver::track() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return track_;
 }
 
 RTCDtlsTransport* RTCRtpReceiver::transport() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return transport_;
 }
 
@@ -80,11 +82,13 @@
 }
 
 absl::optional<double> RTCRtpReceiver::playoutDelayHint() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return playout_delay_hint_;
 }
 
 void RTCRtpReceiver::setPlayoutDelayHint(absl::optional<double> hint,
                                          ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (hint.has_value() && hint.value() < 0.0) {
     exception_state.ThrowTypeError("playoutDelayHint can't be negative");
     return;
@@ -97,6 +101,7 @@
 HeapVector<Member<RTCRtpSynchronizationSource>>
 RTCRtpReceiver::getSynchronizationSources(ScriptState* script_state,
                                           ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!script_state->ContextIsValid()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
                                       "Window is detached");
@@ -139,6 +144,7 @@
 HeapVector<Member<RTCRtpContributingSource>>
 RTCRtpReceiver::getContributingSources(ScriptState* script_state,
                                        ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!script_state->ContextIsValid()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
                                       "Window is detached");
@@ -179,6 +185,7 @@
 }
 
 ScriptPromise RTCRtpReceiver::getStats(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   receiver_->GetStats(
@@ -190,6 +197,7 @@
 RTCInsertableStreams* RTCRtpReceiver::createEncodedStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (track_->kind() == "audio")
     return createEncodedAudioStreams(script_state, exception_state);
   DCHECK_EQ(track_->kind(), "video");
@@ -199,6 +207,7 @@
 RTCInsertableStreams* RTCRtpReceiver::createEncodedAudioStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!force_encoded_audio_insertable_streams_) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
@@ -218,6 +227,7 @@
 RTCInsertableStreams* RTCRtpReceiver::createEncodedVideoStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!force_encoded_video_insertable_streams_) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
@@ -235,26 +245,32 @@
 }
 
 RTCRtpReceiverPlatform* RTCRtpReceiver::platform_receiver() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return receiver_.get();
 }
 
 MediaStreamVector RTCRtpReceiver::streams() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return streams_;
 }
 
 void RTCRtpReceiver::set_streams(MediaStreamVector streams) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   streams_ = std::move(streams);
 }
 
 void RTCRtpReceiver::set_transceiver(RTCRtpTransceiver* transceiver) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   transceiver_ = transceiver;
 }
 
 void RTCRtpReceiver::set_transport(RTCDtlsTransport* transport) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   transport_ = transport;
 }
 
 void RTCRtpReceiver::UpdateSourcesIfNeeded() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!web_sources_needs_updating_)
     return;
   web_sources_ = receiver_->GetSources();
@@ -270,6 +286,7 @@
 }
 
 void RTCRtpReceiver::SetContributingSourcesNeedsUpdating() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   web_sources_needs_updating_ = true;
 }
 
@@ -350,6 +367,7 @@
 }
 
 RTCRtpReceiveParameters* RTCRtpReceiver::getParameters() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   RTCRtpReceiveParameters* parameters = RTCRtpReceiveParameters::Create();
   std::unique_ptr<webrtc::RtpParameters> webrtc_parameters =
       receiver_->GetParameters();
@@ -390,6 +408,7 @@
 }
 
 void RTCRtpReceiver::RegisterEncodedAudioStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!platform_receiver()
               ->GetEncodedAudioStreamTransformer()
               ->HasTransformerCallback());
@@ -402,6 +421,7 @@
 }
 
 void RTCRtpReceiver::UnregisterEncodedAudioStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_EQ(track_->kind(), "audio");
   platform_receiver()
       ->GetEncodedAudioStreamTransformer()
@@ -409,6 +429,7 @@
 }
 
 void RTCRtpReceiver::InitializeEncodedAudioStreams(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!encoded_audio_streams_);
   DCHECK(!audio_from_depacketizer_underlying_source_);
   DCHECK(!audio_to_decoder_underlying_sink_);
@@ -456,6 +477,7 @@
 
 void RTCRtpReceiver::OnAudioFrameFromDepacketizer(
     std::unique_ptr<webrtc::TransformableFrameInterface> encoded_audio_frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (audio_from_depacketizer_underlying_source_) {
     audio_from_depacketizer_underlying_source_->OnFrameFromSource(
         std::move(encoded_audio_frame));
@@ -463,6 +485,7 @@
 }
 
 void RTCRtpReceiver::RegisterEncodedVideoStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!platform_receiver()
               ->GetEncodedVideoStreamTransformer()
               ->HasTransformerCallback());
@@ -475,6 +498,7 @@
 }
 
 void RTCRtpReceiver::UnregisterEncodedVideoStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_EQ(track_->kind(), "video");
   platform_receiver()
       ->GetEncodedVideoStreamTransformer()
@@ -482,6 +506,7 @@
 }
 
 void RTCRtpReceiver::InitializeEncodedVideoStreams(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!encoded_video_streams_);
   DCHECK(!video_from_depacketizer_underlying_source_);
   DCHECK(!video_to_decoder_underlying_sink_);
@@ -529,6 +554,7 @@
 void RTCRtpReceiver::OnVideoFrameFromDepacketizer(
     std::unique_ptr<webrtc::TransformableVideoFrameInterface>
         encoded_video_frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (video_from_depacketizer_underlying_source_) {
     video_from_depacketizer_underlying_source_->OnFrameFromSource(
         std::move(encoded_video_frame));
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
index f9dcde853..51d43bb 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h
@@ -120,6 +120,8 @@
       video_from_depacketizer_underlying_source_;
   Member<RTCEncodedVideoUnderlyingSink> video_to_decoder_underlying_sink_;
   Member<RTCInsertableStreams> encoded_video_streams_;
+
+  THREAD_CHECKER(thread_checker_);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 7612cd53..02bc7c7b 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -418,10 +418,12 @@
 }
 
 MediaStreamTrack* RTCRtpSender::track() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return track_;
 }
 
 RTCDtlsTransport* RTCRtpSender::transport() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return transport_;
 }
 
@@ -432,6 +434,7 @@
 
 ScriptPromise RTCRtpSender::replaceTrack(ScriptState* script_state,
                                          MediaStreamTrack* with_track) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   if (pc_->IsClosed()) {
@@ -452,6 +455,7 @@
 }
 
 RTCRtpSendParameters* RTCRtpSender::getParameters() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   RTCRtpSendParameters* parameters = RTCRtpSendParameters::Create();
   std::unique_ptr<webrtc::RtpParameters> webrtc_parameters =
       sender_->GetParameters();
@@ -542,6 +546,7 @@
 ScriptPromise RTCRtpSender::setParameters(
     ScriptState* script_state,
     const RTCRtpSendParameters* parameters) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
 
@@ -578,10 +583,12 @@
 }
 
 void RTCRtpSender::ClearLastReturnedParameters() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   last_returned_parameters_ = nullptr;
 }
 
 ScriptPromise RTCRtpSender::getStats(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
   ScriptPromise promise = resolver->Promise();
   sender_->GetStats(
@@ -591,10 +598,12 @@
 }
 
 RTCRtpSenderPlatform* RTCRtpSender::web_sender() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return sender_.get();
 }
 
 void RTCRtpSender::SetTrack(MediaStreamTrack* track) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   track_ = track;
   if (track) {
     if (kind_.IsNull()) {
@@ -608,22 +617,27 @@
 }
 
 MediaStreamVector RTCRtpSender::streams() const {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return streams_;
 }
 
 void RTCRtpSender::set_streams(MediaStreamVector streams) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   streams_ = std::move(streams);
 }
 
 void RTCRtpSender::set_transceiver(RTCRtpTransceiver* transceiver) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   transceiver_ = transceiver;
 }
 
 void RTCRtpSender::set_transport(RTCDtlsTransport* transport) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   transport_ = transport;
 }
 
 RTCDTMFSender* RTCRtpSender::dtmf() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Lazy initialization of dtmf_ to avoid overhead when not used.
   if (!dtmf_ && kind_ == "audio") {
     auto handler = sender_->GetDtmfSender();
@@ -639,6 +653,7 @@
 
 void RTCRtpSender::setStreams(HeapVector<Member<MediaStream>> streams,
                               ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (pc_->IsClosed()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
@@ -659,6 +674,7 @@
 RTCInsertableStreams* RTCRtpSender::createEncodedStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (kind_ == "audio")
     return createEncodedAudioStreams(script_state, exception_state);
   DCHECK_EQ(kind_, "video");
@@ -668,6 +684,7 @@
 RTCInsertableStreams* RTCRtpSender::createEncodedAudioStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!force_encoded_audio_insertable_streams_) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
@@ -687,6 +704,7 @@
 RTCInsertableStreams* RTCRtpSender::createEncodedVideoStreams(
     ScriptState* script_state,
     ExceptionState& exception_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (!force_encoded_video_insertable_streams_) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
@@ -818,6 +836,7 @@
 }
 
 void RTCRtpSender::RegisterEncodedAudioStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!web_sender()
               ->GetEncodedAudioStreamTransformer()
               ->HasTransformerCallback());
@@ -828,10 +847,12 @@
 }
 
 void RTCRtpSender::UnregisterEncodedAudioStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   web_sender()->GetEncodedAudioStreamTransformer()->ResetTransformerCallback();
 }
 
 void RTCRtpSender::InitializeEncodedAudioStreams(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!audio_from_encoder_underlying_source_);
   DCHECK(!audio_to_packetizer_underlying_sink_);
   DCHECK(!encoded_audio_streams_);
@@ -878,12 +899,14 @@
 
 void RTCRtpSender::OnAudioFrameFromEncoder(
     std::unique_ptr<webrtc::TransformableFrameInterface> frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (audio_from_encoder_underlying_source_) {
     audio_from_encoder_underlying_source_->OnFrameFromSource(std::move(frame));
   }
 }
 
 void RTCRtpSender::RegisterEncodedVideoStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!web_sender()
               ->GetEncodedVideoStreamTransformer()
               ->HasTransformerCallback());
@@ -894,10 +917,12 @@
 }
 
 void RTCRtpSender::UnregisterEncodedVideoStreamCallback() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   web_sender()->GetEncodedVideoStreamTransformer()->ResetTransformerCallback();
 }
 
 void RTCRtpSender::InitializeEncodedVideoStreams(ScriptState* script_state) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!video_from_encoder_underlying_source_);
   DCHECK(!video_to_packetizer_underlying_sink_);
   DCHECK(!encoded_video_streams_);
@@ -943,6 +968,7 @@
 
 void RTCRtpSender::OnVideoFrameFromEncoder(
     std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (video_from_encoder_underlying_source_) {
     video_from_encoder_underlying_source_->OnFrameFromSource(std::move(frame));
   }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
index edd0640..a37fb9e5 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h
@@ -126,6 +126,8 @@
   Member<RTCEncodedVideoUnderlyingSource> video_from_encoder_underlying_source_;
   Member<RTCEncodedVideoUnderlyingSink> video_to_packetizer_underlying_sink_;
   Member<RTCInsertableStreams> encoded_video_streams_;
+
+  THREAD_CHECKER(thread_checker_);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn b/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn
index fbcf5fe..c471a49c 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn
+++ b/third_party/blink/renderer/modules/sanitizer_api/BUILD.gn
@@ -8,6 +8,8 @@
 
 blink_modules_sources("sanitizer_api") {
   sources = [
+    "element_sanitizer.cc",
+    "element_sanitizer.h",
     "sanitizer.cc",
     "sanitizer.h",
     "sanitizer_config_impl.cc",
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc
new file mode 100644
index 0000000..9bdf112
--- /dev/null
+++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.cc
@@ -0,0 +1,20 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "element_sanitizer.h"
+
+#include "third_party/blink/renderer/modules/sanitizer_api/sanitizer.h"
+
+namespace blink {
+
+void ElementSanitizer::SetSanitizedHTML(ScriptState* script_state,
+                                        Element& element,
+                                        const String& markup,
+                                        Sanitizer* sanitizer,
+                                        ExceptionState& exception_state) {
+  sanitizer->ElementSetSanitizedHTML(script_state, element, markup,
+                                     exception_state);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h
new file mode 100644
index 0000000..dd7ed20
--- /dev/null
+++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.h
@@ -0,0 +1,29 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SANITIZER_API_ELEMENT_SANITIZER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SANITIZER_API_ELEMENT_SANITIZER_H_
+
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class Element;
+class ExceptionState;
+class Sanitizer;
+class ScriptState;
+
+class MODULES_EXPORT ElementSanitizer final {
+ public:
+  static void SetSanitizedHTML(ScriptState*,
+                               Element&,
+                               const String&,
+                               Sanitizer*,
+                               ExceptionState&);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_SANITIZER_API_ELEMENT_SANITIZER_H_
diff --git a/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl
new file mode 100644
index 0000000..1700c3b
--- /dev/null
+++ b/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl
@@ -0,0 +1,15 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/sanitizer-api
+
+[
+  RuntimeEnabled=SanitizerAPI,
+  ImplementedAs=ElementSanitizer
+] partial interface Element {
+    // TODO(vogelheim): This name is likely going to change. Adapt when the
+    // standards PR changes as well.
+    [CEReactions, RaisesException, CallWith=ScriptState, MeasureAs=SanitizerAPIElementSetSanitized] void SetSanitizedHTML(DOMString markup, Sanitizer sanitizer);
+};
+
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
index 9a0323f6..c413d004 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.cc
@@ -8,7 +8,6 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_node_filter.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
@@ -111,42 +110,47 @@
                       kChildrenOnly);
 }
 
-DocumentFragment* Sanitizer::sanitize(
-    ScriptState* script_state,
-    const V8SanitizerInputWithTrustedHTML* input,
-    ExceptionState& exception_state) {
-  V8SanitizerInput* new_input = nullptr;
-  switch (input->GetContentType()) {
-    case V8SanitizerInputWithTrustedHTML::ContentType::kDocument:
-      new_input =
-          MakeGarbageCollected<V8SanitizerInput>(input->GetAsDocument());
-      break;
-    case V8SanitizerInputWithTrustedHTML::ContentType::kDocumentFragment:
-      new_input = MakeGarbageCollected<V8SanitizerInput>(
-          input->GetAsDocumentFragment());
-      break;
-    case V8SanitizerInputWithTrustedHTML::ContentType::kString: {
-      LocalDOMWindow* window = LocalDOMWindow::From(script_state);
-      if (!window) {
-        exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
-                                          "Cannot find current DOM window.");
-        return nullptr;
-      }
-      new_input =
-          MakeGarbageCollected<V8SanitizerInput>(TrustedTypesCheckForHTML(
-              input->GetAsString(), window->GetExecutionContext(),
-              exception_state));
-      if (exception_state.HadException()) {
-        return nullptr;
-      }
-      break;
-    }
-    case V8SanitizerInputWithTrustedHTML::ContentType::kTrustedHTML:
-      new_input = MakeGarbageCollected<V8SanitizerInput>(
-          input->GetAsTrustedHTML()->toString());
-      break;
+DocumentFragment* Sanitizer::sanitize(ScriptState* script_state,
+                                      const V8SanitizerInput* input,
+                                      ExceptionState& exception_state) {
+  return SanitizeImpl(script_state, input, exception_state);
+}
+
+Element* Sanitizer::sanitizeFor(ScriptState* script_state,
+                                const String& local_name,
+                                const String& markup,
+                                ExceptionState& exception_state) {
+  LocalDOMWindow* window = LocalDOMWindow::From(script_state);
+  Element* element = window->document()->CreateElementForBinding(
+      AtomicString(local_name), exception_state);
+  if (exception_state.HadException()) {
+    exception_state.ClearException();
+    return nullptr;
   }
-  return SanitizeImpl(script_state, new_input, exception_state);
+  element->setInnerHTML(markup, exception_state);
+  if (exception_state.HadException()) {
+    exception_state.ClearException();
+    return nullptr;
+  }
+  DoSanitizing(element, window, exception_state);
+  if (exception_state.HadException()) {
+    exception_state.ClearException();
+    return nullptr;
+  }
+  return element;
+}
+
+void Sanitizer::ElementSetSanitizedHTML(ScriptState* script_state,
+                                        Element& element,
+                                        const String& markup,
+                                        ExceptionState& exception_state) {
+  Element* new_element =
+      sanitizeFor(script_state, element.localName(), markup, exception_state);
+  if (!new_element || exception_state.HadException())
+    return;
+  element.RemoveChildren();
+  while (Node* to_be_moved = new_element->firstChild())
+    element.AppendChild(to_be_moved);
 }
 
 DocumentFragment* Sanitizer::PrepareFragment(LocalDOMWindow* window,
@@ -195,9 +199,9 @@
   return nullptr;
 }
 
-DocumentFragment* Sanitizer::DoSanitizing(DocumentFragment* fragment,
-                                          LocalDOMWindow* window,
-                                          ExceptionState& exception_state) {
+void Sanitizer::DoSanitizing(ContainerNode* fragment,
+                             LocalDOMWindow* window,
+                             ExceptionState& exception_state) {
   Node* node = fragment->firstChild();
 
   while (node) {
@@ -260,8 +264,6 @@
       node = KeepElement(node, fragment, name, window);
     }
   }
-
-  return fragment;
 }
 
 DocumentFragment* Sanitizer::SanitizeImpl(ScriptState* script_state,
@@ -273,12 +275,13 @@
   if (exception_state.HadException()) {
     return nullptr;
   }
-  return DoSanitizing(fragment, window, exception_state);
+  DoSanitizing(fragment, window, exception_state);
+  return fragment;
 }
 
 // If the current element needs to be dropped, remove current element entirely
 // and proceed to its next sibling.
-Node* Sanitizer::DropElement(Node* node, DocumentFragment* fragment) {
+Node* Sanitizer::DropElement(Node* node, ContainerNode* fragment) {
   Node* tmp = node;
   node = NodeTraversal::NextSkippingChildren(*node, fragment);
   tmp->remove();
@@ -288,7 +291,7 @@
 // If the current element should be blocked, append its children after current
 // node to parent node, remove current element and proceed to the next node.
 Node* Sanitizer::BlockElement(Node* node,
-                              DocumentFragment* fragment,
+                              ContainerNode* fragment,
                               ExceptionState& exception_state) {
   ContainerNode* parent = node->parentNode();
   Node* next_sibling = node->nextSibling();
@@ -307,7 +310,7 @@
 // Remove any attributes to be dropped from the current element, and proceed to
 // the next node (preorder, depth-first traversal).
 Node* Sanitizer::KeepElement(Node* node,
-                             DocumentFragment* fragment,
+                             ContainerNode* fragment,
                              String& node_name,
                              LocalDOMWindow* window) {
   Element* element = To<Element>(node);
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
index a1bdb96f..fe41344 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.h
@@ -14,6 +14,7 @@
 
 namespace blink {
 
+class ContainerNode;
 class Document;
 class DocumentFragment;
 class ExceptionState;
@@ -34,25 +35,36 @@
   static Sanitizer* Create(ExecutionContext*,
                            const SanitizerConfig*,
                            ExceptionState&);
-  explicit Sanitizer(ExecutionContext*, const SanitizerConfig*);
+  Sanitizer(ExecutionContext*, const SanitizerConfig*);
   ~Sanitizer() override;
 
   String sanitizeToString(ScriptState* script_state,
                           const V8SanitizerInput* input,
                           ExceptionState& exception_state);
   DocumentFragment* sanitize(ScriptState* script_state,
-                             const V8SanitizerInputWithTrustedHTML* input,
+                             const V8SanitizerInput* input,
                              ExceptionState& exception_state);
+  Element* sanitizeFor(ScriptState* script_state,
+                       const String& element,
+                       const String& markup,
+                       ExceptionState& exception_state);
 
   SanitizerConfig* config() const;
   static SanitizerConfig* defaultConfig();
 
+  // Implementation of ElementSanitizer::SetSanitizedHTML, so that we have
+  // all the sanitizer logic in one place.
+  void ElementSetSanitizedHTML(ScriptState* script_state,
+                               Element& element,
+                               const String& markup,
+                               ExceptionState& exception_state);
+
   void Trace(Visitor*) const override;
 
  private:
-  Node* DropElement(Node*, DocumentFragment*);
-  Node* BlockElement(Node*, DocumentFragment*, ExceptionState&);
-  Node* KeepElement(Node*, DocumentFragment*, String&, LocalDOMWindow*);
+  Node* DropElement(Node*, ContainerNode*);
+  Node* BlockElement(Node*, ContainerNode*, ExceptionState&);
+  Node* KeepElement(Node*, ContainerNode*, String&, LocalDOMWindow*);
 
   void ElementFormatter(HashSet<String>&, const Vector<String>&);
   void AttrFormatter(HashMap<String, Vector<String>>&,
@@ -62,9 +74,7 @@
                                     ScriptState* script_state,
                                     const V8SanitizerInput* input,
                                     ExceptionState& exception_state);
-  DocumentFragment* DoSanitizing(DocumentFragment*,
-                                 LocalDOMWindow*,
-                                 ExceptionState&);
+  void DoSanitizing(ContainerNode*, LocalDOMWindow*, ExceptionState&);
   DocumentFragment* SanitizeImpl(ScriptState* script_state,
                                  const V8SanitizerInput* input,
                                  ExceptionState& exception_state);
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl
index 21f02b2..e2d4bd7 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl
@@ -5,17 +5,19 @@
 // https://github.com/WICG/sanitizer-api
 
 typedef (DOMString or DocumentFragment or Document) SanitizerInput;
-typedef (DOMString or TrustedHTML or DocumentFragment or Document) SanitizerInputWithTrustedHTML;
 
 [
   Exposed=Window,
+  SecureContext,
   RuntimeEnabled=SanitizerAPI
 ] interface Sanitizer {
   [MeasureAs=SanitizerAPICreated, CallWith=ExecutionContext, RaisesException] constructor(optional SanitizerConfig config = {});
 
-  [MeasureAs=SanitizerAPIToFragment, CallWith=ScriptState, RaisesException] DocumentFragment sanitize(SanitizerInputWithTrustedHTML input);
+  [MeasureAs=SanitizerAPIToFragment, CallWith=ScriptState, RaisesException] DocumentFragment sanitize(SanitizerInput input);
   [MeasureAs=SanitizerAPIToString, CallWith=ScriptState, RaisesException] DOMString sanitizeToString(SanitizerInput input);
+  [MeasureAs=SanitizerAPISanitizeFor, CallWith=ScriptState, RaisesException] Element? sanitizeFor(DOMString element, DOMString markup);
 
   [MeasureAs=SanitizerAPIGetConfig] SanitizerConfig config();
   [MeasureAs=SanitizerAPIGetDefaultConfig] static SanitizerConfig defaultConfig();
 };
+
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
index da54b2b3..06198eb4 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_api_fuzzer.cc
@@ -19,8 +19,6 @@
 
 #include "testing/libfuzzer/proto/lpm_interface.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_union_document_documentfragment_string_trustedhtml.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_sanitizer_config.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
@@ -90,18 +88,26 @@
   auto* sanitizer = MakeGarbageCollected<Sanitizer>(
       window->GetExecutionContext(), sanitizer_config);
 
-  // Sanitize string given in proto. Method depends on sanitize_to_string.
-  String str = proto.html_string().c_str();
-  if (proto.sanitize_to_string()) {
-    auto* str1 = MakeGarbageCollected<
-        V8UnionDocumentOrDocumentFragmentOrStringOrTrustedHTML>(str);
-    sanitizer->sanitize(script_state, str1, IGNORE_EXCEPTION_FOR_TESTING);
-  } else {
-    auto* str2 =
-        MakeGarbageCollected<V8UnionDocumentOrDocumentFragmentOrString>(str);
-    sanitizer->sanitizeToString(script_state, str2,
-                                IGNORE_EXCEPTION_FOR_TESTING);
+  // Sanitize string given in proto. Use proto.string_context to decide on
+  // parsing context for sanitizeFor.
+  // TODO(1225606): This needs to be updated to also support SVG & MathML
+  // contexts, once those are implemented.
+  String markup = proto.html_string().c_str();
+  const char* string_context = nullptr;
+  switch (proto.string_context()) {
+    case SanitizerConfigProto::DIV:
+      string_context = "div";
+      break;
+    case SanitizerConfigProto::TABLE:
+      string_context = "table";
+      break;
+    case SanitizerConfigProto::TEMPLATE:
+    default:
+      string_context = "template";
+      break;
   }
+  sanitizer->sanitizeFor(script_state, string_context, markup,
+                         IGNORE_EXCEPTION_FOR_TESTING);
 
   // The fuzzer will eventually run out of memory. Force the GC to run every
   // N-th time. This will trigger both V8 + Oilpan GC.
diff --git a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
index 7f463ef..d12277b6 100644
--- a/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
+++ b/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.proto
@@ -16,5 +16,11 @@
   map<string, Elements> drop_attributes = 6;
 
   optional bool allow_custom_elements = 7;
-  optional bool sanitize_to_string = 8;
+
+  enum StringContext {
+    TEMPLATE = 0;
+    DIV = 1;
+    TABLE = 2;
+  }
+  optional StringContext string_context = 9;
 }
diff --git a/third_party/blink/renderer/modules/scheduler/scheduler.idl b/third_party/blink/renderer/modules/scheduler/scheduler.idl
index 755ec139..8fbedd6 100644
--- a/third_party/blink/renderer/modules/scheduler/scheduler.idl
+++ b/third_party/blink/renderer/modules/scheduler/scheduler.idl
@@ -12,5 +12,5 @@
     RuntimeEnabled=WebScheduler
 ] interface Scheduler {
     [CallWith=ScriptState, MeasureAs=SchedulerPostTask, RaisesException] Promise<any> postTask(SchedulerPostTaskCallback callback, optional SchedulerPostTaskOptions options = {});
-    [CallWith=ScriptState, MeasureAs=SchedulerCurrentTaskSignal] readonly attribute TaskSignal currentTaskSignal;
+    [CallWith=ScriptState, MeasureAs=SchedulerCurrentTaskSignal, RuntimeEnabled=SchedulerCurrentTaskSignal] readonly attribute TaskSignal currentTaskSignal;
 };
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc
index a2b0599..fc20231 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -184,6 +184,12 @@
 ScriptPromise SerialPort::open(ScriptState* script_state,
                                const SerialOptions* options,
                                ExceptionState& exception_state) {
+  if (!GetExecutionContext()) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+                                      "Script context has shut down.");
+    return ScriptPromise();
+  }
+
   if (open_resolver_) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kInvalidStateError,
diff --git a/third_party/blink/renderer/modules/speech/OWNERS b/third_party/blink/renderer/modules/speech/OWNERS
index b997d55..5508040 100644
--- a/third_party/blink/renderer/modules/speech/OWNERS
+++ b/third_party/blink/renderer/modules/speech/OWNERS
@@ -1,2 +1,5 @@
-# Speech synthesis, and final approval for speech recognition
+# Speech synthesis
 dmazzoni@chromium.org
+
+# Speech recognition
+evliu@google.com
diff --git a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
index 6dce56b..7460e845 100644
--- a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
+++ b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
@@ -13,7 +13,6 @@
 #include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/vector_traits.h"
-#include "v8/include/v8-cppgc.h"
 #include "v8/include/v8.h"
 
 #if BUILDFLAG(USE_V8_OILPAN)
@@ -139,7 +138,9 @@
 
   v8::TracedReference<T> handle_;
 
+#if BUILDFLAG(USE_V8_OILPAN)
   friend struct cppgc::TraceTrait<TraceWrapperV8Reference<T>>;
+#endif  // USE_V8_OILPAN
 };
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 2f6a9fd..2616170 100644
--- a/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -33,10 +33,10 @@
 #import <Foundation/Foundation.h>
 #import <math.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_nsobject.h"
-#include "base/stl_util.h"
 #include "third_party/blink/renderer/platform/fonts/font_cache.h"
 #import "third_party/blink/renderer/platform/wtf/hash_set.h"
 #import "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
diff --git a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
index 2150493..4be9a4f 100644
--- a/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
+++ b/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -26,9 +26,9 @@
 #import <AppKit/NSFont.h>
 #import <AvailabilityMacros.h>
 
+#include "base/cxx17_backports.h"
 #import "base/mac/foundation_util.h"
 #import "base/mac/scoped_nsobject.h"
-#include "base/stl_util.h"
 #include "third_party/blink/public/platform/mac/web_sandbox_support.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/fonts/font.h"
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn
index aea96d0e..73a7ef2 100644
--- a/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -232,8 +232,11 @@
     "//third_party/blink/renderer/platform/wtf:buildflags",
   ]
 
+  # TODO(v8:11952): Switch to `//v8:v8_for_testing` as target once it properly
+  # depends on v8 without duplicating the whole library which causes ODR
+  # violations when `//v8:v8` is also pulled in otherwise.
   if (enable_blink_heap_use_v8_oilpan) {
-    deps += [ "//v8:v8_for_testing" ]
+    deps += [ "//v8:v8" ]
   }
 
   public_deps = [ "//base/test:test_support" ]
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
index 9a181b9a..a59a5eb 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -103,14 +103,14 @@
 
 const char kWatchTimeHistogram[] = "Media.WebMediaPlayerImpl.WatchTime";
 
-void RecordSimpleWatchTimeUMA(RendererType type) {
+void RecordSimpleWatchTimeUMA(media::RendererType type) {
   UMA_HISTOGRAM_ENUMERATION(kWatchTimeHistogram, type);
 }
 
 void SetSinkIdOnMediaThread(
     scoped_refptr<blink::WebAudioSourceProviderImpl> sink,
     const std::string& device_id,
-    OutputDeviceStatusCB callback) {
+    media::OutputDeviceStatusCB callback) {
   sink->SwitchOutputDevice(device_id, std::move(callback));
 }
 
@@ -123,11 +123,11 @@
 }
 
 bool IsResumeBackgroundVideosEnabled() {
-  return base::FeatureList::IsEnabled(kResumeBackgroundVideo);
+  return base::FeatureList::IsEnabled(media::kResumeBackgroundVideo);
 }
 
 bool IsBackgroundVideoPauseOptimizationEnabled() {
-  return base::FeatureList::IsEnabled(kBackgroundVideoPauseOptimization);
+  return base::FeatureList::IsEnabled(media::kBackgroundVideoPauseOptimization);
 }
 
 bool IsNetworkStateError(blink::WebMediaPlayer::NetworkState state) {
@@ -138,8 +138,10 @@
   return result;
 }
 
-gfx::Size GetRotatedVideoSize(VideoRotation rotation, gfx::Size natural_size) {
-  if (rotation == VIDEO_ROTATION_90 || rotation == VIDEO_ROTATION_270)
+gfx::Size GetRotatedVideoSize(media::VideoRotation rotation,
+                              gfx::Size natural_size) {
+  if (rotation == media::VIDEO_ROTATION_90 ||
+      rotation == media::VIDEO_ROTATION_270)
     return gfx::Size(natural_size.height(), natural_size.width());
   return natural_size;
 }
@@ -156,15 +158,17 @@
 // Maximum number, per-WMPI, of media logs of playback rate changes.
 constexpr int kMaxNumPlaybackRateLogs = 10;
 
-int GetSwitchToLocalMessage(MediaObserverClient::ReasonToSwitchToLocal reason) {
+int GetSwitchToLocalMessage(
+    media::MediaObserverClient::ReasonToSwitchToLocal reason) {
   switch (reason) {
-    case MediaObserverClient::ReasonToSwitchToLocal::NORMAL:
+    case media::MediaObserverClient::ReasonToSwitchToLocal::NORMAL:
       return IDS_MEDIA_REMOTING_STOP_TEXT;
-    case MediaObserverClient::ReasonToSwitchToLocal::POOR_PLAYBACK_QUALITY:
+    case media::MediaObserverClient::ReasonToSwitchToLocal::
+        POOR_PLAYBACK_QUALITY:
       return IDS_MEDIA_REMOTING_STOP_BY_PLAYBACK_QUALITY_TEXT;
-    case MediaObserverClient::ReasonToSwitchToLocal::PIPELINE_ERROR:
+    case media::MediaObserverClient::ReasonToSwitchToLocal::PIPELINE_ERROR:
       return IDS_MEDIA_REMOTING_STOP_BY_ERROR_TEXT;
-    case MediaObserverClient::ReasonToSwitchToLocal::ROUTE_TERMINATED:
+    case media::MediaObserverClient::ReasonToSwitchToLocal::ROUTE_TERMINATED:
       return blink::WebMediaPlayerClient::kMediaRemotingStopNoText;
   }
   NOTREACHED();
@@ -179,11 +183,11 @@
 enum class EncryptionSchemeUMA { kCenc = 0, kCbcs = 1, kCount };
 
 EncryptionSchemeUMA DetermineEncryptionSchemeUMAValue(
-    EncryptionScheme encryption_scheme) {
-  if (encryption_scheme == EncryptionScheme::kCbcs)
+    media::EncryptionScheme encryption_scheme) {
+  if (encryption_scheme == media::EncryptionScheme::kCbcs)
     return EncryptionSchemeUMA::kCbcs;
 
-  DCHECK_EQ(encryption_scheme, EncryptionScheme::kCenc);
+  DCHECK_EQ(encryption_scheme, media::EncryptionScheme::kCenc);
   return EncryptionSchemeUMA::kCenc;
 }
 
@@ -203,12 +207,12 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> vfc_task_runner,
     std::unique_ptr<Demuxer> demuxer,
-    std::unique_ptr<DataSource> data_source,
+    std::unique_ptr<media::DataSource> data_source,
     std::unique_ptr<VideoFrameCompositor> compositor,
-    std::unique_ptr<CdmContextRef> cdm_context_1,
-    std::unique_ptr<CdmContextRef> cdm_context_2,
-    std::unique_ptr<MediaLog> media_log,
-    std::unique_ptr<RendererFactorySelector> renderer_factory_selector,
+    std::unique_ptr<media::CdmContextRef> cdm_context_1,
+    std::unique_ptr<media::CdmContextRef> cdm_context_2,
+    std::unique_ptr<media::MediaLog> media_log,
+    std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector,
     std::unique_ptr<blink::WebSurfaceLayerBridge> bridge,
     bool is_chunk_demuxer) {
   // We release |bridge| after pipeline stop to ensure layout tests receive
@@ -247,9 +251,9 @@
       base::BindOnce(
           [](scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
              std::unique_ptr<Demuxer> demuxer_to_destroy,
-             std::unique_ptr<CdmContextRef> cdm_context_1,
-             std::unique_ptr<CdmContextRef> cdm_context_2,
-             std::unique_ptr<MediaLog> media_log) {
+             std::unique_ptr<media::CdmContextRef> cdm_context_1,
+             std::unique_ptr<media::CdmContextRef> cdm_context_2,
+             std::unique_ptr<media::MediaLog> media_log) {
             SCOPED_UMA_HISTOGRAM_TIMER("Media.MSE.DemuxerDestructionTime");
             demuxer_to_destroy.reset();
             main_task_runner->DeleteSoon(FROM_HERE, std::move(cdm_context_1));
@@ -317,8 +321,8 @@
 // Returns whether the player uses AudioService. This is needed to enable
 // AudioStreamMonitor (for audio indicator) when not using AudioService.
 // TODO(crbug.com/1017943): Support other RendererTypes.
-bool UsesAudioService(RendererType renderer_type) {
-  return renderer_type != RendererType::kMediaFoundation;
+bool UsesAudioService(media::RendererType renderer_type) {
+  return renderer_type != media::RendererType::kMediaFoundation;
 }
 
 }  // namespace
@@ -336,7 +340,7 @@
     blink::WebMediaPlayerClient* client,
     blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
     blink::WebMediaPlayerDelegate* delegate,
-    std::unique_ptr<RendererFactorySelector> renderer_factory_selector,
+    std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector,
     UrlIndex* url_index,
     std::unique_ptr<VideoFrameCompositor> compositor,
     std::unique_ptr<WebMediaPlayerParams> params)
@@ -366,7 +370,6 @@
       surface_layer_mode_(params->use_surface_layer_for_video()),
       create_bridge_callback_(params->create_bridge_callback()),
       request_routing_token_cb_(params->request_routing_token_cb()),
-      overlay_routing_token_(OverlayInfo::RoutingToken()),
       media_metrics_provider_(params->take_metrics_provider()),
       is_background_suspend_enabled_(params->IsBackgroundSuspendEnabled()),
       is_background_video_playback_enabled_(
@@ -392,13 +395,13 @@
   // Using base::Unretained(this) is safe because the |pipeline| is owned by
   // |this| and the callback will always be made on the main task runner.
   // Not using BindToCurrentLoop() because CreateRenderer() is a sync call.
-  auto pipeline = std::make_unique<PipelineImpl>(
+  auto pipeline = std::make_unique<media::PipelineImpl>(
       media_task_runner_, main_task_runner_,
       base::BindRepeating(&WebMediaPlayerImpl::CreateRenderer,
                           base::Unretained(this)),
       media_log_.get());
 
-  pipeline_controller_ = std::make_unique<PipelineController>(
+  pipeline_controller_ = std::make_unique<media::PipelineController>(
       std::move(pipeline),
       base::BindRepeating(&WebMediaPlayerImpl::OnPipelineSeeked, weak_this_),
       base::BindRepeating(&WebMediaPlayerImpl::OnPipelineSuspended, weak_this_),
@@ -416,7 +419,7 @@
   always_enable_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kForceVideoOverlays);
 
-  if (base::FeatureList::IsEnabled(kOverlayFullscreenVideo))
+  if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo))
     overlay_mode_ = OverlayMode::kUseAndroidOverlay;
   else
     overlay_mode_ = OverlayMode::kNoOverlays;
@@ -459,7 +462,7 @@
   memory_usage_reporting_timer_.SetTaskRunner(
       frame_->GetTaskRunner(blink::TaskType::kInternalMedia));
 
-  main_thread_mem_dumper_ = std::make_unique<MemoryDumpProviderProxy>(
+  main_thread_mem_dumper_ = std::make_unique<media::MemoryDumpProviderProxy>(
       "WebMediaPlayer_MainThread", main_task_runner_,
       base::BindRepeating(&WebMediaPlayerImpl::OnMainThreadMemoryDump,
                           weak_this_, media_log_->id()));
@@ -473,7 +476,7 @@
 
 #if defined(OS_ANDROID)
   renderer_factory_selector_->SetRemotePlayStateChangeCB(
-      BindToCurrentLoop(base::BindRepeating(
+      media::BindToCurrentLoop(base::BindRepeating(
           &WebMediaPlayerImpl::OnRemotePlayStateChange, weak_this_)));
 #endif  // defined (OS_ANDROID)
 }
@@ -629,7 +632,7 @@
   if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) {
     token_available_cb_.Cancel();
     overlay_routing_token_is_pending_ = false;
-    overlay_routing_token_ = OverlayInfo::RoutingToken();
+    overlay_routing_token_ = media::OverlayInfo::RoutingToken();
   }
 
   if (decoder_requires_restart_for_overlay_)
@@ -774,14 +777,14 @@
 
   // Do a truncation to kMaxUrlLength+1 at most; we can add ellipsis later.
   media_log_->AddEvent<MediaLogEvent::kLoad>(
-      url.GetString().Substring(0, kMaxUrlLength + 1).Utf8());
+      url.GetString().Substring(0, media::kMaxUrlLength + 1).Utf8());
   load_start_time_ = base::TimeTicks::Now();
 
-  std::vector<TextTrackConfig> text_configs;
+  std::vector<media::TextTrackConfig> text_configs;
   for (const auto& metadata : client_->GetTextTrackMetadata()) {
-    text_configs.emplace_back(TextTrackConfig::ConvertKind(metadata.kind()),
-                              metadata.label(), metadata.language(),
-                              metadata.id());
+    text_configs.emplace_back(
+        media::TextTrackConfig::ConvertKind(metadata.kind()), metadata.label(),
+        metadata.language(), metadata.id());
   }
   media_log_->SetProperty<MediaLogProperty::kTextTracks>(text_configs);
 
@@ -792,8 +795,8 @@
   media_metrics_provider_->Initialize(
       load_type == kLoadTypeMediaSource,
       load_type == kLoadTypeURL ? blink::GetMediaURLScheme(loaded_url_)
-                                : mojom::MediaURLScheme::kUnknown,
-      mojom::MediaStreamType::kNone);
+                                : media::mojom::MediaURLScheme::kUnknown,
+      media::mojom::MediaStreamType::kNone);
 
   if (demuxer_override_ || load_type == kLoadTypeMediaSource) {
     // If a demuxer override was specified or a Media Source pipeline will be
@@ -801,7 +804,7 @@
     StartPipeline();
   } else {
     // If |loaded_url_| is remoting media, starting the pipeline.
-    if (loaded_url_.SchemeIs(remoting::kRemotingScheme)) {
+    if (loaded_url_.SchemeIs(media::remoting::kRemotingScheme)) {
       StartPipeline();
       return;
     }
@@ -825,7 +828,7 @@
       buffered_data_source_host_->AddBufferedByteRange(0, data.size());
 
       DCHECK(!mb_data_source_);
-      data_source_ = std::make_unique<MemoryDataSource>(std::move(data));
+      data_source_ = std::make_unique<media::MemoryDataSource>(std::move(data));
       DataSourceInitialized(true);
       return;
     }
@@ -971,8 +974,8 @@
     if (old_state == kReadyStateHaveEnoughData) {
       main_task_runner_->PostTask(
           FROM_HERE, base::BindOnce(&WebMediaPlayerImpl::OnBufferingStateChange,
-                                    weak_this_, BUFFERING_HAVE_ENOUGH,
-                                    BUFFERING_CHANGE_REASON_UNKNOWN));
+                                    weak_this_, media::BUFFERING_HAVE_ENOUGH,
+                                    media::BUFFERING_CHANGE_REASON_UNKNOWN));
     }
     return;
   }
@@ -1034,7 +1037,7 @@
 
   if (delegate_has_audio_ != HasUnmutedAudio()) {
     delegate_has_audio_ = HasUnmutedAudio();
-    MediaContentType content_type = GetMediaContentType();
+    media::MediaContentType content_type = GetMediaContentType();
     client_->DidMediaMetadataChange(delegate_has_audio_, HasVideo(),
                                     content_type);
     delegate_->DidMediaMetadataChange(delegate_id_, delegate_has_audio_,
@@ -1081,7 +1084,7 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   DVLOG(1) << __func__;
 
-  OutputDeviceStatusCB callback =
+  media::OutputDeviceStatusCB callback =
       ConvertToOutputDeviceStatusCB(std::move(completion_callback));
   auto sink_id_utf8 = sink_id.Utf8();
   media_task_runner_->PostTask(
@@ -1153,7 +1156,8 @@
 
 gfx::Size WebMediaPlayerImpl::VisibleSize() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor();
+  scoped_refptr<media::VideoFrame> video_frame =
+      GetCurrentFrameFromCompositor();
   if (!video_frame)
     return gfx::Size();
 
@@ -1193,7 +1197,7 @@
     return chunk_demuxer_->GetDuration();
 
   base::TimeDelta pipeline_duration = GetPipelineMediaDuration();
-  return pipeline_duration == kInfiniteDuration
+  return pipeline_duration == media::kInfiniteDuration
              ? std::numeric_limits<double>::infinity()
              : pipeline_duration.InSecondsF();
 }
@@ -1269,11 +1273,11 @@
 blink::WebTimeRanges WebMediaPlayerImpl::Buffered() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
-  Ranges<base::TimeDelta> buffered_time_ranges =
+  media::Ranges<base::TimeDelta> buffered_time_ranges =
       pipeline_controller_->GetBufferedTimeRanges();
 
   const base::TimeDelta duration = GetPipelineMediaDuration();
-  if (duration != kInfiniteDuration) {
+  if (duration != media::kInfiniteDuration) {
     buffered_data_source_host_->AddBufferedTimeRanges(&buffered_time_ranges,
                                                       duration);
   }
@@ -1359,7 +1363,8 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   TRACE_EVENT0("media", "WebMediaPlayerImpl:paint");
 
-  scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor();
+  scoped_refptr<media::VideoFrame> video_frame =
+      GetCurrentFrameFromCompositor();
   last_frame_request_time_ = tick_clock_->NowTicks();
 
   video_renderer_.Paint(
@@ -1368,7 +1373,7 @@
       raster_context_provider_.get());
 }
 
-scoped_refptr<VideoFrame> WebMediaPlayerImpl::GetCurrentFrame() {
+scoped_refptr<media::VideoFrame> WebMediaPlayerImpl::GetCurrentFrame() {
   last_frame_request_time_ = tick_clock_->NowTicks();
   return GetCurrentFrameFromCompositor();
 }
@@ -1457,9 +1462,9 @@
 }
 
 void WebMediaPlayerImpl::OnEncryptedMediaInitData(
-    EmeInitDataType init_data_type,
+    media::EmeInitDataType init_data_type,
     const std::vector<uint8_t>& init_data) {
-  DCHECK(init_data_type != EmeInitDataType::UNKNOWN);
+  DCHECK(init_data_type != media::EmeInitDataType::UNKNOWN);
 
   RecordEncryptedEvent(true);
 
@@ -1484,7 +1489,7 @@
 }
 
 void WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated(
-    std::unique_ptr<MediaTracks> tracks) {
+    std::unique_ptr<media::MediaTracks> tracks) {
   // For MSE/chunk_demuxer case the media track updates are handled by
   // WebSourceBufferImpl.
   DCHECK(demuxer_.get());
@@ -1555,7 +1560,7 @@
     media_metrics_provider_->SetIsHardwareSecure();
   CreateVideoDecodeStatsReporter();
 
-  CdmContext* cdm_context = cdm_context_ref->GetCdmContext();
+  auto* cdm_context = cdm_context_ref->GetCdmContext();
   DCHECK(cdm_context);
 
   // Keep the reference to the CDM, as it shouldn't be destroyed until
@@ -1635,8 +1640,9 @@
     // Note: This call is dual purpose, it is also responsible for triggering an
     // UpdatePlayState() call which may need to resume the pipeline once Blink
     // has been told about the ReadyState change.
-    OnBufferingStateChangeInternal(BUFFERING_HAVE_ENOUGH,
-                                   BUFFERING_CHANGE_REASON_UNKNOWN, true);
+    OnBufferingStateChangeInternal(media::BUFFERING_HAVE_ENOUGH,
+                                   media::BUFFERING_CHANGE_REASON_UNKNOWN,
+                                   true);
   }
 
   attempting_suspended_start_ = false;
@@ -1729,7 +1735,8 @@
     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
   DVLOG(2) << __func__ << " memory_pressure_level=" << memory_pressure_level;
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  DCHECK(base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC));
+  DCHECK(
+      base::FeatureList::IsEnabled(media::kMemoryPressureBasedSourceBufferGC));
   DCHECK(chunk_demuxer_);
 
   if (memory_pressure_level ==
@@ -1756,16 +1763,16 @@
   // from ~WMPI by first hopping to |media_task_runner_| to prevent race with
   // this task.
   media_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&ChunkDemuxer::OnMemoryPressure,
+      FROM_HERE, base::BindOnce(&media::ChunkDemuxer::OnMemoryPressure,
                                 base::Unretained(chunk_demuxer_),
                                 base::TimeDelta::FromSecondsD(CurrentTime()),
                                 memory_pressure_level, force_instant_gc));
 }
 
-void WebMediaPlayerImpl::OnError(PipelineStatus status) {
+void WebMediaPlayerImpl::OnError(media::PipelineStatus status) {
   DVLOG(1) << __func__ << ": status=" << status;
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  DCHECK_NE(status, PIPELINE_OK);
+  DCHECK_NE(status, media::PIPELINE_OK);
 
   if (suppress_destruction_errors_)
     return;
@@ -1773,8 +1780,9 @@
 #if defined(OS_ANDROID)
   // |mb_data_source_| may be nullptr if someone passes in a m3u8 as a data://
   // URL, since MediaPlayer doesn't support data:// URLs, fail playback now.
-  const bool found_hls = base::FeatureList::IsEnabled(kHlsPlayer) &&
-                         status == PipelineStatus::DEMUXER_ERROR_DETECTED_HLS;
+  const bool found_hls =
+      base::FeatureList::IsEnabled(media::kHlsPlayer) &&
+      status == media::PipelineStatus::DEMUXER_ERROR_DETECTED_HLS;
   if (found_hls && mb_data_source_) {
     demuxer_found_hls_ = true;
 
@@ -1800,7 +1808,8 @@
         "Media.WebMediaPlayerImpl.HLS.IsMixedContent",
         frame_url_is_cryptographic && !manifest_url_is_cryptographic);
 
-    renderer_factory_selector_->SetBaseRendererType(RendererType::kMediaPlayer);
+    renderer_factory_selector_->SetBaseRendererType(
+        media::RendererType::kMediaPlayer);
 
     loaded_url_ = mb_data_source_->GetUrlAfterRedirects();
     DCHECK(data_source_);
@@ -1816,9 +1825,9 @@
     // data source now that we're switching to HLS playback.
     media_task_runner_->PostTask(
         FROM_HERE,
-        BindToCurrentLoop(base::BindOnce(
+        media::BindToCurrentLoop(base::BindOnce(
             [](std::unique_ptr<Demuxer> demuxer,
-               std::unique_ptr<DataSource> data_source,
+               std::unique_ptr<media::DataSource> data_source,
                base::OnceClosure start_pipeline_cb) {
               // Release resources before starting HLS.
               demuxer.reset();
@@ -1834,12 +1843,12 @@
 
   // We found hls in a data:// URL, fail immediately.
   if (found_hls)
-    status = PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED;
+    status = media::PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED;
 #elif defined(OS_WIN)
   // Hardware context reset is not an error. Restart to recover.
   // TODO(crbug.com/1208618): Find a way to break the potential infinite loop of
   // restart -> PIPELINE_ERROR_HARDWARE_CONTEXT_RESET -> restart.
-  if (status == PipelineStatus::PIPELINE_ERROR_HARDWARE_CONTEXT_RESET) {
+  if (status == media::PipelineStatus::PIPELINE_ERROR_HARDWARE_CONTEXT_RESET) {
     ScheduleRestart();
     return;
   }
@@ -1890,7 +1899,7 @@
   UpdatePlayState();
 }
 
-void WebMediaPlayerImpl::OnMetadata(const PipelineMetadata& metadata) {
+void WebMediaPlayerImpl::OnMetadata(const media::PipelineMetadata& metadata) {
   DVLOG(1) << __func__;
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
@@ -1909,7 +1918,7 @@
   UMA_HISTOGRAM_ENUMERATION(
       "Media.VideoRotation",
       metadata.video_decoder_config.video_transformation().rotation,
-      VIDEO_ROTATION_MAX + 1);
+      media::VIDEO_ROTATION_MAX + 1);
 
   if (HasAudio()) {
     media_metrics_provider_->SetHasAudio(metadata.audio_decoder_config.codec());
@@ -1951,7 +1960,7 @@
     observer_->OnMetadataChanged(pipeline_metadata_);
 
   delegate_has_audio_ = HasUnmutedAudio();
-  MediaContentType content_type = GetMediaContentType();
+  media::MediaContentType content_type = GetMediaContentType();
   client_->DidMediaMetadataChange(delegate_has_audio_, HasVideo(),
                                   content_type);
   delegate_->DidMediaMetadataChange(delegate_id_, delegate_has_audio_,
@@ -1969,7 +1978,7 @@
   // reaching HAVE_METADATA.
   if (!HasVideo() && !HasAudio()) {
     DVLOG(1) << __func__ << ": no audio and no video -> error";
-    OnError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN);
+    OnError(media::PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN);
     return;  // Do not transition to HAVE_METADATA.
   }
 
@@ -2028,8 +2037,8 @@
 }
 
 void WebMediaPlayerImpl::OnBufferingStateChange(
-    BufferingState state,
-    BufferingStateChangeReason reason) {
+    media::BufferingState state,
+    media::BufferingStateChangeReason reason) {
   OnBufferingStateChangeInternal(state, reason, false);
 }
 
@@ -2050,7 +2059,7 @@
 
   // Profile must be known for use as index to save the reported stats.
   if (pipeline_metadata_.video_decoder_config.profile() ==
-      VIDEO_CODEC_PROFILE_UNKNOWN) {
+      media::VIDEO_CODEC_PROFILE_UNKNOWN) {
     return;
   }
 
@@ -2061,7 +2070,7 @@
     DCHECK(!key_system_.empty());
   }
 
-  mojo::PendingRemote<mojom::VideoDecodeStatsRecorder> recorder;
+  mojo::PendingRemote<media::mojom::VideoDecodeStatsRecorder> recorder;
   media_metrics_provider_->AcquireVideoDecodeStatsRecorder(
       recorder.InitWithNewPipeAndPassReceiver());
 
@@ -2108,7 +2117,7 @@
 }
 
 bool WebMediaPlayerImpl::CanPlayThrough() {
-  if (!base::FeatureList::IsEnabled(kSpecCompliantCanPlayThrough))
+  if (!base::FeatureList::IsEnabled(media::kSpecCompliantCanPlayThrough))
     return true;
   if (chunk_demuxer_)
     return true;
@@ -2125,8 +2134,8 @@
 }
 
 void WebMediaPlayerImpl::OnBufferingStateChangeInternal(
-    BufferingState state,
-    BufferingStateChangeReason reason,
+    media::BufferingState state,
+    media::BufferingStateChangeReason reason,
     bool for_suspended_start) {
   DVLOG(1) << __func__ << "(" << state << ", " << reason << ")";
   DCHECK(main_task_runner_->BelongsToCurrentThread());
@@ -2137,13 +2146,14 @@
     return;
 
   media_log_->AddEvent<MediaLogEvent::kBufferingStateChanged>(
-      SerializableBufferingState<SerializableBufferingStateType::kPipeline>{
+      media::SerializableBufferingState<
+          media::SerializableBufferingStateType::kPipeline>{
           state, reason, for_suspended_start});
 
-  if (state == BUFFERING_HAVE_ENOUGH && !for_suspended_start)
+  if (state == media::BUFFERING_HAVE_ENOUGH && !for_suspended_start)
     media_metrics_provider_->SetHaveEnough();
 
-  if (state == BUFFERING_HAVE_ENOUGH) {
+  if (state == media::BUFFERING_HAVE_ENOUGH) {
     TRACE_EVENT1("media", "WebMediaPlayerImpl::BufferingHaveEnough", "id",
                  media_log_->id());
     // The SetReadyState() call below may clear
@@ -2196,7 +2206,7 @@
       playback_events_recorder_->OnBufferingComplete();
   } else {
     // Buffering has underflowed.
-    DCHECK_EQ(state, BUFFERING_HAVE_NOTHING);
+    DCHECK_EQ(state, media::BUFFERING_HAVE_NOTHING);
 
     // Report the number of times we've entered the underflow state. Ensure we
     // only report the value when transitioning from HAVE_ENOUGH to
@@ -2220,8 +2230,8 @@
   // If this is an NNR, then notify the smoothness helper about it.  Note that
   // it's unclear what we should do if there is no smoothness helper yet.  As it
   // is, we just discard the NNR.
-  if (state == BUFFERING_HAVE_NOTHING && reason == DECODER_UNDERFLOW &&
-      smoothness_helper_) {
+  if (state == media::BUFFERING_HAVE_NOTHING &&
+      reason == media::DECODER_UNDERFLOW && smoothness_helper_) {
     smoothness_helper_->NotifyNNR();
   }
 
@@ -2242,7 +2252,7 @@
     return;
 
   client_->DurationChanged();
-  MediaContentType content_type = GetMediaContentType();
+  media::MediaContentType content_type = GetMediaContentType();
   client_->DidMediaMetadataChange(delegate_has_audio_, HasVideo(),
                                   content_type);
   delegate_->DidMediaMetadataChange(delegate_id_, delegate_has_audio_,
@@ -2252,8 +2262,8 @@
     watch_time_reporter_->OnDurationChanged(GetPipelineMediaDuration());
 }
 
-void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config,
-                                        AddTextTrackDoneCB done_cb) {
+void WebMediaPlayerImpl::OnAddTextTrack(const media::TextTrackConfig& config,
+                                        media::AddTextTrackDoneCB done_cb) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   const WebInbandTextTrackImpl::Kind web_kind =
@@ -2266,19 +2276,19 @@
   std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track(
       new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id));
 
-  std::unique_ptr<TextTrack> text_track(new TextTrackImpl(
+  std::unique_ptr<media::TextTrack> text_track(new TextTrackImpl(
       main_task_runner_, client_, std::move(web_inband_text_track)));
 
   std::move(done_cb).Run(std::move(text_track));
 }
 
-void WebMediaPlayerImpl::OnWaiting(WaitingReason reason) {
+void WebMediaPlayerImpl::OnWaiting(media::WaitingReason reason) {
   DVLOG(2) << __func__ << ": reason=" << static_cast<int>(reason);
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   switch (reason) {
-    case WaitingReason::kNoCdm:
-    case WaitingReason::kNoDecryptionKey:
+    case media::WaitingReason::kNoCdm:
+    case media::WaitingReason::kNoDecryptionKey:
       encrypted_client_->DidBlockPlaybackWaitingForKey();
       // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called
       // when a key has been successfully added (e.g. OnSessionKeysChange() with
@@ -2293,7 +2303,7 @@
     // TODO(xhwang): Handle this in PipelineController when we have a clearer
     // picture on how to refactor WebMediaPlayerImpl, PipelineController and
     // PipelineImpl.
-    case WaitingReason::kDecoderStateLost:
+    case media::WaitingReason::kDecoderStateLost:
       pipeline_controller_->OnDecoderStateLost();
       return;
   }
@@ -2365,7 +2375,8 @@
   UpdateSmoothnessHelper();
 }
 
-void WebMediaPlayerImpl::OnAudioConfigChange(const AudioDecoderConfig& config) {
+void WebMediaPlayerImpl::OnAudioConfigChange(
+    const media::AudioDecoderConfig& config) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   DCHECK_NE(ready_state_, WebMediaPlayer::kReadyStateHaveNothing);
 
@@ -2388,7 +2399,8 @@
     UpdateSecondaryProperties();
 }
 
-void WebMediaPlayerImpl::OnVideoConfigChange(const VideoDecoderConfig& config) {
+void WebMediaPlayerImpl::OnVideoConfigChange(
+    const media::VideoDecoderConfig& config) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   DCHECK_NE(ready_state_, WebMediaPlayer::kReadyStateHaveNothing);
 
@@ -2419,7 +2431,7 @@
 }
 
 void WebMediaPlayerImpl::OnAudioPipelineInfoChange(
-    const AudioPipelineInfo& info) {
+    const media::AudioPipelineInfo& info) {
   media_metrics_provider_->SetAudioPipelineInfo(info);
   if (info.decoder_type == audio_decoder_type_)
     return;
@@ -2434,7 +2446,7 @@
 }
 
 void WebMediaPlayerImpl::OnVideoPipelineInfoChange(
-    const VideoPipelineInfo& info) {
+    const media::VideoPipelineInfo& info) {
   media_metrics_provider_->SetVideoPipelineInfo(info);
   if (info.decoder_type == video_decoder_type_)
     return;
@@ -2586,14 +2598,15 @@
   ScheduleRestart();
 }
 
-void WebMediaPlayerImpl::OnRemotePlayStateChange(MediaStatus::State state) {
+void WebMediaPlayerImpl::OnRemotePlayStateChange(
+    media::MediaStatus::State state) {
   DCHECK(is_flinging_);
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
-  if (state == MediaStatus::State::PLAYING && Paused()) {
+  if (state == media::MediaStatus::State::PLAYING && Paused()) {
     DVLOG(1) << __func__ << " requesting PLAY.";
     client_->ResumePlayback();
-  } else if (state == MediaStatus::State::PAUSED && !Paused()) {
+  } else if (state == media::MediaStatus::State::PAUSED && !Paused()) {
     DVLOG(1) << __func__ << " requesting PAUSE.";
     client_->PausePlayback();
   }
@@ -2613,7 +2626,7 @@
 
   if (!success) {
     SetNetworkState(WebMediaPlayer::kNetworkStateFormatError);
-    media_metrics_provider_->OnError(PIPELINE_ERROR_NETWORK);
+    media_metrics_provider_->OnError(media::PIPELINE_ERROR_NETWORK);
 
     // Not really necessary, since the pipeline was never started, but it at
     // least this makes sure that the error handling code is in sync.
@@ -2657,13 +2670,13 @@
   DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay);
   // TODO(liberato): |token| should already be a RoutingToken.
   overlay_routing_token_is_pending_ = false;
-  overlay_routing_token_ = OverlayInfo::RoutingToken(token);
+  overlay_routing_token_ = media::OverlayInfo::RoutingToken(token);
   MaybeSendOverlayInfoToDecoder();
 }
 
 void WebMediaPlayerImpl::OnOverlayInfoRequested(
     bool decoder_requires_restart_for_overlay,
-    ProvideOverlayInfoCB provide_overlay_info_cb) {
+    media::ProvideOverlayInfoCB provide_overlay_info_cb) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   // If we get a non-null cb, a decoder is initializing and requires overlay
@@ -2732,17 +2745,17 @@
   }
 }
 
-std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer(
-    absl::optional<RendererType> renderer_type) {
+std::unique_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer(
+    absl::optional<media::RendererType> renderer_type) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   // Make sure that overlays are enabled if they're always allowed.
   if (always_enable_overlays_)
     EnableOverlay();
 
-  RequestOverlayInfoCB request_overlay_info_cb;
+  media::RequestOverlayInfoCB request_overlay_info_cb;
 #if defined(OS_ANDROID)
-  request_overlay_info_cb = BindToCurrentLoop(base::BindRepeating(
+  request_overlay_info_cb = media::BindToCurrentLoop(base::BindRepeating(
       &WebMediaPlayerImpl::OnOverlayInfoRequested, weak_this_));
 #endif
 
@@ -2771,20 +2784,20 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb =
-      BindToCurrentLoop(base::BindRepeating(
+      media::BindToCurrentLoop(base::BindRepeating(
           &WebMediaPlayerImpl::OnEncryptedMediaInitData, weak_this_));
 
   vfc_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&VideoFrameCompositor::SetOnNewProcessedFrameCallback,
                      base::Unretained(compositor_.get()),
-                     BindToCurrentLoop(base::BindOnce(
+                     media::BindToCurrentLoop(base::BindOnce(
                          &WebMediaPlayerImpl::OnFirstFrame, weak_this_))));
 
 #if defined(OS_ANDROID)
-  if (demuxer_found_hls_ ||
-      renderer_factory_selector_->GetCurrentFactory()
-              ->GetRequiredMediaResourceType() == MediaResource::Type::URL) {
+  if (demuxer_found_hls_ || renderer_factory_selector_->GetCurrentFactory()
+                                    ->GetRequiredMediaResourceType() ==
+                                media::MediaResource::Type::URL) {
     // MediaPlayerRendererClientFactory is the only factory that a uses
     // MediaResource::Type::URL for the moment.
     using_media_player_renderer_ = true;
@@ -2793,13 +2806,13 @@
     // reporter.
     video_decode_stats_reporter_.reset();
 
-    SetDemuxer(std::make_unique<MediaUrlDemuxer>(
+    SetDemuxer(std::make_unique<media::MediaUrlDemuxer>(
         media_task_runner_, loaded_url_,
         frame_->GetDocument().SiteForCookies().RepresentativeUrl(),
         frame_->GetDocument().TopFrameOrigin(),
         allow_media_player_renderer_credentials_, demuxer_found_hls_));
-    pipeline_controller_->Start(Pipeline::StartType::kNormal, demuxer_.get(),
-                                this, false, false);
+    pipeline_controller_->Start(media::Pipeline::StartType::kNormal,
+                                demuxer_.get(), this, false, false);
     return;
   }
 #endif  // defined(OS_ANDROID)
@@ -2817,29 +2830,30 @@
 
 #if BUILDFLAG(ENABLE_FFMPEG)
     Demuxer::MediaTracksUpdatedCB media_tracks_updated_cb =
-        BindToCurrentLoop(base::BindRepeating(
+        media::BindToCurrentLoop(base::BindRepeating(
             &WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated, weak_this_));
 
-    SetDemuxer(std::make_unique<FFmpegDemuxer>(
+    SetDemuxer(std::make_unique<media::FFmpegDemuxer>(
         media_task_runner_, data_source_.get(), encrypted_media_init_data_cb,
         media_tracks_updated_cb, media_log_.get(), IsLocalFile(loaded_url_)));
 #else
-    OnError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN);
+    OnError(media::PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN);
     return;
 #endif
   } else {
     DCHECK(!chunk_demuxer_);
     DCHECK(!data_source_);
 
-    chunk_demuxer_ =
-        new ChunkDemuxer(BindToCurrentLoop(base::BindOnce(
-                             &WebMediaPlayerImpl::OnDemuxerOpened, weak_this_)),
-                         BindToCurrentLoop(base::BindRepeating(
-                             &WebMediaPlayerImpl::OnProgress, weak_this_)),
-                         encrypted_media_init_data_cb, media_log_.get());
+    chunk_demuxer_ = new media::ChunkDemuxer(
+        media::BindToCurrentLoop(
+            base::BindOnce(&WebMediaPlayerImpl::OnDemuxerOpened, weak_this_)),
+        media::BindToCurrentLoop(
+            base::BindRepeating(&WebMediaPlayerImpl::OnProgress, weak_this_)),
+        encrypted_media_init_data_cb, media_log_.get());
     SetDemuxer(std::unique_ptr<Demuxer>(chunk_demuxer_));
 
-    if (base::FeatureList::IsEnabled(kMemoryPressureBasedSourceBufferGC)) {
+    if (base::FeatureList::IsEnabled(
+            media::kMemoryPressureBasedSourceBufferGC)) {
       // base::Unretained is safe because |this| owns memory_pressure_listener_.
       memory_pressure_listener_ =
           std::make_unique<base::MemoryPressureListener>(
@@ -2850,13 +2864,14 @@
   }
 
   // If possible attempt to avoid decoder spool up until playback starts.
-  Pipeline::StartType start_type = Pipeline::StartType::kNormal;
+  auto start_type = media::Pipeline::StartType::kNormal;
   if (!chunk_demuxer_ && preload_ == MultiBufferDataSource::METADATA &&
       !client_->CouldPlayIfEnoughData() && !IsStreaming()) {
     start_type =
-        (has_poster_ || base::FeatureList::IsEnabled(kPreloadMetadataLazyLoad))
-            ? Pipeline::StartType::kSuspendAfterMetadata
-            : Pipeline::StartType::kSuspendAfterMetadataForAudioOnly;
+        (has_poster_ ||
+         base::FeatureList::IsEnabled(media::kPreloadMetadataLazyLoad))
+            ? media::Pipeline::StartType::kSuspendAfterMetadata
+            : media::Pipeline::StartType::kSuspendAfterMetadataForAudioOnly;
     attempting_suspended_start_ = true;
   }
 
@@ -2901,8 +2916,8 @@
   return audio_source_provider_;
 }
 
-scoped_refptr<VideoFrame> WebMediaPlayerImpl::GetCurrentFrameFromCompositor()
-    const {
+scoped_refptr<media::VideoFrame>
+WebMediaPlayerImpl::GetCurrentFrameFromCompositor() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
 
@@ -2911,7 +2926,7 @@
     return nullptr;
 
   // Can be null.
-  scoped_refptr<VideoFrame> video_frame =
+  scoped_refptr<media::VideoFrame> video_frame =
       compositor_->GetCurrentFrameOnAnyThread();
 
   // base::Unretained is safe here because |compositor_| is destroyed on
@@ -2938,7 +2953,7 @@
     bool at_beginning =
         ready_state_ == WebMediaPlayer::kReadyStateHaveNothing ||
         CurrentTime() == 0.0;
-    if (!at_beginning || GetPipelineMediaDuration() == kInfiniteDuration)
+    if (!at_beginning || GetPipelineMediaDuration() == media::kInfiniteDuration)
       can_auto_suspend = false;
   }
 
@@ -3197,7 +3212,7 @@
   // base::Unretained() is safe here. |demuxer_| is destroyed on the main
   // thread, but before doing it ~WebMediaPlayerImpl() posts a media thread task
   // that deletes media_thread_mem_dumper_ and  waits for it to finish.
-  media_thread_mem_dumper_ = std::make_unique<MemoryDumpProviderProxy>(
+  media_thread_mem_dumper_ = std::make_unique<media::MemoryDumpProviderProxy>(
       "WebMediaPlayer_MediaThread", media_task_runner_,
       base::BindRepeating(&WebMediaPlayerImpl::OnMediaThreadMemoryDump,
                           media_log_->id(), base::Unretained(demuxer_.get())));
@@ -3230,7 +3245,7 @@
 void WebMediaPlayerImpl::FinishMemoryUsageReport(int64_t demuxer_memory_usage) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
-  const PipelineStatistics stats = GetPipelineStatistics();
+  const auto stats = GetPipelineStatistics();
   const int64_t data_source_memory_usage =
       data_source_ ? data_source_->GetMemoryUsage() : 0;
 
@@ -3245,8 +3260,8 @@
       stats.video_memory_usage +
       ((pipeline_metadata_.has_video && !stats.video_memory_usage &&
         has_first_frame_)
-           ? VideoFrame::AllocationSize(PIXEL_FORMAT_I420,
-                                        pipeline_metadata_.natural_size)
+           ? media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
+                                               pipeline_metadata_.natural_size)
            : 0);
 
   const int64_t current_memory_usage =
@@ -3268,7 +3283,7 @@
     int32_t id,
     const base::trace_event::MemoryDumpArgs& args,
     base::trace_event::ProcessMemoryDump* pmd) {
-  const PipelineStatistics stats = GetPipelineStatistics();
+  const auto stats = GetPipelineStatistics();
   auto player_node_name =
       base::StringPrintf("media/webmediaplayer/player_0x%x", id);
   auto* player_node = pmd->CreateAllocatorDump(player_node_name);
@@ -3337,10 +3352,10 @@
 
   // Create the watch time reporter and synchronize its initial state.
   watch_time_reporter_ = std::make_unique<blink::WatchTimeReporter>(
-      mojom::PlaybackProperties::New(
+      media::mojom::PlaybackProperties::New(
           pipeline_metadata_.has_audio, has_video, false, false,
           !!chunk_demuxer_, is_encrypted_, embedded_media_experience_enabled_,
-          mojom::MediaStreamType::kNone),
+          media::mojom::MediaStreamType::kNone),
       pipeline_metadata_.natural_size,
       base::BindRepeating(&WebMediaPlayerImpl::GetCurrentTimeInternal,
                           base::Unretained(this)),
@@ -3384,7 +3399,7 @@
 
 void WebMediaPlayerImpl::UpdateSecondaryProperties() {
   watch_time_reporter_->UpdateSecondaryProperties(
-      mojom::SecondaryPlaybackProperties::New(
+      media::mojom::SecondaryPlaybackProperties::New(
           pipeline_metadata_.audio_decoder_config.codec(),
           pipeline_metadata_.video_decoder_config.codec(),
           pipeline_metadata_.audio_decoder_config.profile(),
@@ -3407,7 +3422,7 @@
 
 bool WebMediaPlayerImpl::DoesOverlaySupportMetadata() const {
   return pipeline_metadata_.video_decoder_config.video_transformation() ==
-         kNoTransformation;
+         media::kNoTransformation;
 }
 
 void WebMediaPlayerImpl::UpdateRemotePlaybackCompatibility(bool is_compatible) {
@@ -3452,8 +3467,9 @@
 }
 
 void WebMediaPlayerImpl::RequestVideoFrameCallback() {
-  compositor_->SetOnFramePresentedCallback(BindToCurrentLoop(base::BindOnce(
-      &WebMediaPlayerImpl::OnNewFramePresentedCallback, weak_this_)));
+  compositor_->SetOnFramePresentedCallback(
+      media::BindToCurrentLoop(base::BindOnce(
+          &WebMediaPlayerImpl::OnNewFramePresentedCallback, weak_this_)));
 }
 
 void WebMediaPlayerImpl::OnNewFramePresentedCallback() {
@@ -3563,7 +3579,7 @@
     return true;
 
   // Otherwise, only optimize videos with shorter average keyframe distance.
-  PipelineStatistics stats = GetPipelineStatistics();
+  auto stats = GetPipelineStatistics();
   return stats.video_keyframe_distance_average <
          kMaxKeyframeDistanceToDisableBackgroundVideo;
 }
@@ -3640,11 +3656,11 @@
 }
 
 void WebMediaPlayerImpl::SetPipelineStatisticsForTest(
-    const PipelineStatistics& stats) {
+    const media::PipelineStatistics& stats) {
   pipeline_statistics_for_test_ = absl::make_optional(stats);
 }
 
-PipelineStatistics WebMediaPlayerImpl::GetPipelineStatistics() const {
+media::PipelineStatistics WebMediaPlayerImpl::GetPipelineStatistics() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
 
   return pipeline_statistics_for_test_.value_or(
@@ -3663,8 +3679,8 @@
       pipeline_controller_->GetMediaDuration());
 }
 
-MediaContentType WebMediaPlayerImpl::GetMediaContentType() const {
-  return DurationToMediaContentType(GetPipelineMediaDuration());
+media::MediaContentType WebMediaPlayerImpl::GetMediaContentType() const {
+  return media::DurationToMediaContentType(GetPipelineMediaDuration());
 }
 
 void WebMediaPlayerImpl::SwitchToRemoteRenderer(
@@ -3690,7 +3706,7 @@
 }
 
 void WebMediaPlayerImpl::SwitchToLocalRenderer(
-    MediaObserverClient::ReasonToSwitchToLocal reason) {
+    media::MediaObserverClient::ReasonToSwitchToLocal reason) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   if (!is_remote_rendering_)
     return;  // Is currently with local renderer.
@@ -3784,11 +3800,11 @@
 
 void WebMediaPlayerImpl::RecordEncryptionScheme(
     const std::string& stream_name,
-    EncryptionScheme encryption_scheme) {
+    media::EncryptionScheme encryption_scheme) {
   DCHECK(stream_name == "Audio" || stream_name == "Video");
 
   // If the stream is not encrypted, don't record it.
-  if (encryption_scheme == EncryptionScheme::kUnencrypted)
+  if (encryption_scheme == media::EncryptionScheme::kUnencrypted)
     return;
 
   base::UmaHistogramEnumeration(
@@ -3842,7 +3858,7 @@
 
 void WebMediaPlayerImpl::UpdateSmoothnessHelper() {
   // If the experiment flag is off, then do nothing.
-  if (!base::FeatureList::IsEnabled(kMediaLearningSmoothnessExperiment))
+  if (!base::FeatureList::IsEnabled(media::kMediaLearningSmoothnessExperiment))
     return;
 
   // If we're paused, or if we can't get all the features, then clear any
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc b/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc
index b9ea900..d14062b 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl_unittest.cc
@@ -192,7 +192,7 @@
   MockWebMediaPlayerEncryptedMediaClient() = default;
 
   MOCK_METHOD3(Encrypted,
-               void(EmeInitDataType, const unsigned char*, unsigned));
+               void(media::EmeInitDataType, const unsigned char*, unsigned));
   MOCK_METHOD0(DidBlockPlaybackWaitingForKey, void());
   MOCK_METHOD0(DidResumePlaybackBlockedForKey, void());
 
@@ -217,7 +217,8 @@
     observer_ = nullptr;
   }
 
-  MOCK_METHOD4(DidMediaMetadataChange, void(int, bool, bool, MediaContentType));
+  MOCK_METHOD4(DidMediaMetadataChange,
+               void(int, bool, bool, media::MediaContentType));
 
   void DidPlay(int player_id) override { DCHECK_EQ(player_id_, player_id); }
 
@@ -303,7 +304,7 @@
   MOCK_METHOD0(
       GetLastPresentedFrameMetadata,
       std::unique_ptr<blink::WebMediaPlayer::VideoFramePresentationMetadata>());
-  MOCK_METHOD0(GetCurrentFrameOnAnyThread, scoped_refptr<VideoFrame>());
+  MOCK_METHOD0(GetCurrentFrameOnAnyThread, scoped_refptr<media::VideoFrame>());
   MOCK_METHOD1(UpdateCurrentFrameIfStale,
                void(VideoFrameCompositor::UpdateType));
   MOCK_METHOD3(EnableSubmission,
@@ -340,7 +341,7 @@
                                                   blink::LocalFrameToken(),
                                                   nullptr)),
         context_provider_(viz::TestContextProvider::Create()),
-        audio_parameters_(TestAudioParameters::Normal()),
+        audio_parameters_(media::TestAudioParameters::Normal()),
         memory_dump_manager_(
             base::trace_event::MemoryDumpManager::CreateInstanceForTesting()),
         agent_group_scheduler_(std::move(agent_group_scheduler)) {
@@ -384,7 +385,7 @@
  protected:
   void InitializeWebMediaPlayerImplInternal(
       std::unique_ptr<media::Demuxer> demuxer_override) {
-    auto media_log = std::make_unique<NiceMock<MockMediaLog>>();
+    auto media_log = std::make_unique<NiceMock<media::MockMediaLog>>();
     InitializeSurfaceLayerBridge();
 
     // Retain a raw pointer to |media_log| for use by tests. Meanwhile, give its
@@ -393,30 +394,31 @@
     ASSERT_FALSE(media_log_) << "Reinitialization of media_log_ is disallowed";
     media_log_ = media_log.get();
 
-    auto factory_selector = std::make_unique<RendererFactorySelector>();
+    auto factory_selector = std::make_unique<media::RendererFactorySelector>();
     renderer_factory_selector_ = factory_selector.get();
     decoder_factory_ = std::make_unique<media::DefaultDecoderFactory>(nullptr);
 #if defined(OS_ANDROID)
     factory_selector->AddBaseFactory(
-        RendererType::kDefault,
-        std::make_unique<DefaultRendererFactory>(
+        media::RendererType::kDefault,
+        std::make_unique<media::DefaultRendererFactory>(
             media_log.get(), decoder_factory_.get(),
-            DefaultRendererFactory::GetGpuFactoriesCB()));
+            media::DefaultRendererFactory::GetGpuFactoriesCB()));
     factory_selector->StartRequestRemotePlayStateCB(base::DoNothing());
 #else
     factory_selector->AddBaseFactory(
-        RendererType::kDefault,
-        std::make_unique<DefaultRendererFactory>(
+        media::RendererType::kDefault,
+        std::make_unique<media::DefaultRendererFactory>(
             media_log.get(), decoder_factory_.get(),
-            DefaultRendererFactory::GetGpuFactoriesCB(), nullptr));
+            media::DefaultRendererFactory::GetGpuFactoriesCB(), nullptr));
 #endif
 
-    mojo::Remote<mojom::MediaMetricsProvider> provider;
-    MediaMetricsProvider::Create(
-        MediaMetricsProvider::BrowsingMode::kNormal,
-        MediaMetricsProvider::FrameStatus::kNotTopFrame, ukm::kInvalidSourceId,
-        learning::FeatureValue(0), VideoDecodePerfHistory::SaveCallback(),
-        MediaMetricsProvider::GetLearningSessionCallback(),
+    mojo::Remote<media::mojom::MediaMetricsProvider> provider;
+    media::MediaMetricsProvider::Create(
+        media::MediaMetricsProvider::BrowsingMode::kNormal,
+        media::MediaMetricsProvider::FrameStatus::kNotTopFrame,
+        ukm::kInvalidSourceId, media::learning::FeatureValue(0),
+        media::VideoDecodePerfHistory::SaveCallback(),
+        media::MediaMetricsProvider::GetLearningSessionCallback(),
         base::BindRepeating(
             &WebMediaPlayerImplTest::GetRecordAggregateWatchTimeCallback,
             base::Unretained(this)),
@@ -425,10 +427,11 @@
     // Initialize provider since none of the tests below actually go through the
     // full loading/pipeline initialize phase. If this ever changes the provider
     // will start DCHECK failing.
-    provider->Initialize(false, mojom::MediaURLScheme::kHttp,
-                         mojom::MediaStreamType::kNone);
+    provider->Initialize(false, media::mojom::MediaURLScheme::kHttp,
+                         media::mojom::MediaStreamType::kNone);
 
-    audio_sink_ = base::WrapRefCounted(new NiceMock<MockAudioRendererSink>());
+    audio_sink_ =
+        base::WrapRefCounted(new NiceMock<media::MockAudioRendererSink>());
 
     url_index_ = std::make_unique<UrlIndex>(&mock_resource_fetch_context_,
                                             media_thread_.task_runner());
@@ -439,7 +442,7 @@
         media_thread_.task_runner(), media_thread_.task_runner(),
         base::BindRepeating(&WebMediaPlayerImplTest::OnAdjustAllocatedMemory,
                             base::Unretained(this)),
-        nullptr, RequestRoutingTokenCallback(), nullptr, false, false,
+        nullptr, media::RequestRoutingTokenCallback(), nullptr, false, false,
         provider.Unbind(),
         base::BindOnce(&WebMediaPlayerImplTest::CreateMockSurfaceLayerBridge,
                        base::Unretained(this)),
@@ -486,7 +489,7 @@
     wmpi_->OnDurationChange();
   }
 
-  MediaMetricsProvider::RecordAggregateWatchTimeCallback
+  media::MediaMetricsProvider::RecordAggregateWatchTimeCallback
   GetRecordAggregateWatchTimeCallback() {
     return base::NullCallback();
   }
@@ -529,21 +532,21 @@
     }
   }
 
-  void SetError(PipelineStatus status = PIPELINE_ERROR_DECODE) {
+  void SetError(media::PipelineStatus status = media::PIPELINE_ERROR_DECODE) {
     wmpi_->OnError(status);
   }
 
-  void OnMetadata(const PipelineMetadata& metadata) {
+  void OnMetadata(const media::PipelineMetadata& metadata) {
     wmpi_->OnMetadata(metadata);
   }
 
-  void OnWaiting(WaitingReason reason) { wmpi_->OnWaiting(reason); }
+  void OnWaiting(media::WaitingReason reason) { wmpi_->OnWaiting(reason); }
 
   void OnVideoNaturalSizeChange(const gfx::Size& size) {
     wmpi_->OnVideoNaturalSizeChange(size);
   }
 
-  void OnVideoConfigChange(const VideoDecoderConfig& config) {
+  void OnVideoConfigChange(const media::VideoDecoderConfig& config) {
     wmpi_->OnVideoConfigChange(config);
   }
 
@@ -658,7 +661,7 @@
     return wmpi_->video_decode_stats_reporter_.get();
   }
 
-  VideoCodecProfile GetVideoStatsReporterCodecProfile() const {
+  media::VideoCodecProfile GetVideoStatsReporterCodecProfile() const {
     DCHECK(GetVideoStatsReporter());
     return GetVideoStatsReporter()->codec_profile_;
   }
@@ -671,10 +674,11 @@
     return wmpi_->mb_data_source_->media_has_played();
   }
 
-  scoped_refptr<VideoFrame> CreateFrame() {
+  scoped_refptr<media::VideoFrame> CreateFrame() {
     gfx::Size size(8, 8);
-    return VideoFrame::CreateFrame(PIXEL_FORMAT_I420, size, gfx::Rect(size),
-                                   size, base::TimeDelta());
+    return media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_I420, size,
+                                          gfx::Rect(size), size,
+                                          base::TimeDelta());
   }
 
   void RequestVideoFrameCallback() { wmpi_->RequestVideoFrameCallback(); }
@@ -685,7 +689,7 @@
 
   void OnNewFramePresentedCallback() { wmpi_->OnNewFramePresentedCallback(); }
 
-  scoped_refptr<VideoFrame> GetCurrentFrameFromCompositor() {
+  scoped_refptr<media::VideoFrame> GetCurrentFrameFromCompositor() {
     return wmpi_->GetCurrentFrameFromCompositor();
   }
 
@@ -724,7 +728,8 @@
     base::RunLoop().RunUntilIdle();
 
     // Load a real media file into memory.
-    scoped_refptr<DecoderBuffer> data = ReadTestDataFile(data_file);
+    scoped_refptr<media::DecoderBuffer> data =
+        media::ReadTestDataFile(data_file);
 
     // "Serve" the file to the DataSource. Note: We respond with 200 okay, which
     // will prevent range requests or partial responses from being used. For
@@ -808,7 +813,7 @@
 
     base::RunLoop run_loop;
     WebContentDecryptionModuleImpl::Create(
-        &mock_cdm_factory_, key_system, test_origin, CdmConfig(),
+        &mock_cdm_factory_, key_system, test_origin, media::CdmConfig(),
         base::BindOnce(&WebMediaPlayerImplTest::OnCdmCreated,
                        base::Unretained(this), run_loop.QuitClosure()));
     run_loop.Run();
@@ -822,10 +827,10 @@
     wmpi_->SetCdmInternal(web_cdm_.get());
   }
 
-  MemoryDumpProviderProxy* GetMainThreadMemDumper() {
+  media::MemoryDumpProviderProxy* GetMainThreadMemDumper() {
     return wmpi_->main_thread_mem_dumper_.get();
   }
-  MemoryDumpProviderProxy* GetMediaThreadMemDumper() {
+  media::MemoryDumpProviderProxy* GetMediaThreadMemDumper() {
     return wmpi_->media_thread_mem_dumper_.get();
   }
 
@@ -843,12 +848,12 @@
   scoped_refptr<viz::TestContextProvider> context_provider_;
   NiceMock<MockVideoFrameCompositor>* compositor_;
 
-  scoped_refptr<NiceMock<MockAudioRendererSink>> audio_sink_;
+  scoped_refptr<NiceMock<media::MockAudioRendererSink>> audio_sink_;
   MockResourceFetchContext mock_resource_fetch_context_;
-  std::unique_ptr<media::UrlIndex> url_index_;
+  std::unique_ptr<UrlIndex> url_index_;
 
   // Audio hardware configuration.
-  AudioParameters audio_parameters_;
+  media::AudioParameters audio_parameters_;
 
   bool is_background_suspend_enabled_ = false;
   bool is_background_video_playback_enabled_ = true;
@@ -857,11 +862,12 @@
   NiceMock<MockWebMediaPlayerClient> client_;
   MockWebMediaPlayerEncryptedMediaClient encrypted_client_;
 
-  // Used to create the MockCdm to test encrypted playback.
-  scoped_refptr<MockCdm> mock_cdm_{new MockCdm()};
-  MockCdmFactory mock_cdm_factory_{mock_cdm_};
+  // Used to create the media::MockCdm to test encrypted playback.
+  scoped_refptr<media::MockCdm> mock_cdm_ =
+      base::MakeRefCounted<media::MockCdm>();
+  media::MockCdmFactory mock_cdm_factory_{mock_cdm_};
   std::unique_ptr<blink::WebContentDecryptionModule> web_cdm_;
-  MockCdmContext mock_cdm_context_;
+  media::MockCdmContext mock_cdm_context_;
 
   viz::FrameSinkId frame_sink_id_ = viz::FrameSinkId(1, 1);
   viz::LocalSurfaceId local_surface_id_ =
@@ -877,16 +883,16 @@
 
   // Only valid once set by InitializeWebMediaPlayerImpl(), this is for
   // verifying a subset of potential media logs.
-  NiceMock<MockMediaLog>* media_log_ = nullptr;
+  NiceMock<media::MockMediaLog>* media_log_ = nullptr;
 
   // Total memory in bytes allocated by the WebMediaPlayerImpl instance.
   int64_t reported_memory_ = 0;
 
-  // Raw pointer of the RendererFactorySelector owned by |wmpi_|.
-  RendererFactorySelector* renderer_factory_selector_ = nullptr;
+  // Raw pointer of the media::RendererFactorySelector owned by |wmpi_|.
+  media::RendererFactorySelector* renderer_factory_selector_ = nullptr;
 
   // default decoder factory for WMPI
-  std::unique_ptr<DecoderFactory> decoder_factory_;
+  std::unique_ptr<media::DecoderFactory> decoder_factory_;
 
   // The WebMediaPlayerImpl instance under test.
   std::unique_ptr<WebMediaPlayerImpl> wmpi_;
@@ -1083,7 +1089,7 @@
 // Verify that lazy load for preload=metadata works properly.
 TEST_F(WebMediaPlayerImplTest, LazyLoadPreloadMetadataSuspend) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(kPreloadMetadataLazyLoad);
+  scoped_feature_list.InitAndEnableFeature(media::kPreloadMetadataLazyLoad);
   InitializeWebMediaPlayerImpl();
   EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false));
   wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData);
@@ -1348,7 +1354,7 @@
 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendNoResume) {
   SetUpMediaSuspend(true);
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(kResumeBackgroundVideo);
+  scoped_feature_list.InitAndDisableFeature(media::kResumeBackgroundVideo);
 
   InitializeWebMediaPlayerImpl();
   SetMetadata(true, true);
@@ -1371,7 +1377,7 @@
 TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendWithResume) {
   SetUpMediaSuspend(true);
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(kResumeBackgroundVideo);
+  scoped_feature_list.InitAndEnableFeature(media::kResumeBackgroundVideo);
 
   InitializeWebMediaPlayerImpl();
   SetMetadata(true, true);
@@ -1535,7 +1541,7 @@
 }
 
 TEST_F(WebMediaPlayerImplTest, ResumeEnded) {
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config = TestVideoConfig::Normal();
   metadata.has_audio = true;
@@ -1563,7 +1569,7 @@
 }
 
 TEST_F(WebMediaPlayerImplTest, AutoplayMuted) {
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config = TestVideoConfig::Normal();
   metadata.has_audio = true;
@@ -1679,16 +1685,17 @@
 }
 
 // It's possible for current time to be infinite if the page seeks to
-// |kInfiniteDuration| (2**64 - 1) when duration is infinite.
+// |media::kInfiniteDuration| (2**64 - 1) when duration is infinite.
 TEST_F(WebMediaPlayerImplTest, MediaPositionState_InfiniteCurrentTime) {
   InitializeWebMediaPlayerImpl();
-  SetDuration(kInfiniteDuration);
+  SetDuration(media::kInfiniteDuration);
   wmpi_->OnTimeUpdate();
 
-  EXPECT_CALL(client_, DidPlayerMediaPositionStateChange(
-                           0.0, kInfiniteDuration, kInfiniteDuration,
-                           /*end_of_media=*/false));
-  wmpi_->Seek(kInfiniteDuration.InSecondsF());
+  EXPECT_CALL(client_,
+              DidPlayerMediaPositionStateChange(0.0, media::kInfiniteDuration,
+                                                media::kInfiniteDuration,
+                                                /*end_of_media=*/false));
+  wmpi_->Seek(media::kInfiniteDuration.InSecondsF());
   wmpi_->OnTimeUpdate();
 
   testing::Mock::VerifyAndClearExpectations(&client_);
@@ -1699,7 +1706,7 @@
 
 TEST_F(WebMediaPlayerImplTest, NoStreams) {
   InitializeWebMediaPlayerImpl();
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
 
   EXPECT_CALL(client_, SetCcLayer(_)).Times(0);
   EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer()).Times(0);
@@ -1730,7 +1737,7 @@
   {
     base::RunLoop run_loop;
     EXPECT_CALL(encrypted_client_,
-                Encrypted(EmeInitDataType::WEBM, NotNull(), Gt(0u)));
+                Encrypted(media::EmeInitDataType::WEBM, NotNull(), Gt(0u)));
     EXPECT_CALL(encrypted_client_, DidBlockPlaybackWaitingForKey());
     EXPECT_CALL(encrypted_client_, DidResumePlaybackBlockedForKey())
         .WillRepeatedly(RunClosure(run_loop.QuitClosure()));
@@ -1769,12 +1776,12 @@
   EXPECT_CALL(encrypted_client_, DidBlockPlaybackWaitingForKey());
   EXPECT_CALL(encrypted_client_, DidResumePlaybackBlockedForKey());
 
-  OnWaiting(WaitingReason::kNoDecryptionKey);
+  OnWaiting(media::WaitingReason::kNoDecryptionKey);
 }
 
 ACTION(ReportHaveEnough) {
-  arg0->OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
-                               BUFFERING_CHANGE_REASON_UNKNOWN);
+  arg0->OnBufferingStateChange(media::BUFFERING_HAVE_ENOUGH,
+                               media::BUFFERING_CHANGE_REASON_UNKNOWN);
 }
 
 #if defined(OS_WIN)
@@ -1786,19 +1793,19 @@
   // Use MockRendererFactory for kMediaFoundation where the created Renderer
   // will take the CDM, complete Renderer initialization and report HAVE_ENOUGH
   // so that WMPI can reach kReadyStateHaveCurrentData.
-  auto mock_renderer_factory = std::make_unique<MockRendererFactory>();
+  auto mock_renderer_factory = std::make_unique<media::MockRendererFactory>();
   EXPECT_CALL(*mock_renderer_factory, CreateRenderer(_, _, _, _, _, _))
       .WillOnce(testing::WithoutArgs(Invoke([]() {
         auto mock_renderer = std::make_unique<NiceMock<MockRenderer>>();
         EXPECT_CALL(*mock_renderer, OnSetCdm(_, _))
             .WillOnce(RunOnceCallback<1>(true));
         EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
-            .WillOnce(DoAll(RunOnceCallback<2>(PIPELINE_OK),
+            .WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
                             WithArg<1>(ReportHaveEnough())));
         return mock_renderer;
       })));
 
-  renderer_factory_selector_->AddFactory(RendererType::kMediaFoundation,
+  renderer_factory_selector_->AddFactory(media::RendererType::kMediaFoundation,
                                          std::move(mock_renderer_factory));
 
   // Create and set CDM. The CDM doesn't support a Decryptor and requires Media
@@ -1813,7 +1820,7 @@
 
   // Load encrypted media and expect encrypted event.
   EXPECT_CALL(encrypted_client_,
-              Encrypted(EmeInitDataType::WEBM, NotNull(), Gt(0u)));
+              Encrypted(media::EmeInitDataType::WEBM, NotNull(), Gt(0u)));
 
   base::RunLoop run_loop;
   // MediaFoundationRenderer doesn't use AudioService.
@@ -1826,10 +1833,10 @@
 
 TEST_F(WebMediaPlayerImplTest, VideoConfigChange) {
   InitializeWebMediaPlayerImpl();
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
-  metadata.video_decoder_config =
-      TestVideoConfig::NormalCodecProfile(kCodecVP9, VP9PROFILE_PROFILE0);
+  metadata.video_decoder_config = TestVideoConfig::NormalCodecProfile(
+      media::kCodecVP9, media::VP9PROFILE_PROFILE0);
   metadata.natural_size = gfx::Size(320, 240);
 
   // Arrival of metadata should trigger creation of reporter with video config
@@ -1837,42 +1844,43 @@
   OnMetadata(metadata);
   VideoDecodeStatsReporter* last_reporter = GetVideoStatsReporter();
   ASSERT_NE(nullptr, last_reporter);
-  ASSERT_EQ(VP9PROFILE_PROFILE0, GetVideoStatsReporterCodecProfile());
+  ASSERT_EQ(media::VP9PROFILE_PROFILE0, GetVideoStatsReporterCodecProfile());
 
   // Changing the codec profile should trigger recreation of the reporter.
-  auto new_profile_config =
-      TestVideoConfig::NormalCodecProfile(kCodecVP9, VP9PROFILE_PROFILE1);
+  auto new_profile_config = TestVideoConfig::NormalCodecProfile(
+      media::kCodecVP9, media::VP9PROFILE_PROFILE1);
   OnVideoConfigChange(new_profile_config);
-  ASSERT_EQ(VP9PROFILE_PROFILE1, GetVideoStatsReporterCodecProfile());
+  ASSERT_EQ(media::VP9PROFILE_PROFILE1, GetVideoStatsReporterCodecProfile());
   ASSERT_NE(last_reporter, GetVideoStatsReporter());
   last_reporter = GetVideoStatsReporter();
 
   // Changing the codec (implies changing profile) should similarly trigger
   // recreation of the reporter.
-  auto new_codec_config = TestVideoConfig::NormalCodecProfile(kCodecVP8);
+  auto new_codec_config = TestVideoConfig::NormalCodecProfile(media::kCodecVP8);
   OnVideoConfigChange(new_codec_config);
-  ASSERT_EQ(VP8PROFILE_MIN, GetVideoStatsReporterCodecProfile());
+  ASSERT_EQ(media::VP8PROFILE_MIN, GetVideoStatsReporterCodecProfile());
   ASSERT_NE(last_reporter, GetVideoStatsReporter());
   last_reporter = GetVideoStatsReporter();
 
   // Changing other aspects of the config (like colorspace) should not trigger
   // recreation of the reporter
-  VideoDecoderConfig new_color_config = TestVideoConfig::NormalWithColorSpace(
-      kCodecVP8, VideoColorSpace::REC709());
-  ASSERT_EQ(VP8PROFILE_MIN, new_color_config.profile());
+  media::VideoDecoderConfig new_color_config =
+      TestVideoConfig::NormalWithColorSpace(media::kCodecVP8,
+                                            media::VideoColorSpace::REC709());
+  ASSERT_EQ(media::VP8PROFILE_MIN, new_color_config.profile());
   OnVideoConfigChange(new_color_config);
   ASSERT_EQ(last_reporter, GetVideoStatsReporter());
-  ASSERT_EQ(VP8PROFILE_MIN, GetVideoStatsReporterCodecProfile());
+  ASSERT_EQ(media::VP8PROFILE_MIN, GetVideoStatsReporterCodecProfile());
 
   EXPECT_CALL(*surface_layer_bridge_ptr_, ClearObserver());
 }
 
 TEST_F(WebMediaPlayerImplTest, NaturalSizeChange) {
   InitializeWebMediaPlayerImpl();
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
-  metadata.video_decoder_config =
-      TestVideoConfig::NormalCodecProfile(kCodecVP8, VP8PROFILE_MIN);
+  metadata.video_decoder_config = TestVideoConfig::NormalCodecProfile(
+      media::kCodecVP8, media::VP8PROFILE_MIN);
   metadata.natural_size = gfx::Size(320, 240);
 
   OnMetadata(metadata);
@@ -1898,10 +1906,10 @@
 
 TEST_F(WebMediaPlayerImplTest, NaturalSizeChange_Rotated) {
   InitializeWebMediaPlayerImpl();
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config =
-      TestVideoConfig::NormalRotated(VIDEO_ROTATION_90);
+      TestVideoConfig::NormalRotated(media::VIDEO_ROTATION_90);
   metadata.natural_size = gfx::Size(320, 240);
 
   OnMetadata(metadata);
@@ -1930,7 +1938,7 @@
   InitializeWebMediaPlayerImpl();
 
   // Setting metadata initializes |watch_time_reporter_| used in play().
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config = TestVideoConfig::Normal();
 
@@ -1994,10 +2002,10 @@
 // Verifies that an infinite duration doesn't muck up GetCurrentTimeInternal.
 TEST_F(WebMediaPlayerImplTest, InfiniteDuration) {
   InitializeWebMediaPlayerImpl();
-  SetDuration(kInfiniteDuration);
+  SetDuration(media::kInfiniteDuration);
 
   // Send metadata so we have a watch time reporter created.
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config = TestVideoConfig::Normal();
   metadata.has_audio = true;
@@ -2025,10 +2033,10 @@
 TEST_F(WebMediaPlayerImplTest, SetContentsLayerGetsWebLayerFromBridge) {
   InitializeWebMediaPlayerImpl();
 
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   metadata.video_decoder_config =
-      TestVideoConfig::NormalRotated(VIDEO_ROTATION_90);
+      TestVideoConfig::NormalRotated(media::VIDEO_ROTATION_90);
   metadata.natural_size = gfx::Size(320, 240);
 
   EXPECT_CALL(client_, SetCcLayer(_)).Times(0);
@@ -2079,7 +2087,7 @@
   EXPECT_CALL(*compositor_, EnableSubmission(_, _, _));
   EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
 
-  PipelineMetadata metadata;
+  media::PipelineMetadata metadata;
   metadata.has_video = true;
   OnMetadata(metadata);
 
@@ -2209,17 +2217,17 @@
 // Verify that a demuxer override is used when specified.
 // TODO(https://crbug.com/1084476): This test is flaky.
 TEST_F(WebMediaPlayerImplTest, DISABLED_DemuxerOverride) {
-  std::unique_ptr<MockDemuxer> demuxer =
-      std::make_unique<NiceMock<MockDemuxer>>();
-  StrictMock<MockDemuxerStream> stream(DemuxerStream::AUDIO);
+  std::unique_ptr<media::MockDemuxer> demuxer =
+      std::make_unique<NiceMock<media::MockDemuxer>>();
+  StrictMock<media::MockDemuxerStream> stream(media::DemuxerStream::AUDIO);
   stream.set_audio_decoder_config(TestAudioConfig::Normal());
-  std::vector<DemuxerStream*> streams;
+  std::vector<media::DemuxerStream*> streams;
   streams.push_back(&stream);
 
   EXPECT_CALL(stream, SupportsConfigChanges()).WillRepeatedly(Return(false));
 
   EXPECT_CALL(*demuxer.get(), OnInitialize(_, _))
-      .WillOnce(RunOnceCallback<1>(PIPELINE_OK));
+      .WillOnce(RunOnceCallback<1>(media::PIPELINE_OK));
   EXPECT_CALL(*demuxer.get(), GetAllStreams()).WillRepeatedly(Return(streams));
   // Called when WebMediaPlayerImpl is destroyed.
   EXPECT_CALL(*demuxer.get(), Stop());
@@ -2263,21 +2271,21 @@
     if (IsBackgroundPauseOn()) {
       if (!enabled_features.empty())
         enabled_features += ",";
-      enabled_features += kBackgroundVideoPauseOptimization.name;
+      enabled_features += media::kBackgroundVideoPauseOptimization.name;
     } else {
       if (!disabled_features.empty())
         disabled_features += ",";
-      disabled_features += kBackgroundVideoPauseOptimization.name;
+      disabled_features += media::kBackgroundVideoPauseOptimization.name;
     }
 
     if (IsResumeBackgroundVideoEnabled()) {
       if (!enabled_features.empty())
         enabled_features += ",";
-      enabled_features += kResumeBackgroundVideo.name;
+      enabled_features += media::kResumeBackgroundVideo.name;
     } else {
       if (!disabled_features.empty())
         disabled_features += ",";
-      disabled_features += kResumeBackgroundVideo.name;
+      disabled_features += media::kResumeBackgroundVideo.name;
     }
 
     feature_list_.InitFromCommandLine(enabled_features, disabled_features);
@@ -2304,7 +2312,7 @@
   }
 
   void SetVideoKeyframeDistanceAverage(base::TimeDelta value) {
-    PipelineStatistics statistics;
+    media::PipelineStatistics statistics;
     statistics.video_keyframe_distance_average = value;
     wmpi_->SetPipelineStatisticsForTest(statistics);
   }
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
index 63df799..e7819a50 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_test.cc
@@ -8,7 +8,10 @@
 #include "base/logging.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "media/base/media_switches.h"
 #include "media/video/mock_gpu_video_accelerator_factories.h"
 #include "media/video/mock_video_encode_accelerator.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -74,7 +77,12 @@
         mock_gpu_factories_(
             new media::MockGpuVideoAcceleratorFactories(nullptr)),
         idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
-                     base::WaitableEvent::InitialState::NOT_SIGNALED) {}
+                     base::WaitableEvent::InitialState::NOT_SIGNALED) {
+#if defined(ARCH_CPU_X86_FAMILY) && BUILDFLAG(IS_CHROMEOS_ASH)
+    // TODO(crbug.com/1186051): remove once enabled by default.
+    feature_list_.InitAndEnableFeature(media::kVp9kSVCHWEncoding);
+#endif  // defined(ARCH_CPU_X86_FAMILY) && BUILDFLAG(IS_CHROMEOS_ASH)
+  }
 
   media::MockVideoEncodeAccelerator* ExpectCreateInitAndDestroyVEA() {
     // The VEA will be owned by the RTCVideoEncoder once
@@ -308,6 +316,7 @@
   std::unique_ptr<EncodedImageCallbackWrapper> callback_wrapper_;
   base::WaitableEvent idle_waiter_;
   size_t num_spatial_layers_;
+  base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_P(RTCVideoEncoderTest, CreateAndInitSucceeds) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index ff367bb7..3216ff05 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1759,6 +1759,13 @@
       status: "experimental",
     },
     {
+      name: "PrivateNetworkAccessNonSecureContextsAllowed",
+      origin_trial_feature_name: "PrivateNetworkAccessNonSecureContextsAllowed",
+      origin_trial_type: "deprecation",
+      origin_trial_allows_insecure: true,
+      status: "experimental",
+    },
+    {
       name: "PushMessaging",
       status: "stable",
     },
@@ -1885,6 +1892,10 @@
       name: "SanitizerAPI",
       status: "experimental",
     },
+    {
+      name: "SchedulerCurrentTaskSignal",
+      status: "experimental",
+    },
     // WebSpeech API with both speech recognition and synthesis functionality
     // is not fully enabled on all platforms.
     {
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
index f6fa54a..5bc618b 100644
--- a/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h
@@ -7,8 +7,6 @@
 
 #include "third_party/blink/renderer/platform/platform_export.h"
 
-#include <random>
-
 #include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
index 9c6a390..ca6f11e 100644
--- a/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc
@@ -21,7 +21,9 @@
       budget_pool_controller_(budget_pool_controller),
       is_enabled_(true) {}
 
-BudgetPool::~BudgetPool() = default;
+BudgetPool::~BudgetPool() {
+  DCHECK_EQ(0u, associated_task_queues_.size());
+}
 
 const char* BudgetPool::Name() const {
   return name_;
diff --git a/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.cc b/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.cc
index 7e3fc68..fc298f38 100644
--- a/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.cc
+++ b/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.cc
@@ -12,7 +12,9 @@
 UkmTaskSampler::UkmTaskSampler(double thread_time_sampling_rate,
                                double ukm_task_sampling_rate)
     : thread_time_sampling_rate_(clampTo(thread_time_sampling_rate, 0.0, 1.0)),
-      ukm_task_sampling_rate_(clampTo(ukm_task_sampling_rate, 0.0, 1.0)) {}
+      ukm_task_sampling_rate_(clampTo(ukm_task_sampling_rate, 0.0, 1.0)) {
+  random_generator_.Seed();
+}
 
 double UkmTaskSampler::GetConditionalSamplingProbability(bool has_thread_time) {
   if (thread_time_sampling_rate_ == 0.0 || ukm_task_sampling_rate_ == 0.0 ||
@@ -42,8 +44,7 @@
 
 bool UkmTaskSampler::ShouldRecordTaskUkm(bool has_thread_time) {
   double probability = GetConditionalSamplingProbability(has_thread_time);
-  std::bernoulli_distribution dist(probability);
-  return dist(random_generator_);
+  return random_generator_.RandDouble() < probability;
 }
 
 void UkmTaskSampler::SetUkmTaskSamplingRate(double rate) {
diff --git a/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.h b/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.h
index 40c95b3..4bc9276 100644
--- a/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.h
+++ b/third_party/blink/renderer/platform/scheduler/common/ukm_task_sampler.h
@@ -5,9 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_UKM_TASK_SAMPLER_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_UKM_TASK_SAMPLER_H_
 
-#include <random>
-
 #include "base/gtest_prod_util.h"
+#include "base/rand_util.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 
 namespace blink {
@@ -47,7 +46,7 @@
   double thread_time_sampling_rate_;
   double ukm_task_sampling_rate_;
 
-  std::mt19937_64 random_generator_;
+  base::InsecureRandomGenerator random_generator_;
 };
 
 }  // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index bbe6cf81..efb242b 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -1370,6 +1370,13 @@
 std::unique_ptr<WebSchedulingTaskQueue>
 FrameSchedulerImpl::CreateWebSchedulingTaskQueue(
     WebSchedulingPriority priority) {
+  // The QueueTraits for scheduler.postTask() are similar to those of
+  // setTimeout() (deferrable queue traits + throttling for delayed tasks), with
+  // the following differences:
+  //  1. All delayed tasks are intensively throttled (no nesting-level exception
+  //     or policy/flag opt-out)
+  //  2. There is no separate PrioritisationType (prioritization is based on the
+  //     WebSchedulingPriority, which is only set for these task queues)
   scoped_refptr<MainThreadTaskQueue> immediate_task_queue =
       frame_task_queue_controller_->NewWebSchedulingTaskQueue(
           DeferrableTaskQueueTraits(), priority);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index 1f97f072..6786c77 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -2843,17 +2843,14 @@
 TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrderDelayedTasks) {
   Vector<String> run_order;
 
-  // We're relying on all of the delays to expire at the same time, in which
-  // case the tasks will run in the updated priority order.
-  PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2",
+  PostWebSchedulingTestTasks(&run_order, "U1 U2 V1 V2",
                              base::TimeDelta::FromMilliseconds(5));
   task_queues_[static_cast<int>(WebSchedulingPriority::kUserBlockingPriority)]
       ->SetPriority(WebSchedulingPriority::kBackgroundPriority);
 
   task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
 
-  EXPECT_THAT(run_order,
-              testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2"));
+  EXPECT_THAT(run_order, testing::ElementsAre("V1", "V2", "U1", "U2"));
 }
 
 // Verify that tasks posted with TaskType::kJavascriptTimerDelayed* and
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
index c53e239..ea8df41 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -95,6 +95,7 @@
       current_task_slice_start_time_(now),
       safepoints_in_current_toplevel_task_count_(0) {
   main_thread_load_tracker_.Resume(now);
+  random_generator_.Seed();
   if (renderer_backgrounded) {
     background_main_thread_load_tracker_.Resume(now);
   } else {
@@ -200,11 +201,6 @@
 
   last_reported_task_ = task_timing.end_time();
 
-  UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime2",
-                              base::saturated_cast<base::HistogramBase::Sample>(
-                                  duration.InMicroseconds()),
-                              1, 1000 * 1000, 50);
-
   // We want to measure thread time here, but for efficiency reasons
   // we stick with wall time.
   main_thread_load_tracker_.RecordTaskTime(task_timing.start_time(),
@@ -213,6 +209,16 @@
                                                       task_timing.end_time());
   background_main_thread_load_tracker_.RecordTaskTime(task_timing.start_time(),
                                                       task_timing.end_time());
+  // WARNING: All code below must be compatible with down-sampling.
+  constexpr double kSamplingProbabily = .01;
+  bool should_sample = random_generator_.RandDouble() < kSamplingProbabily;
+  if (!should_sample)
+    return;
+
+  UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime2",
+                              base::saturated_cast<base::HistogramBase::Sample>(
+                                  duration.InMicroseconds()),
+                              1, 1000 * 1000, 50);
 
   if (safepoints_in_current_toplevel_task_count_ > 0) {
     FrameStatus frame_status =
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
index 7be28bc..9db90ac 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_METRICS_HELPER_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_METRICS_HELPER_H_
 
+#include "base/rand_util.h"
 #include "base/time/time.h"
 #include "components/scheduling_metrics/task_duration_metric_reporter.h"
 #include "components/scheduling_metrics/total_duration_metric_reporter.h"
@@ -124,6 +125,8 @@
   // cooperative scheduling had a chance to run a task (as we don't necessarily
   // run a task in each safepoint).
   int safepoints_in_current_toplevel_task_count_;
+
+  base::InsecureRandomGenerator random_generator_;
 };
 
 }  // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
index 18b3e76..cd0acea3 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -7,7 +7,6 @@
 
 #include <map>
 #include <memory>
-#include <random>
 #include <stack>
 
 #include "base/atomicops.h"
diff --git a/third_party/blink/renderer/platform/text/locale_mac.mm b/third_party/blink/renderer/platform/text/locale_mac.mm
index aa3216e..0e908ad 100644
--- a/third_party/blink/renderer/platform/text/locale_mac.mm
+++ b/third_party/blink/renderer/platform/text/locale_mac.mm
@@ -34,8 +34,8 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
 #include "third_party/blink/renderer/platform/language.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/web_test_support.h"
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
index b377c80..e520e42f 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
+++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -486,7 +486,7 @@
   }
 #endif  // defined(OS_WIN)
   if (planes.empty()) {
-    if (base::FeatureList::IsEnabled(media::kMultiPlaneSharedImageVideo)) {
+    if (base::FeatureList::IsEnabled(media::kMultiPlaneVideoSharedImages)) {
       planes.push_back(gfx::BufferPlane::Y);
       planes.push_back(gfx::BufferPlane::UV);
     } else {
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
index 487d9d3..b354311 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -27,9 +27,11 @@
 from blinkpy.web_tests.port.android import ANDROID_DISABLED_TESTS
 
 MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
+MOCK_GEN = '/mock-checkout/out/Release/gen/'
 MANIFEST_INSTALL_CMD = [
     'python3', '/mock-checkout/third_party/wpt_tools/wpt/wpt', 'manifest',
-    '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt'
+    '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt',
+    '--path', MOCK_GEN + 'external/wpt/MANIFEST.json'
 ]
 
 
@@ -526,7 +528,12 @@
         host.filesystem.write_text_file(
             MOCK_WEB_TESTS + 'external/wpt/MANIFEST.json', '{}')
         importer._generate_manifest()
-        self.assertEqual(host.executive.calls, [MANIFEST_INSTALL_CMD] * 2)
+        install_cmd = [
+            'python3', '/mock-checkout/third_party/wpt_tools/wpt/wpt', 'manifest',
+            '-v', '--no-download', '--tests-root', MOCK_WEB_TESTS + 'external/wpt',
+            '--path', MOCK_WEB_TESTS + 'external/wpt/MANIFEST.json'
+        ]
+        self.assertEqual(host.executive.calls, [MANIFEST_INSTALL_CMD, install_cmd])
         self.assertEqual(importer.chromium_git.added_paths,
                          {MOCK_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME})
 
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
index b95556e..06d468b 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_expectations_updater_unittest.py
@@ -26,6 +26,7 @@
 from blinkpy.web_tests.port.factory_mock import MockPortFactory
 
 MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
+MOCK_GEN = '/mock-checkout/out/Release/gen/'
 
 class WPTExpectationsUpdaterTest(LoggingTestCase):
     def mock_host(self):
@@ -824,7 +825,7 @@
         host.filesystem.maybe_make_directory(
             port.web_tests_dir(), 'wpt_internal')
         host.filesystem.copyfile(
-            host.filesystem.join(port.web_tests_dir(),
+            host.filesystem.join(MOCK_GEN,
                                  'external', 'wpt', MANIFEST_NAME),
             host.filesystem.join(port.web_tests_dir(), 'wpt_internal',
                                  MANIFEST_NAME))
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
index d45ced9e..c78f391 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
@@ -102,9 +102,10 @@
 
     @property
     def wpt_dir(self):
-        return self.host.filesystem.dirname(
-            self.host.filesystem.relpath(
-                self.wpt_manifest_path, self.port.web_tests_dir()))
+        if 'external' in self.wpt_manifest_path:
+            return 'external/wpt'
+        else:
+            return 'wpt_internal'
 
     def _items_for_file_path(self, path_in_wpt):
         """Finds manifest items for the given WPT path.
@@ -285,18 +286,21 @@
         return self.test_name_to_file.get(url)
 
     @staticmethod
-    def ensure_manifest(port, path=None):
+    def ensure_manifest(port, path=None, manifest_path=None):
         """Regenerates the WPT MANIFEST.json file.
 
         Args:
             port: A blinkpy.web_tests.port.Port object.
             path: The path to a WPT root (relative to web_tests, optional).
+            manifest_path: The path to the new manifest file
         """
         fs = port.host.filesystem
         if path is None:
             path = fs.join('external', 'wpt')
         wpt_path = fs.join(port.web_tests_dir(), path)
-        manifest_path = fs.join(wpt_path, MANIFEST_NAME)
+        if manifest_path is None:
+            manifest_path = fs.join(wpt_path, MANIFEST_NAME)
+        fs.maybe_make_directory(fs.dirname(manifest_path))
 
         # Unconditionally delete local MANIFEST.json to avoid regenerating the
         # manifest from scratch (when version is bumped) or invalid/out-of-date
@@ -317,7 +321,7 @@
                 _log.error('Manifest base not found at "%s".',
                            base_manifest_path)
 
-        WPTManifest.generate_manifest(port, wpt_path)
+        WPTManifest.generate_manifest(port, wpt_path, manifest_path)
 
         if fs.isfile(manifest_path):
             _log.debug('Manifest generation completed.')
@@ -328,14 +332,17 @@
             fs.write_text_file(manifest_path, '{}')
 
     @staticmethod
-    def generate_manifest(port, dest_path):
+    def generate_manifest(port, dest_path, manifest_path=None):
         """Generates MANIFEST.json on the specified directory."""
+        if manifest_path is None:
+            fs = port.host.filesystem
+            manifest_path = fs.join(dest_path, MANIFEST_NAME)
         wpt_exec_path = PathFinder(
             port.host.filesystem).path_from_chromium_base(
                 'third_party', 'wpt_tools', 'wpt', 'wpt')
         cmd = [
             port.python3_command(), wpt_exec_path, 'manifest', '-v',
-            '--no-download', '--tests-root', dest_path
+            '--no-download', '--tests-root', dest_path, '--path', manifest_path
         ]
 
         # ScriptError will be raised if the command fails.
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
index 7449816f..b653d29 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
@@ -31,6 +31,8 @@
             '--no-download',
             '--tests-root',
             WEB_TEST_DIR + '/external/wpt',
+            '--path',
+            WEB_TEST_DIR + '/external/wpt/MANIFEST.json'
         ]])
 
     def test_ensure_manifest_updates_manifest_if_it_exists(self):
@@ -55,6 +57,8 @@
             '--no-download',
             '--tests-root',
             WEB_TEST_DIR + '/external/wpt',
+            '--path',
+            WEB_TEST_DIR + '/external/wpt/MANIFEST.json'
         ]])
 
     def test_ensure_manifest_raises_exception(self):
@@ -77,6 +81,8 @@
             '--no-download',
             '--tests-root',
             WEB_TEST_DIR + '/wpt_internal',
+            '--path',
+            WEB_TEST_DIR + '/wpt_internal/MANIFEST.json',
         ]])
 
     def test_does_not_throw_when_missing_some_test_types(self):
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py
index 747edb7..d0bd482 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/base.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -1021,12 +1021,11 @@
         assert path in self.WPT_DIRS
         # Convert '/' to the platform-specific separator.
         path = self._filesystem.normpath(path)
-        manifest_path = self._filesystem.join(self.web_tests_dir(), path,
-                                              MANIFEST_NAME)
+        manifest_path = self._build_path('gen', path, MANIFEST_NAME)
         if not self._filesystem.exists(manifest_path) or self.get_option(
                 'manifest_update', False):
             _log.debug('Generating MANIFEST.json for %s...', path)
-            WPTManifest.ensure_manifest(self, path)
+            WPTManifest.ensure_manifest(self, path, manifest_path)
         return WPTManifest(self.host, manifest_path)
 
     def is_wpt_crash_test(self, test_name):
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
index 08a3012d..d5209f22 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/base_unittest.py
@@ -779,7 +779,7 @@
         port.set_option_default('manifest_update', False)
         filesystem = port.host.filesystem
         filesystem.write_text_file(
-            WEB_TEST_DIR + '/external/wpt/MANIFEST.json', '{}')
+            '/mock-checkout/out/Release/gen' + '/external/wpt/MANIFEST.json', '{}')
         filesystem.clear_written_files()
 
         port.wpt_manifest('external/wpt')
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/test.py b/third_party/blink/tools/blinkpy/web_tests/port/test.py
index 1b88176..23b7ef2 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/test.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/test.py
@@ -530,7 +530,7 @@
     port.set_option_default('manifest_update', False)
     filesystem = port.host.filesystem
     filesystem.write_text_file(
-        WEB_TEST_DIR + '/external/wpt/MANIFEST.json',
+        '/mock-checkout/out/Release/gen' + '/external/wpt/MANIFEST.json',
         json.dumps({
             'items': {
                 'testharness': {
@@ -610,7 +610,7 @@
         WEB_TEST_DIR + '/external/wpt/common/blank.html', 'foo')
 
     filesystem.write_text_file(
-        WEB_TEST_DIR + '/wpt_internal/MANIFEST.json',
+        '/mock-checkout/out/Release/gen' + '/wpt_internal/MANIFEST.json',
         json.dumps({
             'items': {
                 'testharness': {
diff --git a/third_party/blink/tools/gen_manifest.py b/third_party/blink/tools/gen_manifest.py
new file mode 100755
index 0000000..e96c0a5
--- /dev/null
+++ b/third_party/blink/tools/gen_manifest.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import errno
+import os
+import shutil
+import subprocess
+import sys
+
+SRC_DIR = os.path.abspath(
+    os.path.join(os.path.dirname(__file__),
+                 os.pardir, os.pardir, os.pardir))
+WPT_EXEC_PATH = os.path.join(SRC_DIR, 'third_party', 'wpt_tools', 'wpt', 'wpt')
+BASE_MANIFEST_PATH = os.path.join(SRC_DIR, 'third_party', 'blink',
+                                  'web_tests', 'external',
+                                  'WPT_BASE_MANIFEST_8.json')
+MANIFEST_NAME = 'MANIFEST.json'
+
+def maybe_make_directory(path):
+    try:
+        os.makedirs(path)
+    except OSError as error:
+        if error.errno != errno.EEXIST:
+            raise
+
+def main() :
+    usage = "Generate manifest for web test..."
+    parser = argparse.ArgumentParser(
+        add_help=False, prog='gen_manifest.py', usage=usage)
+    parser.add_argument('--out', required=True,
+                        help='Path of the output directory')
+    options = parser.parse_args()
+    if options.out.startswith('//'):
+        options.out = os.path.join(SRC_DIR, options.out[2:])
+
+    WPT_DIRS = ['wpt_internal', 'external/wpt']
+    for path in WPT_DIRS:
+        print('Generating MANIFEST.json for %s...' % path)
+        wpt_path = os.path.join(SRC_DIR, 'third_party',
+                                'blink', 'web_tests', path)
+        manifest_path = os.path.join(options.out, path, MANIFEST_NAME)
+        if 'external' in path:
+            maybe_make_directory(os.path.dirname(manifest_path))
+            shutil.copyfile(BASE_MANIFEST_PATH, manifest_path)
+        cmd = [
+            sys.executable, WPT_EXEC_PATH, 'manifest', '-v',
+            '--no-download', '--tests-root', wpt_path, '--path', manifest_path
+        ]
+        subprocess.check_output(cmd)
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index da4af36..e43eb1a 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -833,7 +833,7 @@
 # MathML depends on LayoutNG.
 crbug.com/6606 external/wpt/mathml/* [ Skip ]
 
-crbug.com/1034944 webexposed/global-interface-listing.html [ Skip ]
+crbug.com/1034944 http/tests/webexposed/global-interface-listing.php [ Skip ]
 
 # TODO(iopopesc) these need to be rebaselined for focus ring changes.
 crbug.com/1035582 fast/css/focus-ring-detached.html [ Failure ]
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
index d3793919..cb8f3d0 100644
--- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
+++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -6,7 +6,6 @@
 # crbug.com/1138028 tracks the removal of these failure expectations
 
 # Crashes
-crbug.com/1012242 external/wpt/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html [ CRASH ]
 crbug.com/1225856 virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-display-none-editable.html [ CRASH ]
 crbug.com/1225860 crbug.com/926685 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-010.html [ CRASH ]
 crbug.com/1225860 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-017.html [ CRASH ]
diff --git a/third_party/blink/web_tests/FlagExpectations/highdpi b/third_party/blink/web_tests/FlagExpectations/highdpi
index 653dc48..c6aba30 100644
--- a/third_party/blink/web_tests/FlagExpectations/highdpi
+++ b/third_party/blink/web_tests/FlagExpectations/highdpi
@@ -8,6 +8,7 @@
 external/wpt/* [ Skip ]
 gamepad/* [ Skip ]
 harness-tests/* [ Skip ]
+http/tests/webexposed/* [ Skip ]
 js/* [ Skip ]
 media/* [ Skip ]
 mhtml/* [ Skip ]
@@ -36,7 +37,6 @@
 virtual/threaded-prefer-compositing/* [ Skip ]
 virtual/transform-interop-disabled/* [ Skip ]
 webaudio/* [ Skip ]
-webexposed/* [ Skip ]
 wpt_internal/* [ Skip ]
 
 # TODO(crbug.com/1168836):Enable the following for highdpi.
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index bb6d9a25..f6aa061 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -155,7 +155,7 @@
 crbug.com/948670 [ Debug Mac10.13 ] fast/css3-text/css3-word-break/word-break-all-ascii.html [ Slow ]
 
 # Slow on many platforms.
-crbug.com/866165 webexposed/global-interface-listing.html [ Slow ]
+crbug.com/866165 http/tests/webexposed/global-interface-listing.php [ Slow ]
 
 crbug.com/1074122 http/tests/serviceworker/webexposed/global-interface-listing-service-worker.html [ Slow ]
 
@@ -225,7 +225,7 @@
 
 crbug.com/942951 media/controls/controls-layout-in-different-size.html [ Slow ]
 
-crbug.com/910627 webexposed/global-interface-listing-shared-worker.html [ Slow ]
+crbug.com/910627 http/tests/webexposed/global-interface-listing-shared-worker.php [ Slow ]
 
 ### virtual/gpu/fast/canvas/ blending layout tests are slow
 crbug.com/866850 virtual/gpu/fast/canvas/canvas-blend-image.html [ Slow ]
@@ -653,8 +653,8 @@
 crbug.com/1043792 [ Release Win ] http/tests/devtools/template-content-inspect-crash.js [ Slow ]
 crbug.com/1043792 [ Mac Release ] http/tests/devtools/template-content-inspect-crash.js [ Slow ]
 crbug.com/1043796 [ Release ] http/tests/devtools/coverage/gutter-html.js [ Slow ]
-crbug.com/1043893 [ Debug Mac10.13 ] webexposed/global-interface-listing-dedicated-worker.html [ Slow ]
-crbug.com/1043893 [ Release ] webexposed/global-interface-listing-dedicated-worker.html [ Slow ]
+crbug.com/1043893 [ Debug Mac10.13 ] http/tests/webexposed/global-interface-listing-dedicated-worker.php [ Slow ]
+crbug.com/1043893 [ Release ] http/tests/webexposed/global-interface-listing-dedicated-worker.php [ Slow ]
 crbug.com/1043920 [ Release Win ] http/tests/devtools/stylesheet-source-mapping.js [ Slow ]
 crbug.com/1043920 [ Mac Release ] http/tests/devtools/stylesheet-source-mapping.js [ Slow ]
 crbug.com/1044350 [ Release ] http/tests/devtools/network/network-xhr-replay.js [ Slow ]
diff --git a/third_party/blink/web_tests/SmokeTests b/third_party/blink/web_tests/SmokeTests
index 925745d..8d6495ce 100644
--- a/third_party/blink/web_tests/SmokeTests
+++ b/third_party/blink/web_tests/SmokeTests
@@ -962,7 +962,7 @@
 virtual/stable/http/tests/navigation/location-assign-adds-history-item.html
 virtual/stable/http/tests/navigation/replacestate-base-legal.html
 virtual/stable/http/tests/navigation/useragent.php
-virtual/stable/webexposed/internal-properties-should-not-be-exposed.html
+virtual/stable/http/tests/webexposed/internal-properties-should-not-be-exposed.html
 virtual/threaded-no-composited-antialiasing/animations/stability/pseudo-element-animation-with-marker-crash.html
 virtual/threaded/printing/page-and-element-geometry-match.html
 webaudio/AudioParam/audioparam-setValueCurve-duration.html
@@ -979,9 +979,9 @@
 webaudio/ScriptProcessor/scriptprocessornode-0-output-channels.html
 webaudio/ScriptProcessor/scriptprocessornode-downmix8-2channel-input.html
 webaudio/WaveShaper/waveshaper-364379.html
-webexposed/internal-properties-should-not-be-exposed.html
-webexposed/permissions-attribute.html
-webexposed/web-animations-api.html
+http/tests/webexposed/internal-properties-should-not-be-exposed.html
+http/tests/webexposed/permissions-attribute.html
+http/tests/webexposed/web-animations-api.html
 wpt_internal/geolocation-api/enabled.html
 wpt_internal/presentation/presentationconnectionavailableevent-ctor-mock.html
 wpt_internal/webmidi/permission.html
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 764b9c9..b1c658ba 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1891,7 +1891,7 @@
 
 # crbug.com/1218729 These tests fail when InterestCohortAPIOriginTrial is enabled.
 crbug.com/1218729 http/tests/origin_trials/webexposed/interest-cohort-origin-trial-interfaces.html [ Failure ]
-crbug.com/1218729 virtual/stable/webexposed/feature-policy-features.html [ Failure ]
+crbug.com/1218729 virtual/stable/http/tests/webexposed/feature-policy-features.html [ Failure ]
 
 # This test relies on racy should_send_resource_timing_info_to_parent() flag being sent between processes.
 crbug.com/957181 external/wpt/resource-timing/nested-context-navigations-iframe.html [ Failure Pass ]
@@ -2634,10 +2634,11 @@
 crbug.com/626703 external/wpt/css/css-content/content-none-table.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-content/content-none-select-2.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-content/content-none-span.html [ Failure ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-onsignalingstatechanged.https.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/handover-datachannel.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Timeout ]
+# See also crbug.com/v8/11365 for the failure in addition to timeout
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-onsignalingstatechanged.https.html [ Failure Timeout ]
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/candidate-exchange.https.html [ Failure Timeout ]
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/handover-datachannel.html [ Failure Timeout ]
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Failure Timeout ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-lists/counter-reset-reversed-list-item.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-align/self-alignment/self-align-safe-unsafe-flex-002.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-align/self-alignment/self-align-safe-unsafe-flex-001.html [ Failure ]
@@ -3204,9 +3205,6 @@
 crbug.com/626703 [ Win7 ] external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-backspace.tentative.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/input-events/input-events-get-target-ranges-forwarddelete.tentative.html [ Failure Timeout ]
-crbug.com/626703 external/wpt/streams/transform-streams/patched-global.any.serviceworker.html [ Timeout ]
-crbug.com/626703 external/wpt/streams/transform-streams/patched-global.any.worker.html [ Timeout ]
-crbug.com/626703 external/wpt/streams/transform-streams/patched-global.any.sharedworker.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/css/css-color/t422-rgba-a0.6-a.xht [ Failure ]
 crbug.com/626703 external/wpt/css/css-color/t32-opacity-basic-0.6-a.xht [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/css/css-color/t425-hsla-basic-a.xht [ Failure ]
@@ -4123,7 +4121,6 @@
 crbug.com/1179585 virtual/layout_ng_svg_text/paint/invalidation/svg/transform-text-element.html [ Failure Pass ]
 crbug.com/1179585 [ Mac ] virtual/layout_ng_svg_text/paint/invalidation/svg/tspan-dynamic-positioning.svg [ Failure ]
 crbug.com/1179585 [ Mac ] virtual/layout_ng_svg_text/paint/invalidation/svg/use-detach.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/animations/animate-text-nested-transforms.html [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/batik/text/smallFonts.svg [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/batik/text/textDecoration.svg [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/batik/text/textDecoration2.svg [ Failure ]
@@ -4144,7 +4141,6 @@
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/gradient-userSpaceOnUse-with-percentage.svg [ Pass Skip ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/mouse-move-on-svg-container.xhtml [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/mouse-move-on-svg-container-standalone.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/path-textPath-simulation.svg [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/svg-root-with-opacity.html [ Failure Pass ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/text-match-highlight.html [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/transformed-outlines.svg [ Failure ]
@@ -4174,16 +4170,6 @@
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/selection-dragging-outside-2.html [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/selection-dragging-outside-3.html [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/selection-styles.xhtml [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2.svg [ Failure ]
-crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3.svg [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/surrogate-pair-attribute-positions.html [ Failure Pass ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/text-decorations-in-scaled-pattern.svg [ Failure ]
 crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/text-outline-2.html [ Failure ]
@@ -4396,9 +4382,6 @@
 # Expect to fail. The test is applicable only when DigitalGoods flag is disabled.
 crbug.com/1080870 http/tests/payments/payment-request-app-store-billing-mandatory-total.html [ Failure ]
 
-# Disabled for rolling DevTools change.
-crbug.com/1172300 http/tests/devtools/agents-enable-disable.js [ Skip ]
-
 # Layout Tests on Swarming (Windows) - https://crbug.com/717347
 crbug.com/713094 [ Win ] fast/css/fontfaceset-check-platform-fonts.html [ Failure Pass ]
 
@@ -6906,6 +6889,7 @@
 crbug.com/v8/11365 external/wpt/html/dom/usvstring-reflection.https.html [ Failure Pass ]
 crbug.com/v8/11365 external/wpt/html/semantics/rellist-feature-detection.html [ Failure Pass ]
 crbug.com/v8/11365 external/wpt/html/semantics/embedded-content/the-object-element/usemap-casing.html [ Failure Pass ]
+crbug.com/v8/11365 [ Mac ] external/wpt/html/semantics/forms/input-change-event-properties.html [ Failure Pass ]
 crbug.com/v8/11365 external/wpt/html/webappapis/dynamic-markup-insertion/document-write/contentType.window.html [ Failure Pass ]
 crbug.com/v8/11365 external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator-window-controls-overlay.html [ Failure Pass ]
 crbug.com/v8/11365 external/wpt/input-events/input-events-exec-command.html [ Failure Pass ]
@@ -7052,3 +7036,11 @@
 
 # Sheriff 2021-07-05
 crbug.com/1226445 [ Mac ] virtual/storage-access-api/external/wpt/storage-access-api/storageAccess.testdriver.sub.html [ Failure Pass ]
+
+# DevTools roll
+crbug.com/1223391 http/tests/devtools/security/interstitial-sidebar.js [ Skip ]
+crbug.com/1223391 http/tests/devtools/security/mixed-content-sidebar.js [ Skip ]
+crbug.com/1223391 http/tests/devtools/security/origin-view-then-interstitial.js [ Skip ]
+
+# Sheriff 2021-07-07
+crbug.com/1227092 [ Win ] virtual/scroll-unification/fast/events/selection-autoscroll-borderbelt.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index a15eb40..80d5c22 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -114,9 +114,9 @@
               "http/tests/navigation",
               "http/tests/sendbeacon",
               "http/tests/serviceworker/webexposed",
+              "http/tests/webexposed",
               "inspector-protocol/dom-snapshot",
               "media/stable",
-              "webexposed",
               "compositing/filters"
               ],
     "args": ["--stable-release-mode",
@@ -1101,6 +1101,7 @@
               "external/wpt/accessibility/crashtests/input-time-datalist.html",
               "external/wpt/accessibility/crashtests/map-inside-map.html",
               "external/wpt/accessibility/crashtests/map-inside-map-2.html",
+              "external/wpt/accessibility/crashtests/move-owned-inside-another-owned.html",
               "external/wpt/accessibility/crashtests/slot-assignment-lockup.html",
               "external/wpt/accessibility/crashtests/validation-message.html"],
     "args": ["--force-renderer-accessibility"]
@@ -1124,8 +1125,8 @@
   },
   {
     "prefix": "anonymous-iframe",
-    "bases": ["webexposed/element-instance-property-listing.html",
-              "webexposed/global-interface-listing.html"],
+    "bases": ["http/tests/webexposed/element-instance-property-listing.html",
+              "http/tests/webexposed/global-interface-listing.php"],
     "args": ["--enable-blink-features=AnonymousIframe"]
   },
   {
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 9368e1a..354683da 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
@@ -83654,7 +83654,7 @@
       ]
      ],
      "contain-paint-clip-005.html": [
-      "ff6db1a73078c12e76a1f4f311d33b961dcd7711",
+      "fce4a89fbb8ac2c416798e8ccbc96998fa85b2a5",
       [
        null,
        [
@@ -96797,7 +96797,7 @@
       ]
      ],
      "flexbox_columns.html": [
-      "c89ace569f3833d3c3e1c3a9e7fd61b319293218",
+      "d39c2db55f2a144e5ab9efa713572bd27da72c07",
       [
        null,
        [
@@ -118280,7 +118280,7 @@
       ]
      ],
      "list-marker-alignment.html": [
-      "c147a5f7a717fea0656b2072c39c35994a5cdcb8",
+      "46f63a6981065fe5fce37e12b5022cda535842f0",
       [
        null,
        [
@@ -118293,7 +118293,7 @@
       ]
      ],
      "list-marker-symbol-bidi.html": [
-      "e82d9ae1567111038ee9927bda124956df1ebf03",
+      "47e77be8995331180530ae285f1aad85e7c60989",
       [
        null,
        [
@@ -118318,6 +118318,32 @@
        {}
       ]
      ],
+     "list-style-image-gradients-dynamic.html": [
+      "eb96fdd444f34b5f3958516e70d8fe7bd5ab0068",
+      [
+       null,
+       [
+        [
+         "/css/css-lists/list-style-image-gradients-dynamic-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "list-style-image-gradients.html": [
+      "eb797155643d725e526c17d803f77c2129dda59d",
+      [
+       null,
+       [
+        [
+         "/css/css-lists/list-style-image-gradients-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "list-style-image-zoom-dynamic.html": [
       "d0cd9de0aa74e9de24a19834e173f839c3879421",
       [
@@ -123056,7 +123082,7 @@
       ]
      ],
      "multicol-list-item-001.xht": [
-      "8d32ac31bc49ed0fc21a983fcb89c52932b033f6",
+      "bcf3fa2613e417e691babd51f1d087cc4935768b",
       [
        null,
        [
@@ -128347,7 +128373,7 @@
       ]
      ],
      "position-absolute-dynamic-list-marker.html": [
-      "79535326396e451d0db5ae6b6a1cfe56b810c443",
+      "2e233e882e9469950385ed71515249023fda5733",
       [
        null,
        [
@@ -130901,7 +130927,7 @@
       ]
      ],
      "marker-content-008.tentative.html": [
-      "88aee13dc8c9530967d73da7f09a609a40e483ac",
+      "155b50ab6f0a9f633adbb65aaac0fd5fbdebb066",
       [
        null,
        [
@@ -178661,7 +178687,7 @@
       ]
      ],
      "block-flow-direction-vlr-022.xht": [
-      "abdc5708e1822b2b58edc8e5d2d90fbb1109c800",
+      "6c2f4d3b65514630b4537f0a807b2aaf5ef3a525",
       [
        null,
        [
@@ -178804,7 +178830,7 @@
       ]
      ],
      "block-flow-direction-vrl-021.xht": [
-      "3204969564b2d2979b46b82e22a221afc378fc6b",
+      "41a623db55c06b98211409b72192b187cdd13b62",
       [
        null,
        [
@@ -191635,7 +191661,7 @@
          ]
         ],
         "redefine-attr-mapping.html": [
-         "716b14383860c8061d1f7ca9567e860c529c3aaa",
+         "1656f9f33ebaf59c90849438196a57f072057ae6",
          [
           null,
           [
@@ -225863,7 +225889,7 @@
       []
      ],
      "display-flow-root-list-item-001-ref.html": [
-      "00bfbca26a6036692746a8c2689831f1fcc21427",
+      "7d9199af420f8c00fa18991a530977b91b5b446d",
       []
      ],
      "display-inline-dynamic-001-ref.html": [
@@ -238011,7 +238037,7 @@
       []
      ],
      "inline-list-ref.html": [
-      "ae1570a9703e52bdfdeb4a09b3c954ab92e7a59b",
+      "244aedac881f9b93ad10a3895bbe5ea9d9f6b4ff",
       []
      ],
      "inline-list-with-table-child-ref.html": [
@@ -238063,17 +238089,25 @@
       []
      ],
      "list-marker-alignment-ref.html": [
-      "afd21b0302201655d2f30c89d190dec6e7a1df1f",
+      "acbc73e284c05a74abbfb8ef9b482c1f0228c517",
       []
      ],
      "list-marker-symbol-bidi-ref.html": [
-      "cf213d731f33201fc6863544f18bf97c51eb2a3c",
+      "892933a48f8c28cc1e2eca762c36fff6dcf584db",
       []
      ],
      "list-marker-with-lineheight-and-overflow-hidden-001-ref.html": [
       "ae6486147e28502db80f6b887b1a6b16c30184f2",
       []
      ],
+     "list-style-image-gradients-dynamic-ref.html": [
+      "b8940767e741a363792076964525f154d260e82e",
+      []
+     ],
+     "list-style-image-gradients-ref.html": [
+      "21092dad6e1a71762d588940091d29fa98b84114",
+      []
+     ],
      "list-style-image-zoom-dynamic-ref.html": [
       "09baac4663a16dbc43b6147848a2b16b39b71815",
       []
@@ -238119,7 +238153,7 @@
       []
      ],
      "list-type-none-style-image-ref.html": [
-      "9e72fb310233145c5a6c014c3febb2975586d76d",
+      "e54375fe9b6a899e10317c98a4f42ea87c592285",
       []
      ],
      "list-with-image-display-changed-001-ref.html": [
@@ -239415,11 +239449,11 @@
       []
      ],
      "multicol-span-all-list-item-001-ref.html": [
-      "4f3fe18a6d5804a4a7a6874fd46d5614c0a8dff2",
+      "ff69c3ba7529db6c064fb861bace5bd21f5aeea5",
       []
      ],
      "multicol-span-all-list-item-002-ref.html": [
-      "938dae654045c2cac2def96e42cea2d880ce9d64",
+      "d542342ace02f4040bebba958df2aefda0b596e4",
       []
      ],
      "multicol-span-all-margin-001-ref.xht": [
@@ -240969,7 +241003,7 @@
       []
      ],
      "marker-content-008-ref.html": [
-      "6d5052b378b7a5f626a51cb033fba8f7339192aa",
+      "3e80d5ff54dfd1ba3db54f39091ec93da122b39a",
       []
      ],
      "marker-content-009-ref.html": [
@@ -247385,6 +247419,10 @@
        "2fee6f7c1fc46593f450fac606a651a12403ff72",
        []
       ],
+      "transform-perspective-composition-expected.txt": [
+       "5736b4f2a25b8520be5ad0a4efab3ed557225974",
+       []
+      ],
       "translate-interpolation-expected.txt": [
        "0499ca03b5ee21961e69a72ab904c4110d35d9d9",
        []
@@ -255758,7 +255796,7 @@
          []
         ],
         "redefine-attr-mapping-ref.html": [
-         "57d4fd0a7e206e0c7d90cfd9c6b1a64b8173b376",
+         "385efdf0181f8aea034762173c57386fbb1a157b",
          []
         ],
         "redefine-builtin-ref.html": [
@@ -266628,7 +266666,7 @@
          []
         ],
         "path-objects.yaml": [
-         "36194b19ce3c68aa08b33bfbf55e36d0c7d6c5d2",
+         "0e40e8bb88308a0078fde58f90a6cb3b69898fab",
          []
         ],
         "pixel-manipulation.yaml": [
@@ -266706,7 +266744,7 @@
          []
         ],
         "path-objects.yaml": [
-         "b8906eb650174e6a3625003e9cfa85aab71f7f94",
+         "c10b9d3053a3abb9ceb11eba46f5586cc1ead834",
          []
         ],
         "pixel-manipulation.yaml": [
@@ -266801,7 +266839,7 @@
         []
        ],
        "common.js": [
-        "0e7816d339010b4f4ec720c54c35dd5ca63d22d1",
+        "68f8782b3942ed5eff4bb17fe926a42dbe5bf451",
         []
        ],
        "dispatcher.js": [
@@ -272408,7 +272446,7 @@
        []
       ],
       "summary-text-decoration-ref.html": [
-       "8b6105fd2ec3eaa17ff9f18e50acfe989c4878af",
+       "ffdcfd25fb35bbc0db93bd9c746006d46e304846",
        []
       ]
      },
@@ -280355,6 +280393,10 @@
        "ce65aba18c9483274765cde6f62bdf5fdeea001e",
        []
       ],
+      "display-2-expected.txt": [
+       "61433fd7ac22a82bc3f1fcabb831ecc1e9e45ce0",
+       []
+      ],
       "displaystyle-011-ref.html": [
        "400c46a2456d0e1d4d48860e3ad557fa5d2990ee",
        []
@@ -290096,19 +290138,19 @@
      []
     ],
     "idlharness.any-expected.txt": [
-     "8e0e13d04f3bfff0982c7b495f7c31c8378873c0",
+     "a6650fa0772be58c08b633a61644fe445bd331c8",
      []
     ],
     "idlharness.any.serviceworker-expected.txt": [
-     "8e0e13d04f3bfff0982c7b495f7c31c8378873c0",
+     "a6650fa0772be58c08b633a61644fe445bd331c8",
      []
     ],
     "idlharness.any.sharedworker-expected.txt": [
-     "8e0e13d04f3bfff0982c7b495f7c31c8378873c0",
+     "a6650fa0772be58c08b633a61644fe445bd331c8",
      []
     ],
     "idlharness.any.worker-expected.txt": [
-     "8e0e13d04f3bfff0982c7b495f7c31c8378873c0",
+     "a6650fa0772be58c08b633a61644fe445bd331c8",
      []
     ],
     "readable-byte-streams": {
@@ -292395,7 +292437,7 @@
    "urlpattern": {
     "resources": {
      "urlpatterntestdata.json": [
-      "019bf4f9170abd0818b1b5e86396264691bc9211",
+      "8715b60bd85401eea104abe952a55d20fc63aa43",
       []
      ],
      "urlpatterntests.js": [
@@ -311704,6 +311746,17 @@
       ]
      ]
     },
+    "getRandomValues-bigint.tentative.any.js": [
+     "9daa92a83b6073f147913ac52325e297806f6c72",
+     [
+      "WebCryptoAPI/getRandomValues-bigint.tentative.any.html",
+      {}
+     ],
+     [
+      "WebCryptoAPI/getRandomValues-bigint.tentative.any.worker.html",
+      {}
+     ]
+    ],
     "getRandomValues.any.js": [
      "473d57fc460917535719607a4bd13fe8f8e9547f",
      [
@@ -347811,7 +347864,7 @@
        ]
       ],
       "transform-perspective-composition.html": [
-       "82f8dad59b6590c325ae7b4d2de7cf7b72959c71",
+       "f1b0256faa96e98e7c5615a1095518b671c87357",
        [
         null,
         {}
@@ -396382,6 +396435,13 @@
          {}
         ]
        ],
+       "2d.path.roundrect.radius.negative.html": [
+        "01ad92ea5c0a5b2730981f38f7708a955e5f1996",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.path.roundrect.radius.none.html": [
         "b55d1eca654065329ff34622d270f938aa2e7214",
         [
@@ -406408,6 +406468,20 @@
          {}
         ]
        ],
+       "2d.path.roundrect.radius.negative.html": [
+        "4c973738583f00755a45c218292633e38c0715b2",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.path.roundrect.radius.negative.worker.js": [
+        "b941725dd30356e0ec46a7ea69cce4fc79a3c21f",
+        [
+         "html/canvas/offscreen/path-objects/2d.path.roundrect.radius.negative.worker.html",
+         {}
+        ]
+       ],
        "2d.path.roundrect.radius.none.html": [
         "6defab24e32e0e5ab095ff78c1251454ac1d5085",
         [
@@ -410569,7 +410643,7 @@
      ],
      "credentialless": {
       "cache-storage.tentative.https.html": [
-       "d3278674be184bb499dc450a8c595e6ec0f5c750",
+       "230f1048a7230b6a936db0e16c18ba81853f5da5",
        [
         "html/cross-origin-embedder-policy/credentialless/cache-storage.tentative.https.html?dedicated_worker",
         {
@@ -434045,7 +434119,7 @@
        ]
       ],
       "display-2.html": [
-       "35c46685aacb887f9289baf74f36077edc03dfda",
+       "570cf3e0ac2d4dbd0009cc6c91a6df95f789c230",
        [
         null,
         {}
@@ -442829,6 +442903,13 @@
       {}
      ]
     ],
+    "screen-wake-lock-permission.html": [
+     "0fa69ff96a03b36d3fbd3de15a70f9b199074ebc",
+     [
+      null,
+      {}
+     ]
+    ],
     "test-background-fetch-permission.html": [
      "c824ecf1d2b47630f8ebcef3ed42c8c908c8e9eb",
      [
@@ -474496,14 +474577,14 @@
        ]
       ],
       "SVGGeometryElement.getPointAtLength-04.svg": [
-       "8d4ad294d0cce18de394316394d418daa0625500",
+       "cbff157c2dd71fb655333a18294eee6b564f83cb",
        [
         null,
         {}
        ]
       ],
       "SVGGeometryElement.getPointAtLength-05.svg": [
-       "50a713743d684e70f0aba780df4e858cb89dad9b",
+       "a8dc208fd58aa54e977f6d68ebb3dcb07bcd76ea",
        [
         null,
         {}
@@ -507518,7 +507599,7 @@
        ]
       ],
       "004.any.js": [
-       "963a9962d11f36f2a7fc01854b30d3a7477b7ef8",
+       "822379e2c90767ff8c37dde68d5419ef42927a51",
        [
         "workers/semantics/interface-objects/004.any.sharedworker.html",
         {
diff --git a/third_party/blink/web_tests/external/wpt/accessibility/crashtests/move-owned-inside-another-owned.html b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/move-owned-inside-another-owned.html
new file mode 100644
index 0000000..babe8dc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/accessibility/crashtests/move-owned-inside-another-owned.html
@@ -0,0 +1,13 @@
+<script>
+window.onload = function() {
+  // Reparent z1 under z2.
+  const z2 = document.getElementById('z2');
+  z2.appendChild(document.querySelector('#z1'));
+}
+</script>
+<div aria-owns="z1 z2">
+  <progress>
+    <div id="z1"></div>
+    <div id="z2"></div>
+  </progress>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-clip-005.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-clip-005.html
index ff6db1a7..fce4a89f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-clip-005.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-paint-clip-005.html
@@ -21,6 +21,7 @@
     margin: 25px;
     padding: 25px;
   }
+  ::marker { font-family: inherit; }
   </style>
 </head>
 <body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-display/display-flow-root-list-item-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-display/display-flow-root-list-item-001-ref.html
index 00bfbca..7d9199af 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-display/display-flow-root-list-item-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-display/display-flow-root-list-item-001-ref.html
@@ -29,7 +29,7 @@
 
 <div style="border:1px solid">
   <div style="margin: 40px 0">
-    <div style="display:list-item">x</div>
+    <div style="display:list-item"><div>x</div></div>
   </div>
 </div>
 
@@ -44,7 +44,7 @@
 </div>
 
 <span>
-  <span style="display:list-item; background:grey; margin:20px 0 0 21px"><div style="padding:20px">x</div></span>
+  <div style="display:flow-root; margin-top:20px"><span style="display:list-item; background:grey"><div style="padding:20px">x</div></span></div>
 </span>
 
 <div style="display:list-item; border:3px solid; height:10px;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox_columns.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox_columns.html
index c89ace5..d39c2db5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox_columns.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flexbox_columns.html
@@ -15,6 +15,7 @@
 	columns: 3;
 	column-rule: 1em solid red;
 }
+::marker { font-family:inherit; }
 </style>
 
 <ul>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/inline-list-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/inline-list-ref.html
index ae1570a..244aeda 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/inline-list-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/inline-list-ref.html
@@ -24,7 +24,7 @@
 <body>
 
 <div class="wrap">
-<span><ib><li>A</li></ib> A A A A A A A A A A A A A A A A A A A </span><span><ib><li value=2></li></ib>B</span>
+<span><ib><li>A</li></ib> A A A A A A A A A A A A A A A A A A A </span><span style="white-space:pre"><ib><li value=2></li></ib>B</span>
 
 <ol>
 <span><ib><li>A</li></ib> A A A A A A A A A A A A A A A A A A A </span><span><ib><li>B</li></ib></span>
@@ -41,7 +41,7 @@
 </ol>
 
 <ul>
-<span><ib><li>A</li></ib> A A A A A A A A A A A A A A A A A A A </span><span><ib><li></li></ib><br>B <ol style="display:inline"><span><ib><li>a</li></ib> a a a a a a a a a a a a a a a a a a a </span><span><ib><li>b</li></ib></span>
+<span><ib><li>A</li></ib> A A A A A A A A A A A A A A A A A A A </span><span><x style="white-space:pre"><ib><li></li></ib>B</x> <ol style="display:inline"><span><ib><li>a</li></ib> a a a a a a a a a a a a a a a a a a a </span><span><ib><li>b</li></ib></span>
 </ol></span><span><ib><li>C</li></ib></span>
 </ul>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment-ref.html
index afd21b0..acbc73e2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment-ref.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<style>::marker { font-family:inherit; }</style>
 <div style="display:inline-block;">
   <ul>
     <li>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment.html
index c147a5f..46f63a69 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-alignment.html
@@ -2,6 +2,7 @@
 <link rel="help" href="https://crbug.com/1051181">
 <link rel="match" href="list-marker-alignment-ref.html">
 <meta name="assert" content="This test checks the list marker aligns to the first baseline.">
+<style>::marker { font-family:inherit; }</style>
 <div style="display:inline-block;">
   <ul>
     <li>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi-ref.html
index cf213d7..892933a4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi-ref.html
@@ -12,6 +12,7 @@
 span {
   float: right;
 }
+::marker { font-family: inherit; }
 </style>
 <section>
   <ul dir="ltr">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi.html
index e82d9ae..47e77be8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-marker-symbol-bidi.html
@@ -34,6 +34,7 @@
 .isolateoverride-item::marker, .isolateoverride-none::marker {
   unicode-bidi: normal;
 }
+::marker { font-family: inherit; }
 </style>
 <section>
   <ul dir="ltr">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic-ref.html
new file mode 100644
index 0000000..b894076
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic-ref.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<meta charset="utf-8">
+<title>CSS Reference: Gradient list markers with dynamic font-size change</title>
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<style>
+li {
+  list-style-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' style='background: blue'></svg>");
+}
+::marker {
+  font-size: 36px;
+}
+</style>
+<ul>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+</ul>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic.html
new file mode 100644
index 0000000..eb96fdd4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-dynamic.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>CSS Test: Gradient list markers with dynamic font-size change</title>
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-lists/#image-markers">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#typedef-gradient">
+<link rel="match" href="list-style-image-gradients-dynamic-ref.html">
+<meta name="assert" content="list-style-image:<gradient> with a single color renders the same as an image without an intrinsic size of the same color">
+<style>
+.larger-font ::marker {
+  font-size: 36px;
+}
+</style>
+<ul>
+  <li style="list-style-image: linear-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-linear-gradient(blue, blue 2px, blue 4px)">text</li>
+  <li style="list-style-image: radial-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-radial-gradient(blue, blue .2em, blue .4em)">text</li>
+</ul>
+<script src="/common/reftest-wait.js"></script>
+<script>
+addEventListener("load", () => {
+  document.body.offsetLeft;
+  document.body.classList.add("larger-font");
+  takeScreenshot();
+}, {once: true});
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-ref.html
new file mode 100644
index 0000000..21092da
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients-ref.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<meta charset="utf-8">
+<title>CSS Reference: Gradient list markers</title>
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<style>
+li {
+  list-style-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' style='background: blue'></svg>");
+}
+.none > li { list-style-type: none; }
+</style>
+<ul>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+</ul>
+<ol>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+</ol>
+<ol class="none">
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+  <li>text</li>
+</ol>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients.html
new file mode 100644
index 0000000..eb797155
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-image-gradients.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<meta charset="utf-8">
+<title>CSS Test: Gradient list markers</title>
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-lists/#image-markers">
+<link rel="help" href="https://drafts.csswg.org/css-images-3/#typedef-gradient">
+<link rel="match" href="list-style-image-gradients-ref.html">
+<meta name="assert" content="list-style-image:<gradient> with a single color renders the same as an image without an intrinsic size of the same color">
+<style>
+.none > li { list-style-type: none; }
+</style>
+<ul>
+  <li style="list-style-image: linear-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-linear-gradient(blue, blue 2px, blue 4px)">text</li>
+  <li style="list-style-image: radial-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-radial-gradient(blue, blue .2em, blue .4em)">text</li>
+</ul>
+<ol>
+  <li style="list-style-image: linear-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-linear-gradient(blue, blue 2px, blue 4px)">text</li>
+  <li style="list-style-image: radial-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-radial-gradient(blue, blue .2em, blue .4em)">text</li>
+</ol>
+<ol class="none">
+  <li style="list-style-image: linear-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-linear-gradient(blue, blue 2px, blue 4px)">text</li>
+  <li style="list-style-image: radial-gradient(blue, blue)">text</li>
+  <li style="list-style-image: repeating-radial-gradient(blue, blue .2em, blue .4em)">text</li>
+</ol>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-type-none-style-image-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-type-none-style-image-ref.html
index 9e72fb31..e54375fe 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/list-type-none-style-image-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-type-none-style-image-ref.html
@@ -7,6 +7,9 @@
       li {
         list-style-image: url('../../images/green-16x16.png');
       }
+      ::marker {
+        font-family: inherit;
+      }
     </style>
   </head>
   <body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-list-item-001.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-list-item-001.xht
index 8d32ac31..bcf3fa2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-list-item-001.xht
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-list-item-001.xht
@@ -28,6 +28,7 @@
   {
   margin-left: 1em;
   padding: 0em;
+  list-style-type: "X";
   }
 
   span {display: block;}
@@ -50,4 +51,4 @@
   </ul>
 
  </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-001-ref.html
index 4f3fe18..ff69c3b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-001-ref.html
@@ -20,7 +20,7 @@
   <body>
     <ul>
       <li style="list-style-position: outside;">
-        bullet outside
+        <div>bullet outside</div>
         <h3>spanner</h3>
       </li>
       <li style="list-style-position: inside;">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-002-ref.html
index 938dae65..d542342 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-list-item-002-ref.html
@@ -21,7 +21,7 @@
   <body>
     <ul>
       <li style="list-style-position: outside;">
-        bullet outside
+        <div>bullet outside</div>
         <h3>spanner</h3>
       </li>
       <li style="list-style-position: inside;">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-dynamic-list-marker.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-dynamic-list-marker.html
index 79535326..2e233e8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-dynamic-list-marker.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-dynamic-list-marker.html
@@ -19,6 +19,7 @@
   height: 100px;
   background: green;
 }
+::marker { color: white; }
 </style>
 <p>Test passes if there is a filled green square.</p>
 <ul>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008-ref.html
index 6d5052b3..3e80d5f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008-ref.html
@@ -7,7 +7,7 @@
 <style>
 li { list-style-type: "ab"; }
 #t1 > li { list-style-type: "ab"; }
-#t2 > li { list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D); }
+#t2 > li::before { content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D); margin-left: -24px; }
 li::after {
   content: "d";
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008.tentative.html
index 88aee13..155b50a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/marker-content-008.tentative.html
@@ -11,7 +11,7 @@
   list-style-position: outside;
 }
 #t1 > li::marker { content: "a" "b"; }
-#t2 > li::marker { content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D); padding-inline-end: calc(1em / 2); }
+#t2 > li::marker { content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D); }
 li::before {
   content: "c";
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt
new file mode 100644
index 0000000..5736b4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (-0.5) should be [perspective(4.12px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0) should be [perspective(5px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.25) should be [perspective(5.45px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.5) should be [perspective(6.15px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.75) should be [perspective(7.06px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (1) should be [perspective(8.33px)]
+FAIL Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (1.5) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1.1, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , - 1.1 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , - 0.1 , 0 , 0 , 0 , 1 ) "
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (-0.5) should be [perspective(4.12px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0) should be [perspective(5px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.25) should be [perspective(5.45px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.5) should be [perspective(6.15px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.75) should be [perspective(7.06px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (1) should be [perspective(8.33px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (1.5) should be [perspective(12.5px)]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition.html
index 82f8dad..f1b0256 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/transform-perspective-composition.html
@@ -13,7 +13,7 @@
 // Addition and accumulation of perspective values are very similar, but not
 // identical. We can test the difference by constructing a scenario where a
 // perspective parameter would go negative in one case (and thus be clamped
-// to 0), and would not go negative in the other case.
+// to 1), and would not go negative in the other case.
 //
 // In the test below, the values differ at 1.5 progress. The reason for this
 // is that at 1.5 progress, the addition case (which uses concatenation)
@@ -23,7 +23,7 @@
 //
 // Since perspective cannot go negative, this is clamped to:
 //
-//   perspective(10px) identity
+//   perspective(10px) perspective(1px)
 //
 // The accumulation case, on the other hand, combines the components
 // and so ends up blending from perspective(5px) to perspective(8.33...px) at
@@ -44,7 +44,7 @@
   {at: 0.5, expect: 'perspective(6.15px)'},
   {at: 0.75, expect: 'perspective(7.06px)'},
   {at: 1, expect: 'perspective(8.33px)'},
-  {at: 1.5, expect: 'perspective(10px)'},
+  {at: 1.5, expect: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1.1, 0, 0, 0, 1)'},
 ]);
 
 // ------------ Accumulation tests --------------
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-001.html
new file mode 100644
index 0000000..3be0af3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-001.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html style="columns: 1">
+<title>CSS Test (Transforms): preserve-3d, inlines, and being a containing block</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1226287">
+<meta name="assert" content="This should not crash.">
+
+<span style="transform-style: preserve-3d"><span style="position: absolute"></span></span>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-002.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-002.html
new file mode 100644
index 0000000..163e977a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/crashtests/preserve3d-containing-block-inline-002.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<title>CSS Test (Transforms): preserve-3d, inlines, and being a containing block</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1226287">
+<meta name="assert" content="This should not crash.">
+
+<span style="transform-style: preserve-3d"><span style="position: absolute"></span></span>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline-ref.html
new file mode 100644
index 0000000..7ca006cc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<meta charset="UTF-8">
+<title>CSS Test Reference: transform-style: preserve-3d not being a containing block on inlines</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<style>
+
+body {
+  margin: 0;
+}
+
+#ref {
+  display: block;
+  width: 50px;
+  height: 50px;
+  background: blue;
+}
+
+</style>
+
+<span id="ref"></span>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline.tentative.html
new file mode 100644
index 0000000..c5666aa3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline.tentative.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<meta charset="UTF-8">
+<title>CSS Test: transform-style: preserve-3d not being a containing block on inlines</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#transform-style-property">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6430">
+<link rel="match" href="preserve-3d-flat-grouping-properties-containing-block-inline-ref.html">
+<style>
+
+#container {
+  margin: 150px;
+}
+
+#outer {
+  transform-style: preserve-3d;
+}
+
+#inner {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 50px;
+  height: 50px;
+  background: blue;
+}
+
+</style>
+
+<div id="container">
+  <span id="outer">
+    <span id="inner"></span>
+  </span>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vlr-022.xht b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vlr-022.xht
index abdc570..6c2f4d3b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vlr-022.xht
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vlr-022.xht
@@ -51,6 +51,17 @@
     {
       border-right: blue solid 1em;
     }
+
+  /*
+     This test depends on the blue ::marker image being placed inside the (blue)
+     padding area.  That depends on how the spacing between it and the list-item
+     box is calculated, which depends on font metrics.  The following rule is
+     to avoid these uncertainties and place it inside the padding for sure.
+  */
+  ::marker
+    {
+      font-size: 0;
+    }
   ]]></style>
  </head>
 
@@ -95,4 +106,4 @@
 <!-- The 4th left-most line of right-most "S" --> <ul id="right-border"><li>j&nbsp; kkkk</li></ul>
 
  </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht
index 32049695..41a623d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht
+++ b/third_party/blink/web_tests/external/wpt/css/css-writing-modes/block-flow-direction-vrl-021.xht
@@ -51,6 +51,17 @@
     {
       border-left: blue solid 1em;
     }
+
+  /*
+     This test depends on the blue ::marker image being placed inside the (blue)
+     padding area.  That depends on how the spacing between it and the list-item
+     box is calculated, which depends on font metrics.  The following rule is
+     to avoid these uncertainties and place it inside the padding for sure.
+  */
+  ::marker
+    {
+      font-size: 0;
+    }
   ]]></style>
  </head>
 
@@ -95,4 +106,4 @@
 <!-- The 4th right-most line of "P" --> <ul id="left-border"><li>kkkkkkk</li></ul>
 
  </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
index 57d4fd0..385efdf0 100644
--- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping-ref.html
@@ -10,6 +10,7 @@
   .katakana { list-style-type: katakana; }
   .hiragana-iroha { list-style-type: hiragana-iroha; }
   .katakana-iroha { list-style-type: katakana-iroha; }
+  ::marker { font-family: inherit; }
 </style>
 <ul class="circle"><li></ul>
 <ul class="square"><li></ul>
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
index 716b1438..1656f9f 100644
--- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
+++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/counter-styles-3/redefine-attr-mapping.html
@@ -29,6 +29,7 @@
   @counter-style upper-alpha {
     system: extends katakana-iroha;
   }
+  ::marker { font-family: inherit; }
 </style>
 <ul type="circle"><li></ul>
 <ul type="square"><li></ul>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/common.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/common.js
index 68f8782..a5afd362 100644
--- a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/common.js
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/common.js
@@ -1,6 +1,7 @@
 const directory = '/html/cross-origin-embedder-policy/credentialless';
 const executor_path = directory + '/resources/executor.html?pipe=';
 const executor_js_path = directory + '/resources/executor.js?pipe=';
+const sw_executor_js_path = directory + '/resources/sw_executor.js?pipe=';
 
 // COEP
 const coep_none =
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/sw_executor.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/sw_executor.js
new file mode 100644
index 0000000..0b47d66b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/resources/sw_executor.js
@@ -0,0 +1,24 @@
+importScripts('./dispatcher.js');
+
+const params = new URLSearchParams(location.search);
+const uuid = params.get('uuid');
+
+// The fetch handler must be registered before parsing the main script response.
+// So do it here, for future use.
+fetchHandler = () => {}
+addEventListener('fetch', e => {
+  fetchHandler(e);
+});
+
+// Force ServiceWorker to immediately activate itself.
+addEventListener('install', event => {
+  skipWaiting();
+});
+
+let executeOrders = async function() {
+  while(true) {
+    let task = await receive(uuid);
+    eval(`(async () => {${task}})()`);
+  }
+};
+executeOrders();
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-credentialless-proxy.tentative.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-credentialless-proxy.tentative.https.html
new file mode 100644
index 0000000..fe12ec8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-credentialless-proxy.tentative.https.html
@@ -0,0 +1,89 @@
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="./resources/common.js"></script>
+<script src="./resources/dispatcher.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+
+const resource_path = directory + "/resources/";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+promise_test(async test => {
+  const this_token_1 = token();
+  const this_token_2 = token();
+
+  // Register a COEP:credentialless ServiceWorker.
+  const sw_token = token();
+  const sw_url =
+    sw_executor_js_path + coep_credentialless + `&uuid=${sw_token}`;
+  const sw_registration =
+    await service_worker_unregister_and_register(test, sw_url, resource_path);
+  test.add_cleanup(() => sw_registration.unregister());
+  await wait_for_state(test, sw_registration.installing, 'activated');
+
+  // Configure the ServiceWorker to proxy the fetch requests. Wait for the
+  // worker to be installed and activated.
+  send(sw_token, `
+    fetchHandler = event => {
+      if (!event.request.url.includes("/proxied"))
+        return;
+
+      send("${this_token_1}", "ServiceWorker: Proxying");
+
+      // Response with a cross-origin no-cors resource.
+      const url = "${cross_origin}" + "/common/blank.html}";
+
+      event.respondWith(new Promise(async resolve => {
+        try {
+          let response = await fetch(url, {
+            mode: "no-cors",
+            credentials: "include"
+          });
+          send("${this_token_1}", "ServiceWorker: Fetch success");
+          resolve(response);
+        } catch (error) {
+          send("${this_token_1}", "ServiceWorker: Fetch failure");
+          resolve(new Response("", {status: 400}));
+        }
+      }));
+    }
+
+    await clients.claim();
+
+    send("${this_token_1}", serviceWorker.state);
+  `)
+  assert_equals(await receive(this_token_1), "activated");
+
+  // Create a COEP:credentialless document.
+  const document_token = environments["document"](coep_credentialless)[0];
+
+  // The document fetches a same-origin no-cors resource. The requests needs to
+  // be same-origin to be handled by the ServiceWorker.
+  send(document_token, `
+    try {
+      const response = await fetch("/proxied", { mode: "no-cors", });
+
+      send("${this_token_2}", "Document: Fetch success");
+    } catch (error) {
+      send("${this_token_2}", "Document: Fetch error");
+    }
+  `);
+
+  // The COEP:credentialless ServiceWorker is able to handle the cross-origin
+  // no-cors request, requested with credentials.
+  assert_equals(await receive(this_token_1), "ServiceWorker: Proxying");
+  assert_equals(await receive(this_token_1), "ServiceWorker: Fetch success");
+
+  // The COEP:credentialless Document is allowed by CORP to get it.
+  assert_equals(await receive(this_token_2), "Document: Fetch success");
+
+  // test.add_cleanup doesn't allow waiting for a promise. Unregistering a
+  // ServiceWorker is an asynchronous operation. It might not be completed on
+  // time for the next test. Do it here for extra flakiness safety.
+  await sw_registration.unregister()
+}, "COEP:credentialless ServiceWorker");
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-none-proxy.tentative.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-none-proxy.tentative.https.html
new file mode 100644
index 0000000..599623b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker-coep-none-proxy.tentative.https.html
@@ -0,0 +1,91 @@
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="./resources/common.js"></script>
+<script src="./resources/dispatcher.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+
+const resource_path = directory + "/resources/";
+const same_origin = get_host_info().HTTPS_ORIGIN;
+const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;
+
+promise_test(async test => {
+  const this_token_1 = token();
+  const this_token_2 = token();
+
+  // Register a COEP:none ServiceWorker.
+  const sw_token = token();
+  const sw_url = sw_executor_js_path + coep_none + `&uuid=${sw_token}`;
+  const sw_registration =
+    await service_worker_unregister_and_register(test, sw_url, resource_path);
+  test.add_cleanup(() => sw_registration.unregister());
+  await wait_for_state(test, sw_registration.installing, 'activated');
+
+  // Configure the ServiceWorker to proxy the fetch requests. Wait for the
+  // worker to be installed and activated.
+  send(sw_token, `
+    fetchHandler = event => {
+      if (!event.request.url.includes("/proxied"))
+        return;
+
+      send("${this_token_1}", "ServiceWorker: Proxying");
+
+      // Response with a cross-origin no-cors resource.
+      const url = "${cross_origin}" + "/common/blank.html}";
+
+      event.respondWith(new Promise(async resolve => {
+        try {
+          let response = await fetch(url, {
+            mode: "no-cors",
+            credentials: "include"
+          });
+          send("${this_token_1}", "ServiceWorker: Fetch success");
+          resolve(response);
+        } catch (error) {
+          send("${this_token_1}", "ServiceWorker: Fetch failure");
+          resolve(new Response("", {status: 400}));
+        }
+      }));
+    }
+
+    await clients.claim();
+
+    send("${this_token_1}", serviceWorker.state);
+  `)
+  assert_equals(await receive(this_token_1), "activated");
+
+  // Create a COEP:credentialless document.
+  const document_token = environments["document"](coep_credentialless)[0];
+
+  // The document fetches a same-origin no-cors resource. The requests needs to
+  // be same-origin to be handled by the ServiceWorker.
+  send(document_token, `
+    try {
+      const response = await fetch("/proxied", {
+        mode: "no-cors",
+        credentials: "include"
+      });
+
+      send("${this_token_2}", "Document: Fetch success");
+    } catch (error) {
+      send("${this_token_2}", "Document: Fetch error");
+    }
+  `);
+
+  // The COEP:unsafe-none ServiceWorker is able to handle the cross-origin
+  // no-cors request, requested with credentials.
+  assert_equals(await receive(this_token_1), "ServiceWorker: Proxying");
+  assert_equals(await receive(this_token_1), "ServiceWorker: Fetch success");
+
+  // However, the COEP:credentialless Document is disallowed by CORP to get it.
+  assert_equals(await receive(this_token_2), "Document: Fetch error");
+
+  // test.add_cleanup doesn't allow waiting for a promise. Unregistering a
+  // ServiceWorker is an asynchronous operation. It might not be completed on
+  // time for the next test. Do it here for extra flakiness safety.
+  await sw_registration.unregister()
+}, "COEP:unsafe-none ServiceWorker");
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/the-details-element/summary-text-decoration-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/the-details-element/summary-text-decoration-ref.html
index 8b6105f..ffdcfd2 100644
--- a/third_party/blink/web_tests/external/wpt/html/rendering/the-details-element/summary-text-decoration-ref.html
+++ b/third_party/blink/web_tests/external/wpt/html/rendering/the-details-element/summary-text-decoration-ref.html
@@ -1,5 +1,11 @@
 <!doctype html>
 <title>Test reference</title>
-<details>
-  <summary><span style="text-decoration:underline">This text should be underlined.</span></summary>
-</details>
+<style>
+div {
+  display: list-item;
+  list-style-type: disclosure-closed;
+  list-style-position: inside;
+  text-decoration: underline;
+}
+</style>
+<div>This text should be underlined.</div>
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/mathml/relations/css-styling/display-2-expected.txt b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2-expected.txt
similarity index 84%
rename from third_party/blink/web_tests/platform/mac/external/wpt/mathml/relations/css-styling/display-2-expected.txt
rename to third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2-expected.txt
index 2ec5d3b..61433fd 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/mathml/relations/css-styling/display-2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2-expected.txt
@@ -12,9 +12,9 @@
 PASS flexbox display (mrow)
 PASS grid display (math)
 PASS grid display (mrow)
-FAIL ruby display (math) assert_approx_equals: block size expected 76 +/- 1 but got 29
-FAIL ruby display (mrow) assert_approx_equals: block size expected 76 +/- 1 but got 43
-FAIL block display with column width (math) assert_approx_equals: block size expected 76 +/- 1 but got 43
-FAIL block display with column width (mrow) assert_approx_equals: block size expected 76 +/- 1 but got 43
+FAIL ruby display (math) assert_approx_equals: block size expected 78 +/- 1 but got 29
+FAIL ruby display (mrow) assert_approx_equals: block size expected 78 +/- 1 but got 45
+FAIL block display with column width (math) assert_approx_equals: block size expected 78 +/- 1 but got 45
+FAIL block display with column width (mrow) assert_approx_equals: block size expected 78 +/- 1 but got 45
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2.html b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2.html
index 35c4668..570cf3e 100644
--- a/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2.html
+++ b/third_party/blink/web_tests/external/wpt/mathml/relations/css-styling/display-2.html
@@ -9,6 +9,8 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/mathml/support/layout-comparison.js"></script>
 <script src="/mathml/support/mathml-fragments.js"></script>
+<script src="/mathml/support/fonts.js"></script>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
 <style>
   mfrac {
       padding: 0;
@@ -97,7 +99,7 @@
   };
 
   setup({ explicit_done: true });
-  window.addEventListener("load", runTests);
+  window.addEventListener("load", () => { loadAllFonts().then(runTests); });
 
   function runTests() {
 
@@ -108,7 +110,7 @@
               replace(/X/g, `<mspace style="display: inline-block; width: ${Xsize}px; height: ${Xsize}px; background: black"></mspace>`);
           let reference = mathtest.
               replace(/maction|math|mfrac|mmultiscripts|mover|mover|mpadded|mrow|mspace|msubsup|msub|msup|mtable|munderover|munder/g, "div");
-          document.body.insertAdjacentHTML("beforeend", `<div style="position: absolute;">\
+          document.body.insertAdjacentHTML("beforeend", `<div style="font: 20px/1 Ahem; position: absolute;">\
 <div><span>${key}:</span>${mathtest}</div>\
 <div><span>${key}:</span>${reference}</div>\
 </div>`);
diff --git a/third_party/blink/web_tests/external/wpt/permissions/screen-wake-lock-permission.html b/third_party/blink/web_tests/external/wpt/permissions/screen-wake-lock-permission.html
new file mode 100644
index 0000000..0fa69ff9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/permissions/screen-wake-lock-permission.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test "screen-wake-lock" Permission.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+
+<script>
+promise_test(async () => {
+  const result = await navigator.permissions.query({
+    name: "screen-wake-lock",
+  });
+  assert_true(result instanceof PermissionStatus);
+});
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html
index a577a1e3..34615f6 100644
--- a/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/sanitizer-api/sanitizer-sanitize.https.tentative.html
@@ -10,14 +10,29 @@
 <script>
     function getString(fragment) {
       d = document.createElement("div");
-      d.appendChild(fragment);
+      d.replaceChildren(...fragment.cloneNode(true).childNodes);
       return d.innerHTML;
     }
 
+    function getFragment(markup) {
+      const d = document.createElement("div");
+      d.innerHTML = markup;
+      let f = document.createDocumentFragment();
+      f.replaceChildren(...d.childNodes);
+      return f;
+    }
+    function getDoc(markup) {
+      return new DOMParser().parseFromString(markup, "text/html");
+    }
+    function assert_node_equals(node1, node2) {
+      assert_true(node1 instanceof Node && node1.isEqualNode(node2),
+                  `Node[${getString(node1)}] == Node[${getString(node2)}]`);
+    }
+
     test(t => {
-      let s = new Sanitizer({});
+      let s = new Sanitizer();
       assert_throws_js(TypeError, _ => s.sanitize());
-    }, "SanitizerAPI sanitize function without argument should throw an error.");
+    }, "Sanitizer.sanitize() should throw an error.");
 
     test(t => {
       let s = new Sanitizer({});
@@ -26,22 +41,31 @@
       assert_equals(getString(fragment), "null");
     }, "SanitizerAPI sanitize function for null.");
 
-    testcases.forEach(c => test(t => {
-        let s = new Sanitizer(c.config_input);
-        fragment = s.sanitize(c.value);
-        assert_true(fragment instanceof DocumentFragment);
-        assert_equals(getString(fragment), c.result);
-    }, "SanitizerAPI with config: " + c.message + ", sanitize from string function for " + c.message));
+    const probe_string = `<a href="about:blank">hello</a><script>cons` +
+        `ole.log("world!");<` + `/script>`;
+    test(t => {
+      const sanitized = new Sanitizer().sanitize(getFragment(probe_string));
+      const expected = getFragment(probe_string.substr(0, 31));
+      assert_node_equals(expected, sanitized);
+    }, "Sanitizer.sanitze(DocumentFragment)");
+
+    test(t => {
+      const sanitized = new Sanitizer().sanitize(getDoc(probe_string));
+      const expected = getFragment(probe_string.substr(0, 31));
+      assert_node_equals(expected, sanitized);
+    }, "Sanitizer.sanitze(Document)");
+
 
     async_test(t => {
       let s = new Sanitizer();
-      fragment = s.sanitize("<img src='http://bla/'>");
+      fragment = s.sanitize(getFragment("<img src='http://bla/'>"));
       t.step_timeout(_ => {
         assert_equals(performance.getEntriesByName("http://bla/").length, 0);
         t.done();
       }, 1000);
     }, "SanitizerAPI sanitize function shouldn't load the image.");
 
+
     testcases.forEach(c => test(t => {
         let s = new Sanitizer(c.config_input);
         var dom = new DOMParser().parseFromString("<!DOCTYPE html><body>" + c.value, "text/html");
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt
index 8e0e13d..a6650fa 100644
--- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 224 tests; 204 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 224 tests; 212 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique
@@ -159,14 +159,14 @@
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "releaseLock()" with the proper type
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "write(optional any)" with the proper type
 PASS WritableStreamDefaultWriter interface: calling write(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
-FAIL WritableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object length assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object name assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: operation error(optional any) assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
+PASS WritableStreamDefaultController interface: existence and properties of interface object
+PASS WritableStreamDefaultController interface object length
+PASS WritableStreamDefaultController interface object name
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStreamDefaultController interface: operation error(optional any)
+PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
 PASS Stringification of self.writableStreamDefaultController
 PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
 PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt
index 8e0e13d..a6650fa 100644
--- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.serviceworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 224 tests; 204 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 224 tests; 212 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique
@@ -159,14 +159,14 @@
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "releaseLock()" with the proper type
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "write(optional any)" with the proper type
 PASS WritableStreamDefaultWriter interface: calling write(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
-FAIL WritableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object length assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object name assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: operation error(optional any) assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
+PASS WritableStreamDefaultController interface: existence and properties of interface object
+PASS WritableStreamDefaultController interface object length
+PASS WritableStreamDefaultController interface object name
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStreamDefaultController interface: operation error(optional any)
+PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
 PASS Stringification of self.writableStreamDefaultController
 PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
 PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt
index 8e0e13d..a6650fa 100644
--- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.sharedworker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 224 tests; 204 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 224 tests; 212 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique
@@ -159,14 +159,14 @@
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "releaseLock()" with the proper type
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "write(optional any)" with the proper type
 PASS WritableStreamDefaultWriter interface: calling write(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
-FAIL WritableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object length assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object name assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: operation error(optional any) assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
+PASS WritableStreamDefaultController interface: existence and properties of interface object
+PASS WritableStreamDefaultController interface object length
+PASS WritableStreamDefaultController interface object name
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStreamDefaultController interface: operation error(optional any)
+PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
 PASS Stringification of self.writableStreamDefaultController
 PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
 PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
diff --git a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt
index 8e0e13d..a6650fa 100644
--- a/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/streams/idlharness.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 224 tests; 204 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 224 tests; 212 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS ReadableStreamDefaultReader includes ReadableStreamGenericReader: member names are unique
@@ -159,14 +159,14 @@
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "releaseLock()" with the proper type
 PASS WritableStreamDefaultWriter interface: (new WritableStream()).getWriter() must inherit property "write(optional any)" with the proper type
 PASS WritableStreamDefaultWriter interface: calling write(optional any) on (new WritableStream()).getWriter() with too few arguments must throw TypeError
-FAIL WritableStreamDefaultController interface: existence and properties of interface object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object length assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface object name assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController interface: operation error(optional any) assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
-FAIL WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController assert_own_property: self does not have own property "WritableStreamDefaultController" expected property "WritableStreamDefaultController" missing
+PASS WritableStreamDefaultController interface: existence and properties of interface object
+PASS WritableStreamDefaultController interface object length
+PASS WritableStreamDefaultController interface object name
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
+PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
+PASS WritableStreamDefaultController interface: operation error(optional any)
+PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
 PASS Stringification of self.writableStreamDefaultController
 PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
 PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg
index 8d4ad29..cbff157c 100644
--- a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg
+++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg
@@ -3,12 +3,12 @@
   <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
   <h:script src="/resources/testharness.js"/>
   <h:script src="/resources/testharnessreport.js"/>
-  <path id='pathElement1' d='M0,0L100,0L100,100' description='path with display: defualt'/>
+  <path id='pathElement1' d='M0,0L100,0L100,100' description='path with display: default'/>
   <path id='pathElement2' style='display:none' d='M0,0L100,0L100,100' description='path with display: none'/>
   <path id='pathElement3' style='display:none; d:path("M0,0L100,0L100,100");' description='path with display: none and inline style'/>
   <rect id='rectElement1' x='0' y='0' width='50' height='50' description='rect with display: default'/>
   <rect id='rectElement2' style='display:none' x='0' y='0' width='50' height='50' description='rect with display: none'/>
-  <circle id='circleElement1' cx='0' cy='0' r='50' description='circle with display: defualt'/>
+  <circle id='circleElement1' cx='0' cy='0' r='50' description='circle with display: default'/>
   <circle id='circleElement2' style='display:none' cx='0' cy='0' r='50' description='circle with display: none'/>
   <polygon id='polygonElement1' points="0,0 50,0 50,50 0,50" description='polygon with display: default'/>
   <polygon id='polygonElement2' style='display:none' points="0,0 50,0 50,50 0,50" description='polygon with display: none'/>
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg
index 50a7137..a8dc208f 100644
--- a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg
+++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg
@@ -3,13 +3,13 @@
   <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/>
   <h:script src="/resources/testharness.js"/>
   <h:script src="/resources/testharnessreport.js"/>
-  <path id='pathElement1' description='path with display: defualt and an empty path'/>
+  <path id='pathElement1' description='path with display: default and an empty path'/>
   <path id='pathElement2' style='display:none' description='path with display: none and an empty path'/>
-  <rect id='rectElement1' description='rect with display: defualt and an empty path'/>
+  <rect id='rectElement1' description='rect with display: default and an empty path'/>
   <rect id='rectElement2' style='display:none' description='rect with display: none and an empty path'/>
   <circle id='circleElement1' description='circle with display: default and an empty path'/>
   <circle id='circleElement2' style='display:none' description='circle with display: none and an empty path'/>
-  <polygon id='polygonElement1' description='polygon with display: defualt and an empty path'/>
+  <polygon id='polygonElement1' description='polygon with display: default and an empty path'/>
   <polygon id='polygonElement2' style='display:none' description='polygon with display: none and an empty path'/>
   <polyline id='polylineElement1' description='polyline with display: default and an empty path'/>
   <polyline id='polylineElement2' style='display:none' description='polyline with display: none and an empty path'/>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/require-trusted-types-for.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/require-trusted-types-for.tentative.html
index bf3dedd..2a3820a 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/require-trusted-types-for.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/require-trusted-types-for.tentative.html
@@ -75,26 +75,4 @@
       resolve();
     });
   }, "Set require trusted types for 'script' without CSP for trusted types don't block policy creation and using.");
-
-  promise_test(t => {
-    let p = Promise.resolve()
-        .then(promise_violation("require-trusted-types-for 'script'"));
-    let s = new Sanitizer();
-    assert_throws_js(TypeError,
-        _ => {
-          fragment = s.sanitize("testHTML");
-        });
-    return p;
-  }, "Require trusted types for 'script' block Sanitizer sanitize from string API.");
-
-  promise_test(t => {
-    let p = Promise.resolve()
-        .then(promise_violation("require-trusted-types-for 'script'"));
-    let s = new Sanitizer();
-    assert_throws_js(TypeError,
-        _ => {
-          fragment = s.sanitize(null);
-        });
-    return p;
-  }, "Require trusted types for 'script' block Sanitizer sanitize null from string API.");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js
index 963a9962..822379e 100644
--- a/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js
+++ b/third_party/blink/web_tests/external/wpt/workers/semantics/interface-objects/004.any.js
@@ -17,8 +17,6 @@
   "PopStateEvent",
   "HashChangeEvent",
   "PageTransitionEvent",
-  // https://streams.spec.whatwg.org/
-  "WritableStreamDefaultController",
   // http://w3c.github.io/IndexedDB/
   "IDBEnvironment",
   // https://www.w3.org/TR/2010/NOTE-webdatabase-20101118/
diff --git a/third_party/blink/web_tests/external/wpt/xhr/json.any-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/json.any-expected.txt
deleted file mode 100644
index d9a840d..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/json.any-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Ensure the correct JSON parser is used
-FAIL Ensure UTF-16 results in an error assert_equals: expected null but got object "[object Object]"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/xhr/json.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/xhr/json.any.worker-expected.txt
deleted file mode 100644
index d9a840d..0000000
--- a/third_party/blink/web_tests/external/wpt/xhr/json.any.worker-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Ensure the correct JSON parser is used
-FAIL Ensure UTF-16 results in an error assert_equals: expected null but got object "[object Object]"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable.js b/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable.js
index 38fe8ebf..3cb79f4 100644
--- a/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable.js
+++ b/third_party/blink/web_tests/http/tests/devtools/agents-enable-disable.js
@@ -33,17 +33,13 @@
     async function disableAgent(agentName) {
       const agent = target.agents.get(agentName);
       const response = await agent.invoke_disable({});
-      printResult(
-          agentName, 'disable',
-          response[ProtocolClient.InspectorBackend.ProtocolError]);
+      printResult(agentName, 'disable', response.getError());
     }
 
     async function enableAgent(agentName) {
       const agent = target.agents.get(agentName);
       const response = await agent.invoke_enable({});
-      printResult(
-          agentName, 'enable',
-          response[ProtocolClient.InspectorBackend.ProtocolError]);
+      printResult(agentName, 'enable', response.getError());
     }
 
     for (const agentName of agentNames)
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt
deleted file mode 100644
index ffb3c7f..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation-expected.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-Tests that console messages are navigable with the keyboard.
-
-Message count: 100
-
-Running: testBetweenViewportAndExternal
-Setting focus in prompt:
-TEXTAREA:Console prompt
-
-Shift+Tab:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #99
-
-Shift+Tab:
-DIV#console-messages.monospace
-
-Tab:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #99
-
-Tab:
-TEXTAREA:Console prompt
-
-Running: testBetweenViewportAndExternalWithSelectedItemNotInDOM
-Setting focus in prompt:
-TEXTAREA:Console prompt
-
-Shift+Tab:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #99
-
-Scrolling to top of viewport
-DIV.console-group.console-group-messages
-
-Shift+Tab:
-DIV#console-messages.monospace
-
-Tab:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #99
-
-Setting focus in prompt:
-TEXTAREA:Console prompt
-
-Shift+Tab:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #99
-
-Scrolling to top of viewport
-DIV.console-group.console-group-messages
-
-Tab:
-TEXTAREA:Console prompt
-
-Running: testMoveAcrossLogsWithinViewport
-
-Force selecting index 99
-DIV.console-group.console-group-messages
-
-Home:
-DIV:console-key-navigation.js:20 Message #0
-
-ArrowDown:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowDown:
-DIV:console-key-navigation.js:20 Message #1
-
-End:
-DIV:console-key-navigation.js:20 Message #99
-
-ArrowUp:
-SPAN:test://evaluations/0/console-key-navigation.js:20
-
-ArrowUp:
-DIV:console-key-navigation.js:20 Message #98
-
-Running: testViewportDoesNotChangeFocusOnScroll
-
-Force selecting index 98
-DIV:console-key-navigation.js:20 Message #98
-
-Scrolling to top of viewport
-DIV.console-group.console-group-messages
-
-Scrolling to bottom of viewport
-DIV:console-key-navigation.js:20 Message #98
-
-Running: testViewportDoesNotStealFocusOnScroll
-
-Force selecting index 99
-DIV:console-key-navigation.js:20 Message #99
-Setting focus in prompt:
-TEXTAREA:Console prompt
-
-Scrolling to top of viewport
-TEXTAREA:Console prompt
-
-Scrolling to bottom of viewport
-TEXTAREA:Console prompt
-
-Running: testNewLogsShouldNotMoveFocus
-Setting focus in prompt:
-TEXTAREA:Console prompt
-Message count: 101
-TEXTAREA:Console prompt
-
-Running: testClearingConsoleFocusesPrompt
-
-Console cleared:
-TEXTAREA:Console prompt
-
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation.js b/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation.js
deleted file mode 100644
index 52e0b605..0000000
--- a/third_party/blink/web_tests/http/tests/devtools/console/viewport-testing/console-key-navigation.js
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(async function() {
-  TestRunner.addResult(`Tests that console messages are navigable with the keyboard.\n`);
-  await TestRunner.loadModule('console'); await TestRunner.loadTestModule('console_test_runner');
-  await TestRunner.showPanel('console');
-  ConsoleTestRunner.fixConsoleViewportDimensions(600, 200);
-  await ConsoleTestRunner.waitUntilConsoleEditorLoaded();
-
-  const consoleView = Console.ConsoleView.instance();
-  const viewport = consoleView._viewport;
-  const prompt = consoleView._prompt;
-
-  // Log some messages.
-  const logCount = 100;
-  await TestRunner.evaluateInPagePromise(`
-      for (var i = 0; i < ${logCount}; ++i)
-          console.log("Message #" + i);
-    `);
-
-  await ConsoleTestRunner.waitForConsoleMessagesPromise(logCount);
-  await ConsoleTestRunner.waitForPendingViewportUpdates();
-
-  TestRunner.runTestSuite([
-    async function testBetweenViewportAndExternal(next) {
-      TestRunner.addResult(`Setting focus in prompt:`);
-      prompt.focus();
-      await dumpFocus();
-
-      shiftPress('Tab');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      shiftPress('Tab');
-      await dumpFocus();
-
-      press('Tab');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      press('Tab');
-      await dumpFocus();
-
-      next();
-    },
-
-    async function testBetweenViewportAndExternalWithSelectedItemNotInDOM(next) {
-      TestRunner.addResult(`Setting focus in prompt:`);
-      prompt.focus();
-      await dumpFocus();
-
-      shiftPress('Tab');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      scrollViewportToTop();
-      await dumpFocus();
-
-      shiftPress('Tab');
-      await dumpFocus();
-
-      press('Tab');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      TestRunner.addResult(`\nSetting focus in prompt:`);
-      prompt.focus();
-      await dumpFocus();
-
-      shiftPress('Tab');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      scrollViewportToTop();
-      await dumpFocus();
-
-      press('Tab');
-      await dumpFocus();
-
-      next();
-    },
-
-    async function testMoveAcrossLogsWithinViewport(next) {
-      forceSelect(logCount - 1);
-      await dumpFocus();
-
-      press('Home');
-      await dumpFocus();
-
-      press('ArrowDown');
-      await dumpFocus();
-
-      press('ArrowDown');
-      await dumpFocus();
-
-      press('End');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      press('ArrowUp');
-      await dumpFocus();
-
-      next();
-    },
-
-    async function testViewportDoesNotChangeFocusOnScroll(next) {
-      forceSelect(logCount - 2);
-      await dumpFocus();
-
-      scrollViewportToTop();
-      await dumpFocus();
-
-      scrollViewportToBottom();
-      await dumpFocus();
-
-      next();
-    },
-
-    async function testViewportDoesNotStealFocusOnScroll(next) {
-      forceSelect(logCount - 1);
-      await dumpFocus();
-
-      TestRunner.addResult(`Setting focus in prompt:`);
-      prompt.focus();
-      await dumpFocus();
-
-      scrollViewportToTop();
-      await dumpFocus();
-
-      scrollViewportToBottom();
-      await dumpFocus();
-
-      next();
-    },
-
-    async function testNewLogsShouldNotMoveFocus(next) {
-      TestRunner.addResult(`Setting focus in prompt:`);
-      prompt.focus();
-      await dumpFocus();
-
-      await TestRunner.evaluateInPagePromise(`console.log("New Message")`);
-      await ConsoleTestRunner.waitForConsoleMessagesPromise(logCount + 1);
-      await ConsoleTestRunner.waitForPendingViewportUpdates();
-
-      await dumpFocus();
-      next();
-    },
-
-    async function testClearingConsoleFocusesPrompt(next) {
-      TestRunner.addResult(`\nConsole cleared:`);
-      consoleView._consoleCleared();
-      await dumpFocus();
-      next();
-    }
-  ]);
-
-
-  // Utilities.
-  function scrollViewportToTop() {
-    TestRunner.addResult(`\nScrolling to top of viewport`);
-    viewport.setStickToBottom(false);
-    viewport.element.scrollTop = 0;
-    viewport.refresh();
-  }
-
-  function scrollViewportToBottom() {
-    TestRunner.addResult(`\nScrolling to bottom of viewport`);
-    viewport.element.scrollTop = viewport.element.scrollHeight + 1;
-    viewport.refresh();
-  }
-
-  function forceSelect(index) {
-    TestRunner.addResult(`\nForce selecting index ${index}`);
-    viewport._virtualSelectedIndex = index;
-    viewport._contentElement.focus();
-    viewport._updateFocusedItem();
-  }
-
-  function press(key) {
-    TestRunner.addResult(`\n${key}:`);
-    eventSender.keyDown(key);
-  }
-
-  function shiftPress(key) {
-    TestRunner.addResult(`\nShift+${key}:`);
-    eventSender.keyDown(key, ['shiftKey']);
-  }
-
-  async function dumpFocus() {
-    var element = document.deepActiveElement();
-    // Console elements contain live locations that might not be fully resolved yet.
-    await TestRunner.waitForPendingLiveLocationUpdates();
-    if (!element) {
-      TestRunner.addResult('null');
-      return;
-    }
-    var name = element.tagName;
-    if (element.id)
-      name += '#' + element.id;
-    if (element.getAttribute('aria-label'))
-      name += ':' + element.getAttribute('aria-label');
-    else if (UI.Tooltip.getContent(element))
-      name += ':' + UI.Tooltip.getContent(element);
-    else if (element.textContent && element.textContent.length < 50) {
-      name += ':' + element.textContent.replace('\u200B', '');
-    } else if (element.className)
-      name += '.' + element.className.split(' ').join('.');
-    TestRunner.addResult(name);
-  }
-})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/search/search-in-non-existing-resource.js b/third_party/blink/web_tests/http/tests/devtools/search/search-in-non-existing-resource.js
index 65d080e..7be79ec8 100644
--- a/third_party/blink/web_tests/http/tests/devtools/search/search-in-non-existing-resource.js
+++ b/third_party/blink/web_tests/http/tests/devtools/search/search-in-non-existing-resource.js
@@ -20,8 +20,7 @@
     var resource = Bindings.resourceForURL('http://127.0.0.1:8000/devtools/search/resources/search.js');
     var url = 'http://127.0.0.1:8000/devtools/search/resources/non-existing.js';
     var response = await TestRunner.PageAgent.invoke_searchInResource({frameId: resource.frameId, url, query: text});
-    TestRunner.addResult(
-        response[ProtocolClient.InspectorBackend.ProtocolError]);
+    TestRunner.addResult(response.getError());
     TestRunner.completeTest();
   }
 })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/debugger-set-breakpoint-regex.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/debugger-set-breakpoint-regex.js
index f08e075..bf99930 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/debugger-set-breakpoint-regex.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/debugger-set-breakpoint-regex.js
@@ -20,8 +20,7 @@
   SourcesTestRunner.runDebuggerTestSuite([
     async function testSetNoneOfURLAndRegex(next) {
       var response = await TestRunner.DebuggerAgent.invoke_setBreakpointByUrl({lineNumber: 1});
-      TestRunner.addResult(
-          response[ProtocolClient.InspectorBackend.ProtocolError]);
+      TestRunner.addResult(response.getError());
       next();
     },
 
@@ -29,8 +28,7 @@
       var url = 'debugger-set-breakpoint.js';
       var urlRegex = 'debugger-set-breakpoint.*';
       var response = await TestRunner.DebuggerAgent.invoke_setBreakpointByUrl({lineNumber: 1, url, urlRegex});
-      TestRunner.addResult(
-          response[ProtocolClient.InspectorBackend.ProtocolError]);
+      TestRunner.addResult(response.getError());
       next();
     },
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline-expected.txt b/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline-expected.txt
new file mode 100644
index 0000000..19f745d
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline-expected.txt
@@ -0,0 +1,4 @@
+
+Running: testNoSocketOpenWhenOffline
+onerror onclose 
+
diff --git a/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline.js b/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline.js
new file mode 100644
index 0000000..581f240
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/websocket/websocket-emulate-offline.js
@@ -0,0 +1,23 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(async function() {
+  TestRunner.runAsyncTestSuite([async function testNoSocketOpenWhenOffline() {
+    SDK.multitargetNetworkManager.setNetworkConditions(
+        SDK.NetworkManager.OfflineConditions);
+
+    TestRunner.addResult(await TestRunner.evaluateInPageAsync(`
+        new Promise((resolve) => {
+          const ws = new WebSocket('ws://localhost:8880/echo');
+          let log = '';
+          ws.onopen = () => {log += 'onopen '; ws.close(); };
+          ws.onmessage = () => log += 'onmessage ';
+          ws.onerror = () => log += 'onerror ';
+          ws.onclose = () => {
+            log += 'onclose ';
+            resolve(log);
+          };
+        });`));
+  }]);
+})();
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple-expected.txt
new file mode 100644
index 0000000..6d1cef51
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple-expected.txt
@@ -0,0 +1,2 @@
+Regression test for https://crbug.com/1224133.
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple.js
new file mode 100644
index 0000000..49fbf88
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/exception-simple.js
@@ -0,0 +1,15 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startBlank(
+      `Regression test for https://crbug.com/1224133.`);
+
+  await dp.Runtime.enable();
+  const exceptionThrown = dp.Runtime.onceExceptionThrown();
+
+  const url = `https://127.0.0.1:8443/inspector-protocol/network/resources`;
+  session.evaluate(`fetch("${url}/cors-redirect.php");`);
+  session.navigate('../resources/exception-simple.html');
+
+  await exceptionThrown;
+
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/exception-simple.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/exception-simple.html
new file mode 100644
index 0000000..e0ef6f8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/exception-simple.html
@@ -0,0 +1,3 @@
+<script>
+  throw new Error('foo');
+</script>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index fb41bab..54960be 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -3041,6 +3041,10 @@
     method close
     method constructor
     method getWriter
+interface WritableStreamDefaultController
+    attribute @@toStringTag
+    method constructor
+    method error
 interface WritableStreamDefaultWriter
     attribute @@toStringTag
     getter closed
diff --git a/third_party/blink/web_tests/webexposed/README.txt b/third_party/blink/web_tests/http/tests/webexposed/README.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/README.txt
rename to third_party/blink/web_tests/http/tests/webexposed/README.txt
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/css-properties-as-js-properties-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/css-properties-as-js-properties-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties.html b/third_party/blink/web_tests/http/tests/webexposed/css-properties-as-js-properties.html
similarity index 86%
rename from third_party/blink/web_tests/webexposed/css-properties-as-js-properties.html
rename to third_party/blink/web_tests/http/tests/webexposed/css-properties-as-js-properties.html
index bd7762e..a86431f 100644
--- a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/css-properties-as-js-properties.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 <script>
 debug("This test (crudely) documents Blink's web-exposed CSS properties.  All changes to this list should go through Blink's feature review process: http://www.chromium.org/blink#new-features");
 debug("");
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/css-property-listing-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/css-property-listing-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing.html b/third_party/blink/web_tests/http/tests/webexposed/css-property-listing.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/css-property-listing.html
rename to third_party/blink/web_tests/http/tests/webexposed/css-property-listing.html
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt
similarity index 99%
copy from third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
copy to third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt
index 31c4c9cf..cb229082 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing-expected.txt
@@ -22,6 +22,7 @@
     property ENTITY_REFERENCE_NODE
     property NOTATION_NODE
     property PROCESSING_INSTRUCTION_NODE
+    property SetSanitizedHTML
     property TEXT_NODE
     property accessKey
     property accessibleNode
@@ -1242,6 +1243,7 @@
     property ENTITY_REFERENCE_NODE
     property NOTATION_NODE
     property PROCESSING_INSTRUCTION_NODE
+    property SetSanitizedHTML
     property TEXT_NODE
     property accessibleNode
     property addEventListener
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing.html b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing.html
similarity index 77%
rename from third_party/blink/web_tests/webexposed/element-instance-property-listing.html
rename to third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing.html
index e35fb8ea..e0de654 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/element-instance-property-listing.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 <script src="resources/element-instance-property-listing.js"></script>
 <script>
 description("This test documents all properties on all element instances.");
diff --git a/third_party/blink/web_tests/webexposed/event-target-in-prototype-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/event-target-in-prototype-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/event-target-in-prototype-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/event-target-in-prototype-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/event-target-in-prototype.html b/third_party/blink/web_tests/http/tests/webexposed/event-target-in-prototype.html
similarity index 90%
rename from third_party/blink/web_tests/webexposed/event-target-in-prototype.html
rename to third_party/blink/web_tests/http/tests/webexposed/event-target-in-prototype.html
index 3cb16fa..295cf50 100644
--- a/third_party/blink/web_tests/webexposed/event-target-in-prototype.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/event-target-in-prototype.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 </head>
 <body>
 <script>
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/feature-policy-features-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/feature-policy-features-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features.html b/third_party/blink/web_tests/http/tests/webexposed/feature-policy-features.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/feature-policy-features.html
rename to third_party/blink/web_tests/http/tests/webexposed/feature-policy-features.html
diff --git a/third_party/blink/web_tests/webexposed/global-constructors-attributes-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/global-constructors-attributes-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/global-constructors-attributes-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/webexposed/global-constructors-attributes-worker-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker-expected.txt
index b050997b..93bfca5 100644
--- a/third_party/blink/web_tests/webexposed/global-constructors-attributes-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-constructors-attributes-worker.js
+Starting worker: resources/global-constructors-attributes-worker.js.php
 PASS [Worker] Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS [Worker] Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS [Worker] Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker.php b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker.php
new file mode 100644
index 0000000..76787c8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes-worker.php
@@ -0,0 +1,14 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+worker = startWorker("resources/global-constructors-attributes-worker.js.php");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes.php b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes.php
new file mode 100644
index 0000000..e73d94d
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-constructors-attributes.php
@@ -0,0 +1,12 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script src="resources/global-constructors-attributes.js"></script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 6fd3871..2279ae5 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface AbortController
 [Worker]     attribute @@toStringTag
@@ -3268,6 +3268,10 @@
 [Worker]     method close
 [Worker]     method constructor
 [Worker]     method getWriter
+[Worker] interface WritableStreamDefaultController
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method error
 [Worker] interface WritableStreamDefaultWriter
 [Worker]     attribute @@toStringTag
 [Worker]     getter closed
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker.php
new file mode 100644
index 0000000..106251e
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-dedicated-worker.php
@@ -0,0 +1,10 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script src="/js-test-resources/js-test.js"></script>
+<script>
+description("This test documents all interface attributes and methods on DedicatedWorkerGlobalScope.");
+worker = startWorker("resources/global-interface-listing-worker.js.php");
+worker.postMessage({ platformSpecific: false });
+</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt
index f7025a0..5ed4e23 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-expected.txt
@@ -2250,6 +2250,7 @@
     getter shadowRoot
     getter slot
     getter tagName
+    method SetSanitizedHTML
     method after
     method animate
     method append
@@ -6217,6 +6218,7 @@
     method getEntriesByType
     method mark
     method measure
+    method measureUserAgentSpecificMemory
     method now
     method setResourceTimingBufferSize
     method toJSON
@@ -8153,6 +8155,7 @@
     method config
     method constructor
     method sanitize
+    method sanitizeFor
     method sanitizeToString
 interface Scheduler
     attribute @@toStringTag
@@ -10645,6 +10648,10 @@
     method close
     method constructor
     method getWriter
+interface WritableStreamDefaultController
+    attribute @@toStringTag
+    method constructor
+    method error
 interface WritableStreamDefaultWriter
     attribute @@toStringTag
     getter closed
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
similarity index 88%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index bf64d64f..4aa7ef41 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.php
new file mode 100644
index 0000000..0ed4d073
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.php
@@ -0,0 +1,10 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script src="/js-test-resources/js-test.js"></script>
+<script>
+description("This test documents all interface attributes and methods on DedicatedWorkerGlobalScope.");
+worker = startWorker("resources/global-interface-listing-worker.js.php");
+worker.postMessage({ platformSpecific: true });
+</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
similarity index 88%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index 639c7c6..c1d7c16 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker.php
new file mode 100644
index 0000000..0879391
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker.php
@@ -0,0 +1,10 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script src="/js-test-resources/js-test.js"></script>
+<script>
+description("This test documents all interface attributes and methods on SharedWorkerGlobalScope.");
+worker = startWorker("resources/global-interface-listing-worker.js.php", "shared");
+worker.port.postMessage({ platformSpecific: true });
+</script>
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific.php
new file mode 100644
index 0000000..70a0fc8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-platform-specific.php
@@ -0,0 +1,14 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script>
+// Save the list of property names of the global object just after page load.
+var propertyNamesInGlobal = Object.getOwnPropertyNames(this);
+</script>
+<script src="/js-test-resources/js-test.js"></script>
+<script src="/js-test-resources/global-interface-listing.js"></script>
+<script>
+description("This test documents all interface attributes and methods on the global window object and element instances.");
+globalInterfaceListing(this, propertyNamesInGlobal, true, debug);
+</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
index ecd3603b..13bbb42 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface AbortController
 [Worker]     attribute @@toStringTag
@@ -2909,6 +2909,10 @@
 [Worker]     method close
 [Worker]     method constructor
 [Worker]     method getWriter
+[Worker] interface WritableStreamDefaultController
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method error
 [Worker] interface WritableStreamDefaultWriter
 [Worker]     attribute @@toStringTag
 [Worker]     getter closed
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker.php
new file mode 100644
index 0000000..2bebb508
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing-shared-worker.php
@@ -0,0 +1,10 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script src="/js-test-resources/js-test.js"></script>
+<script>
+description("This test documents all interface attributes and methods on SharedWorkerGlobalScope.");
+worker = startWorker("resources/global-interface-listing-worker.js.php", "shared");
+worker.port.postMessage({ platformSpecific: false });
+</script>
diff --git a/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing.php b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing.php
new file mode 100644
index 0000000..9ce96bd
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/webexposed/global-interface-listing.php
@@ -0,0 +1,14 @@
+<?php
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?><!DOCTYPE html>
+<script>
+// Save the list of property names of the global object just after page load.
+var propertyNamesInGlobal = Object.getOwnPropertyNames(this);
+</script>
+<script src="/js-test-resources/js-test.js"></script>
+<script src="/js-test-resources/global-interface-listing.js"></script>
+<script>
+description("This test documents all interface attributes and methods on the global window object and element instances.");
+globalInterfaceListing(this, propertyNamesInGlobal, false /* platformSpecific */, debug);
+</script>
diff --git a/third_party/blink/web_tests/webexposed/internal-properties-should-not-be-exposed-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/internal-properties-should-not-be-exposed-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/internal-properties-should-not-be-exposed-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/internal-properties-should-not-be-exposed-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/internal-properties-should-not-be-exposed.html b/third_party/blink/web_tests/http/tests/webexposed/internal-properties-should-not-be-exposed.html
similarity index 94%
rename from third_party/blink/web_tests/webexposed/internal-properties-should-not-be-exposed.html
rename to third_party/blink/web_tests/http/tests/webexposed/internal-properties-should-not-be-exposed.html
index c539ddb0..f3c3181 100644
--- a/third_party/blink/web_tests/webexposed/internal-properties-should-not-be-exposed.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/internal-properties-should-not-be-exposed.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <body>
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 <script>
 debug("This test checks that -internal-* properties are not exposed to JS.")
 debug("");
diff --git a/third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/nonstable-css-properties-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/nonstable-css-properties-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/nonstable-css-properties-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/nonstable-css-properties.html b/third_party/blink/web_tests/http/tests/webexposed/nonstable-css-properties.html
similarity index 96%
rename from third_party/blink/web_tests/webexposed/nonstable-css-properties.html
rename to third_party/blink/web_tests/http/tests/webexposed/nonstable-css-properties.html
index 98e613b6..e66ce91 100644
--- a/third_party/blink/web_tests/webexposed/nonstable-css-properties.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/nonstable-css-properties.html
@@ -3,7 +3,7 @@
 <body>
 <div id='el'></div>
 
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 <script>
 
 description("Test getting and setting nonstable css properties to non-default values");
diff --git a/third_party/blink/web_tests/webexposed/permissions-attribute-expected.txt b/third_party/blink/web_tests/http/tests/webexposed/permissions-attribute-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/webexposed/permissions-attribute-expected.txt
rename to third_party/blink/web_tests/http/tests/webexposed/permissions-attribute-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/permissions-attribute.html b/third_party/blink/web_tests/http/tests/webexposed/permissions-attribute.html
similarity index 74%
rename from third_party/blink/web_tests/webexposed/permissions-attribute.html
rename to third_party/blink/web_tests/http/tests/webexposed/permissions-attribute.html
index 89048cf..8ab0ad8 100644
--- a/third_party/blink/web_tests/webexposed/permissions-attribute.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/permissions-attribute.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
+<script src="/js-test-resources/js-test.js"></script>
 <body>
 <script>
 description('Tests that the permissions attribute is not exposed for stable');
 </script>
-<iframe permissions="abcdefg"></iframe>
\ No newline at end of file
+<iframe permissions="abcdefg"></iframe>
diff --git a/third_party/blink/web_tests/webexposed/resources/element-instance-property-listing.js b/third_party/blink/web_tests/http/tests/webexposed/resources/element-instance-property-listing.js
similarity index 100%
rename from third_party/blink/web_tests/webexposed/resources/element-instance-property-listing.js
rename to third_party/blink/web_tests/http/tests/webexposed/resources/element-instance-property-listing.js
diff --git a/third_party/blink/web_tests/webexposed/resources/global-constructors-attributes-worker.js b/third_party/blink/web_tests/http/tests/webexposed/resources/global-constructors-attributes-worker.js.php
similarity index 87%
rename from third_party/blink/web_tests/webexposed/resources/global-constructors-attributes-worker.js
rename to third_party/blink/web_tests/http/tests/webexposed/resources/global-constructors-attributes-worker.js.php
index 850eb85a..d52bab4 100644
--- a/third_party/blink/web_tests/webexposed/resources/global-constructors-attributes-worker.js
+++ b/third_party/blink/web_tests/http/tests/webexposed/resources/global-constructors-attributes-worker.js.php
@@ -1,5 +1,9 @@
-if (this.importScripts)
-    importScripts('../../resources/js-test.js');
+<?php
+  header("Content-Type: application/javascript");
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?>if (this.importScripts)
+    importScripts('/js-test-resources/js-test.js');
 
 description("Test to ensure that global constructors in workers environment have the right attributes");
 
diff --git a/third_party/blink/web_tests/webexposed/resources/global-constructors-attributes.js b/third_party/blink/web_tests/http/tests/webexposed/resources/global-constructors-attributes.js
similarity index 100%
rename from third_party/blink/web_tests/webexposed/resources/global-constructors-attributes.js
rename to third_party/blink/web_tests/http/tests/webexposed/resources/global-constructors-attributes.js
diff --git a/third_party/blink/web_tests/webexposed/resources/global-interface-listing-worker.js b/third_party/blink/web_tests/http/tests/webexposed/resources/global-interface-listing-worker.js.php
similarity index 71%
rename from third_party/blink/web_tests/webexposed/resources/global-interface-listing-worker.js
rename to third_party/blink/web_tests/http/tests/webexposed/resources/global-interface-listing-worker.js.php
index 990e059..45d84d7 100644
--- a/third_party/blink/web_tests/webexposed/resources/global-interface-listing-worker.js
+++ b/third_party/blink/web_tests/http/tests/webexposed/resources/global-interface-listing-worker.js.php
@@ -1,11 +1,15 @@
-// Avoid polluting the global scope.
+<?php
+  header("Content-Type: application/javascript");
+  header("Cross-Origin-Opener-Policy: same-origin");
+  header("Cross-Origin-Embedder-Policy: require-corp");
+?>// Avoid polluting the global scope.
 (function(globalObject) {
 
   // Save the list of property names of the global object before loading other scripts.
   var propertyNamesInGlobal = Object.getOwnPropertyNames(globalObject);
 
-  importScripts('../../resources/js-test.js');
-  importScripts('../../resources/global-interface-listing.js');
+  importScripts('/js-test-resources/js-test.js');
+  importScripts('/js-test-resources/global-interface-listing.js');
 
   function runTest(platformSpecific) {
     globalInterfaceListing(
diff --git a/third_party/blink/web_tests/webexposed/wake-lock.html b/third_party/blink/web_tests/http/tests/webexposed/wake-lock.html
similarity index 84%
rename from third_party/blink/web_tests/webexposed/wake-lock.html
rename to third_party/blink/web_tests/http/tests/webexposed/wake-lock.html
index 25738846..07c10efb 100644
--- a/third_party/blink/web_tests/webexposed/wake-lock.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/wake-lock.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <html>
 <body>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
+<script src="/js-test-resources/testharness.js"></script>
+<script src="/js-test-resources/testharnessreport.js"></script>
 <script>
 'use strict';
 
diff --git a/third_party/blink/web_tests/webexposed/web-animations-api.html b/third_party/blink/web_tests/http/tests/webexposed/web-animations-api.html
similarity index 79%
rename from third_party/blink/web_tests/webexposed/web-animations-api.html
rename to third_party/blink/web_tests/http/tests/webexposed/web-animations-api.html
index f8c85d495..dce47e5d 100644
--- a/third_party/blink/web_tests/webexposed/web-animations-api.html
+++ b/third_party/blink/web_tests/http/tests/webexposed/web-animations-api.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
+<script src="/js-test-resources/testharness.js"></script>
+<script src="/js-test-resources/testharnessreport.js"></script>
 <script>
 test(function() {
     assert_true('animate' in Element.prototype);
diff --git a/third_party/blink/web_tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode-expected-mismatch.html b/third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode-expected-mismatch.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode-expected-mismatch.html
rename to third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode-expected-mismatch.html
diff --git a/third_party/blink/web_tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode.html b/third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode.html
rename to third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-exposed-to-quirks-mode.html
diff --git a/third_party/blink/web_tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode-expected.html b/third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode-expected.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode-expected.html
rename to third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode-expected.html
diff --git a/third_party/blink/web_tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode.html b/third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode.html
similarity index 100%
rename from third_party/blink/web_tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode.html
rename to third_party/blink/web_tests/http/tests/webexposed/webkit-focus-ring-not-exposed-to-standards-mode.html
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/mathml/relations/css-styling/display-2-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/mathml/relations/css-styling/display-2-expected.txt
deleted file mode 100644
index 57a3c69..0000000
--- a/third_party/blink/web_tests/platform/linux/external/wpt/mathml/relations/css-styling/display-2-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-This is a testharness.js-based test.
-PASS block display
-PASS block display with contrained width
-PASS list display inside display block
-PASS inline display
-PASS inline-block display
-FAIL table display (math) assert_approx_equals: block size expected 80 +/- 1 but got 78
-PASS table display (mrow)
-FAIL inline-table display (math) assert_approx_equals: block size expected 60 +/- 1 but got 58
-PASS inline-table display (mrow)
-PASS flexbox display (math)
-PASS flexbox display (mrow)
-PASS grid display (math)
-PASS grid display (mrow)
-FAIL ruby display (math) assert_approx_equals: block size expected 80 +/- 1 but got 30
-FAIL ruby display (mrow) assert_approx_equals: block size expected 80 +/- 1 but got 45
-FAIL block display with column width (math) assert_approx_equals: block size expected 80 +/- 1 but got 45
-FAIL block display with column width (mrow) assert_approx_equals: block size expected 80 +/- 1 but got 45
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
new file mode 100644
index 0000000..ff9b19b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
new file mode 100644
index 0000000..8f8761d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
new file mode 100644
index 0000000..cc98acf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
new file mode 100644
index 0000000..4cff8e5
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
new file mode 100644
index 0000000..321809459
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
new file mode 100644
index 0000000..6373580
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
new file mode 100644
index 0000000..47340fa
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
new file mode 100644
index 0000000..17a4550
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
new file mode 100644
index 0000000..4e7e802
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
new file mode 100644
index 0000000..adc6237
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
index 3d282b91..8237e9a 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/platform/linux/virtual/stable/http/tests/webexposed/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/OWNERS
rename to third_party/blink/web_tests/platform/linux/virtual/stable/http/tests/webexposed/OWNERS
diff --git a/third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/linux/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
rename to third_party/blink/web_tests/platform/linux/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
similarity index 87%
rename from third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index 2bdb3c31..76acea13 100644
--- a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
similarity index 87%
rename from third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index 9c23b3a..13f6265 100644
--- a/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac-mac-arm11.0/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
new file mode 100644
index 0000000..37800c2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
new file mode 100644
index 0000000..1aea4a6
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
new file mode 100644
index 0000000..1719044f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
new file mode 100644
index 0000000..7c98ee4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
new file mode 100644
index 0000000..f2ff5fb6
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
new file mode 100644
index 0000000..813578d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
new file mode 100644
index 0000000..be7c0ef
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
new file mode 100644
index 0000000..2bc0a98
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
new file mode 100644
index 0000000..0dd9686b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
new file mode 100644
index 0000000..9585898
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
new file mode 100644
index 0000000..21abca1
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
new file mode 100644
index 0000000..e69427a7
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
new file mode 100644
index 0000000..5520605e
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
new file mode 100644
index 0000000..2d41c27
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
new file mode 100644
index 0000000..52debb26
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
new file mode 100644
index 0000000..555a557
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
new file mode 100644
index 0000000..b137573
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
new file mode 100644
index 0000000..996a977
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
index 065cf5c0..1c92aaa 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/OWNERS
rename to third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/OWNERS
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
similarity index 88%
rename from third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index 5c8c872..37f3ee90 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
rename to third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
similarity index 88%
rename from third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
rename to third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index 802ec99..516a3fde 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface BarcodeDetector
 [Worker]     static method getSupportedFormats
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/mathml/relations/css-styling/display-2-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/mathml/relations/css-styling/display-2-expected.txt
deleted file mode 100644
index 57a3c69..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/mathml/relations/css-styling/display-2-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-This is a testharness.js-based test.
-PASS block display
-PASS block display with contrained width
-PASS list display inside display block
-PASS inline display
-PASS inline-block display
-FAIL table display (math) assert_approx_equals: block size expected 80 +/- 1 but got 78
-PASS table display (mrow)
-FAIL inline-table display (math) assert_approx_equals: block size expected 60 +/- 1 but got 58
-PASS inline-table display (mrow)
-PASS flexbox display (math)
-PASS flexbox display (mrow)
-PASS grid display (math)
-PASS grid display (mrow)
-FAIL ruby display (math) assert_approx_equals: block size expected 80 +/- 1 but got 30
-FAIL ruby display (mrow) assert_approx_equals: block size expected 80 +/- 1 but got 45
-FAIL block display with column width (math) assert_approx_equals: block size expected 80 +/- 1 but got 45
-FAIL block display with column width (mrow) assert_approx_equals: block size expected 80 +/- 1 but got 45
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
new file mode 100644
index 0000000..2a39c8b4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
new file mode 100644
index 0000000..01a79e8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacing-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
new file mode 100644
index 0000000..cdf7138
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
new file mode 100644
index 0000000..e5d625cd
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
new file mode 100644
index 0000000..c37a649
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
new file mode 100644
index 0000000..481c517
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-squeeze-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
new file mode 100644
index 0000000..efd698f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
new file mode 100644
index 0000000..a99c7e2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
new file mode 100644
index 0000000..90b79643
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-3-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
new file mode 100644
index 0000000..c7bd6b2
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/select-textLength-spacingAndGlyphs-stretch-4-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
index 2433707..a2f69514 100644
--- a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/text/text-selection-text-01-b-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/platform/win/virtual/stable/http/tests/webexposed/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/platform/win/virtual/stable/webexposed/OWNERS
rename to third_party/blink/web_tests/platform/win/virtual/stable/http/tests/webexposed/OWNERS
diff --git a/third_party/blink/web_tests/platform/win/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/win/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
rename to third_party/blink/web_tests/platform/win/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
diff --git a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/platform/win7/virtual/stable/http/tests/webexposed/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/OWNERS
rename to third_party/blink/web_tests/platform/win7/virtual/stable/http/tests/webexposed/OWNERS
diff --git a/third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win7/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
rename to third_party/blink/web_tests/platform/win7/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
rename to third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt
index 31c4c9cf..4cd3c09 100644
--- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/element-instance-property-listing-expected.txt
@@ -22,6 +22,7 @@
     property ENTITY_REFERENCE_NODE
     property NOTATION_NODE
     property PROCESSING_INSTRUCTION_NODE
+    property SetSanitizedHTML
     property TEXT_NODE
     property accessKey
     property accessibleNode
@@ -655,6 +656,7 @@
     property allow
     property allowFullscreen
     property allowPaymentRequest
+    property anonymous
     property contentDocument
     property contentWindow
     property csp
@@ -1242,6 +1244,7 @@
     property ENTITY_REFERENCE_NODE
     property NOTATION_NODE
     property PROCESSING_INSTRUCTION_NODE
+    property SetSanitizedHTML
     property TEXT_NODE
     property accessibleNode
     property addEventListener
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt
similarity index 99%
copy from third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
copy to third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt
index f7025a0..022721a 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/anonymous-iframe/http/tests/webexposed/global-interface-listing-expected.txt
@@ -2250,6 +2250,7 @@
     getter shadowRoot
     getter slot
     getter tagName
+    method SetSanitizedHTML
     method after
     method animate
     method append
@@ -3556,6 +3557,7 @@
     getter allow
     getter allowFullscreen
     getter allowPaymentRequest
+    getter anonymous
     getter contentDocument
     getter contentWindow
     getter csp
@@ -3580,6 +3582,7 @@
     setter allow
     setter allowFullscreen
     setter allowPaymentRequest
+    setter anonymous
     setter csp
     setter frameBorder
     setter height
@@ -6217,6 +6220,7 @@
     method getEntriesByType
     method mark
     method measure
+    method measureUserAgentSpecificMemory
     method now
     method setResourceTimingBufferSize
     method toJSON
@@ -8153,6 +8157,7 @@
     method config
     method constructor
     method sanitize
+    method sanitizeFor
     method sanitizeToString
 interface Scheduler
     attribute @@toStringTag
@@ -10645,6 +10650,10 @@
     method close
     method constructor
     method getWriter
+interface WritableStreamDefaultController
+    attribute @@toStringTag
+    method constructor
+    method error
 interface WritableStreamDefaultWriter
     attribute @@toStringTag
     getter closed
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/element-instance-property-listing-expected.txt
deleted file mode 100644
index f652650..0000000
--- a/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/element-instance-property-listing-expected.txt
+++ /dev/null
@@ -1,2324 +0,0 @@
-This test documents all properties on all element instances.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-[HTML NAMESPACE ELEMENT PROPERTIES]
-namespace http://www.w3.org/1999/xhtml
-<common>
-    property ATTRIBUTE_NODE
-    property CDATA_SECTION_NODE
-    property COMMENT_NODE
-    property DOCUMENT_FRAGMENT_NODE
-    property DOCUMENT_NODE
-    property DOCUMENT_POSITION_CONTAINED_BY
-    property DOCUMENT_POSITION_CONTAINS
-    property DOCUMENT_POSITION_DISCONNECTED
-    property DOCUMENT_POSITION_FOLLOWING
-    property DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
-    property DOCUMENT_POSITION_PRECEDING
-    property DOCUMENT_TYPE_NODE
-    property ELEMENT_NODE
-    property ENTITY_NODE
-    property ENTITY_REFERENCE_NODE
-    property NOTATION_NODE
-    property PROCESSING_INSTRUCTION_NODE
-    property TEXT_NODE
-    property accessKey
-    property accessibleNode
-    property addEventListener
-    property after
-    property animate
-    property append
-    property appendChild
-    property ariaActiveDescendantElement
-    property ariaAtomic
-    property ariaAutoComplete
-    property ariaBusy
-    property ariaChecked
-    property ariaColCount
-    property ariaColIndex
-    property ariaColSpan
-    property ariaControlsElements
-    property ariaCurrent
-    property ariaDescribedByElements
-    property ariaDescription
-    property ariaDetailsElements
-    property ariaDisabled
-    property ariaErrorMessageElement
-    property ariaExpanded
-    property ariaFlowToElements
-    property ariaHasPopup
-    property ariaHidden
-    property ariaKeyShortcuts
-    property ariaLabel
-    property ariaLabelledByElements
-    property ariaLevel
-    property ariaLive
-    property ariaModal
-    property ariaMultiLine
-    property ariaMultiSelectable
-    property ariaOrientation
-    property ariaOwnsElements
-    property ariaPlaceholder
-    property ariaPosInSet
-    property ariaPressed
-    property ariaReadOnly
-    property ariaRelevant
-    property ariaRequired
-    property ariaRoleDescription
-    property ariaRowCount
-    property ariaRowIndex
-    property ariaRowSpan
-    property ariaSelected
-    property ariaSetSize
-    property ariaSort
-    property ariaValueMax
-    property ariaValueMin
-    property ariaValueNow
-    property ariaValueText
-    property ariaVirtualContent
-    property assignedSlot
-    property attachInternals
-    property attachShadow
-    property attributeStyleMap
-    property attributes
-    property autocapitalize
-    property autofocus
-    property baseURI
-    property before
-    property blur
-    property childElementCount
-    property childNodes
-    property children
-    property classList
-    property className
-    property click
-    property clientHeight
-    property clientLeft
-    property clientTop
-    property clientWidth
-    property cloneNode
-    property closest
-    property compareDocumentPosition
-    property computedName
-    property computedRole
-    property computedStyleMap
-    property contains
-    property contentEditable
-    property dataset
-    property dir
-    property dispatchEvent
-    property draggable
-    property editContext
-    property elementTiming
-    property enterKeyHint
-    property firstChild
-    property firstElementChild
-    property focus
-    property getAnimations
-    property getAttribute
-    property getAttributeNS
-    property getAttributeNames
-    property getAttributeNode
-    property getAttributeNodeNS
-    property getBoundingClientRect
-    property getClientRects
-    property getElementsByClassName
-    property getElementsByTagName
-    property getElementsByTagNameNS
-    property getInnerHTML
-    property getRootNode
-    property hasAttribute
-    property hasAttributeNS
-    property hasAttributes
-    property hasChildNodes
-    property hasPointerCapture
-    property hidden
-    property id
-    property inert
-    property innerHTML
-    property innerText
-    property inputMode
-    property insertAdjacentElement
-    property insertAdjacentHTML
-    property insertAdjacentText
-    property insertBefore
-    property isConnected
-    property isContentEditable
-    property isDefaultNamespace
-    property isEqualNode
-    property isSameNode
-    property lang
-    property lastChild
-    property lastElementChild
-    property localName
-    property lookupNamespaceURI
-    property lookupPrefix
-    property matches
-    property namespaceURI
-    property nextElementSibling
-    property nextSibling
-    property nodeName
-    property nodeType
-    property nodeValue
-    property nonce
-    property normalize
-    property offsetHeight
-    property offsetLeft
-    property offsetParent
-    property offsetTop
-    property offsetWidth
-    property onabort
-    property onanimationend
-    property onanimationiteration
-    property onanimationstart
-    property onauxclick
-    property onbeforecopy
-    property onbeforecut
-    property onbeforematch
-    property onbeforepaste
-    property onbeforexrselect
-    property onblur
-    property oncancel
-    property oncanplay
-    property oncanplaythrough
-    property onchange
-    property onclick
-    property onclose
-    property oncontextmenu
-    property oncopy
-    property oncuechange
-    property oncut
-    property ondblclick
-    property ondrag
-    property ondragend
-    property ondragenter
-    property ondragleave
-    property ondragover
-    property ondragstart
-    property ondrop
-    property ondurationchange
-    property onemptied
-    property onended
-    property onerror
-    property onfocus
-    property onformdata
-    property onfullscreenchange
-    property onfullscreenerror
-    property ongotpointercapture
-    property oninput
-    property oninvalid
-    property onkeydown
-    property onkeypress
-    property onkeyup
-    property onload
-    property onloadeddata
-    property onloadedmetadata
-    property onloadstart
-    property onlostpointercapture
-    property onmousedown
-    property onmouseenter
-    property onmouseleave
-    property onmousemove
-    property onmouseout
-    property onmouseover
-    property onmouseup
-    property onmousewheel
-    property onoverscroll
-    property onpaste
-    property onpause
-    property onplay
-    property onplaying
-    property onpointercancel
-    property onpointerdown
-    property onpointerenter
-    property onpointerleave
-    property onpointermove
-    property onpointerout
-    property onpointerover
-    property onpointerrawupdate
-    property onpointerup
-    property onprogress
-    property onratechange
-    property onreset
-    property onresize
-    property onscroll
-    property onscrollend
-    property onsearch
-    property onseeked
-    property onseeking
-    property onselect
-    property onselectionchange
-    property onselectstart
-    property onstalled
-    property onsubmit
-    property onsuspend
-    property ontimeupdate
-    property ontoggle
-    property ontouchcancel
-    property ontouchend
-    property ontouchmove
-    property ontouchstart
-    property ontransitioncancel
-    property ontransitionend
-    property ontransitionrun
-    property ontransitionstart
-    property onvolumechange
-    property onwaiting
-    property onwebkitanimationend
-    property onwebkitanimationiteration
-    property onwebkitanimationstart
-    property onwebkitfullscreenchange
-    property onwebkitfullscreenerror
-    property onwebkittransitionend
-    property onwheel
-    property outerHTML
-    property outerText
-    property ownerDocument
-    property parentElement
-    property parentNode
-    property part
-    property prefix
-    property prepend
-    property previousElementSibling
-    property previousSibling
-    property querySelector
-    property querySelectorAll
-    property releasePointerCapture
-    property remove
-    property removeAttribute
-    property removeAttributeNS
-    property removeAttributeNode
-    property removeChild
-    property removeEventListener
-    property replaceChild
-    property replaceChildren
-    property replaceWith
-    property requestFullscreen
-    property requestPointerLock
-    property role
-    property scroll
-    property scrollBy
-    property scrollHeight
-    property scrollIntoView
-    property scrollIntoViewIfNeeded
-    property scrollLeft
-    property scrollTo
-    property scrollTop
-    property scrollWidth
-    property setAttribute
-    property setAttributeNS
-    property setAttributeNode
-    property setAttributeNodeNS
-    property setPointerCapture
-    property shadowRoot
-    property slot
-    property spellcheck
-    property style
-    property tabIndex
-    property tagName
-    property textContent
-    property title
-    property toString
-    property toggleAttribute
-    property translate
-    property virtualKeyboardPolicy
-    property webkitMatchesSelector
-    property webkitRequestFullScreen
-    property webkitRequestFullscreen
-html element a
-    property attributionDestination
-    property attributionExpiry
-    property attributionReportTo
-    property attributionSourceEventId
-    property attributionSourcePriority
-    property charset
-    property coords
-    property download
-    property hash
-    property host
-    property hostname
-    property href
-    property hrefTranslate
-    property hreflang
-    property name
-    property origin
-    property password
-    property pathname
-    property ping
-    property port
-    property protocol
-    property referrerPolicy
-    property registerAttributionSource
-    property rel
-    property relList
-    property rev
-    property search
-    property shape
-    property target
-    property text
-    property type
-    property username
-html element abbr
-html element acronym
-html element address
-html element area
-    property alt
-    property coords
-    property download
-    property hash
-    property host
-    property hostname
-    property href
-    property noHref
-    property origin
-    property password
-    property pathname
-    property ping
-    property port
-    property protocol
-    property referrerPolicy
-    property rel
-    property relList
-    property search
-    property shape
-    property target
-    property username
-html element article
-html element aside
-html element audio
-    property HAVE_CURRENT_DATA
-    property HAVE_ENOUGH_DATA
-    property HAVE_FUTURE_DATA
-    property HAVE_METADATA
-    property HAVE_NOTHING
-    property NETWORK_EMPTY
-    property NETWORK_IDLE
-    property NETWORK_LOADING
-    property NETWORK_NO_SOURCE
-    property addTextTrack
-    property audioTracks
-    property autoplay
-    property buffered
-    property canPlayType
-    property captureStream
-    property controls
-    property controlsList
-    property crossOrigin
-    property currentSrc
-    property currentTime
-    property defaultMuted
-    property defaultPlaybackRate
-    property disableRemotePlayback
-    property duration
-    property ended
-    property error
-    property latencyHint
-    property load
-    property loop
-    property mediaKeys
-    property muted
-    property networkState
-    property onencrypted
-    property onwaitingforkey
-    property pause
-    property paused
-    property play
-    property playbackRate
-    property played
-    property preload
-    property preservesPitch
-    property readyState
-    property remote
-    property seekable
-    property seeking
-    property setMediaKeys
-    property setSinkId
-    property sinkId
-    property src
-    property srcObject
-    property textTracks
-    property videoTracks
-    property volume
-    property webkitAudioDecodedByteCount
-    property webkitVideoDecodedByteCount
-html element b
-html element base
-    property href
-    property target
-html element basefont
-html element bdi
-html element bdo
-html element big
-html element blockquote
-    property cite
-html element body
-    property aLink
-    property background
-    property bgColor
-    property link
-    property onafterprint
-    property onbeforeprint
-    property onbeforeunload
-    property onhashchange
-    property onlanguagechange
-    property onmessage
-    property onmessageerror
-    property onoffline
-    property ononline
-    property onpagehide
-    property onpageshow
-    property onpopstate
-    property onrejectionhandled
-    property onstorage
-    property ontimezonechange
-    property onunhandledrejection
-    property onunload
-    property text
-    property vLink
-html element br
-    property clear
-html element button
-    property checkValidity
-    property disabled
-    property form
-    property formAction
-    property formEnctype
-    property formMethod
-    property formNoValidate
-    property formTarget
-    property labels
-    property name
-    property reportValidity
-    property setCustomValidity
-    property type
-    property validationMessage
-    property validity
-    property value
-    property willValidate
-html element canvas
-    property captureStream
-    property convertToBlob
-    property getContext
-    property height
-    property toBlob
-    property toDataURL
-    property transferControlToOffscreen
-    property width
-html element caption
-    property align
-html element center
-html element cite
-html element code
-html element col
-    property align
-    property ch
-    property chOff
-    property span
-    property vAlign
-    property width
-html element colgroup
-    property align
-    property ch
-    property chOff
-    property span
-    property vAlign
-    property width
-html element data
-    property value
-html element datalist
-    property options
-html element dd
-html element del
-    property cite
-    property dateTime
-html element details
-    property open
-html element dfn
-html element dialog
-    property close
-    property open
-    property returnValue
-    property show
-    property showModal
-html element dir
-    property compact
-html element div
-    property align
-html element dl
-    property compact
-html element dt
-html element em
-html element embed
-    property align
-    property getSVGDocument
-    property height
-    property name
-    property src
-    property type
-    property width
-html element fencedframe
-    property src
-html element fieldset
-    property checkValidity
-    property disabled
-    property elements
-    property form
-    property name
-    property reportValidity
-    property setCustomValidity
-    property type
-    property validationMessage
-    property validity
-    property willValidate
-html element figcaption
-html element figure
-html element font
-    property color
-    property face
-    property size
-html element footer
-html element form
-    property acceptCharset
-    property action
-    property autocomplete
-    property checkValidity
-    property elements
-    property encoding
-    property enctype
-    property length
-    property method
-    property name
-    property noValidate
-    property reportValidity
-    property requestSubmit
-    property reset
-    property submit
-    property target
-html element frame
-    property contentDocument
-    property contentWindow
-    property frameBorder
-    property longDesc
-    property marginHeight
-    property marginWidth
-    property name
-    property noResize
-    property scrolling
-    property src
-html element frameset
-    property cols
-    property onafterprint
-    property onbeforeprint
-    property onbeforeunload
-    property onhashchange
-    property onlanguagechange
-    property onmessage
-    property onmessageerror
-    property onoffline
-    property ononline
-    property onpagehide
-    property onpageshow
-    property onpopstate
-    property onrejectionhandled
-    property onstorage
-    property ontimezonechange
-    property onunhandledrejection
-    property onunload
-    property rows
-html element h1
-    property align
-html element h2
-    property align
-html element h3
-    property align
-html element h4
-    property align
-html element h5
-    property align
-html element h6
-    property align
-html element head
-html element header
-html element hgroup
-html element hr
-    property align
-    property color
-    property noShade
-    property size
-    property width
-html element html
-    property version
-html element i
-html element iframe
-    property align
-    property allow
-    property allowFullscreen
-    property allowPaymentRequest
-    property anonymous
-    property contentDocument
-    property contentWindow
-    property csp
-    property featurePolicy
-    property frameBorder
-    property getSVGDocument
-    property height
-    property loading
-    property longDesc
-    property marginHeight
-    property marginWidth
-    property name
-    property policy
-    property referrerPolicy
-    property sandbox
-    property scrolling
-    property src
-    property srcdoc
-    property width
-html element img
-    property align
-    property alt
-    property border
-    property complete
-    property crossOrigin
-    property currentSrc
-    property decode
-    property decoding
-    property height
-    property hspace
-    property importance
-    property isMap
-    property loading
-    property longDesc
-    property lowsrc
-    property name
-    property naturalHeight
-    property naturalWidth
-    property referrerPolicy
-    property sizes
-    property src
-    property srcset
-    property useMap
-    property vspace
-    property width
-    property x
-    property y
-html element input
-    property accept
-    property align
-    property alt
-    property autocomplete
-    property checkValidity
-    property checked
-    property defaultChecked
-    property defaultValue
-    property dirName
-    property disabled
-    property files
-    property form
-    property formAction
-    property formEnctype
-    property formMethod
-    property formNoValidate
-    property formTarget
-    property height
-    property incremental
-    property indeterminate
-    property labels
-    property list
-    property max
-    property maxLength
-    property min
-    property minLength
-    property multiple
-    property name
-    property pattern
-    property placeholder
-    property readOnly
-    property reportValidity
-    property required
-    property select
-    property selectionDirection
-    property selectionEnd
-    property selectionStart
-    property setCustomValidity
-    property setRangeText
-    property setSelectionRange
-    property size
-    property src
-    property step
-    property stepDown
-    property stepUp
-    property type
-    property useMap
-    property validationMessage
-    property validity
-    property value
-    property valueAsDate
-    property valueAsNumber
-    property webkitEntries
-    property webkitdirectory
-    property width
-    property willValidate
-html element ins
-    property cite
-    property dateTime
-html element kbd
-html element label
-    property control
-    property form
-    property htmlFor
-html element layer
-html element legend
-    property align
-    property form
-html element li
-    property type
-    property value
-html element link
-    property as
-    property charset
-    property crossOrigin
-    property disabled
-    property href
-    property hreflang
-    property imageSizes
-    property imageSrcset
-    property importance
-    property integrity
-    property media
-    property referrerPolicy
-    property rel
-    property relList
-    property resources
-    property rev
-    property scopes
-    property sheet
-    property sizes
-    property target
-    property type
-html element listing
-    property width
-html element main
-html element map
-    property areas
-    property name
-html element mark
-html element marquee
-    property behavior
-    property bgColor
-    property direction
-    property height
-    property hspace
-    property loop
-    property scrollAmount
-    property scrollDelay
-    property start
-    property stop
-    property trueSpeed
-    property vspace
-    property width
-html element menu
-    property compact
-html element meta
-    property content
-    property httpEquiv
-    property media
-    property name
-    property scheme
-html element meter
-    property high
-    property labels
-    property low
-    property max
-    property min
-    property optimum
-    property value
-html element nav
-html element nobr
-html element noembed
-html element noframes
-html element nolayer
-html element noscript
-html element object
-    property align
-    property archive
-    property border
-    property checkValidity
-    property code
-    property codeBase
-    property codeType
-    property contentDocument
-    property contentWindow
-    property data
-    property declare
-    property form
-    property getSVGDocument
-    property height
-    property hspace
-    property name
-    property reportValidity
-    property setCustomValidity
-    property standby
-    property type
-    property useMap
-    property validationMessage
-    property validity
-    property vspace
-    property width
-    property willValidate
-html element ol
-    property compact
-    property reversed
-    property start
-    property type
-html element optgroup
-    property disabled
-    property label
-html element option
-    property defaultSelected
-    property disabled
-    property form
-    property index
-    property label
-    property selected
-    property text
-    property value
-html element output
-    property checkValidity
-    property defaultValue
-    property form
-    property htmlFor
-    property labels
-    property name
-    property reportValidity
-    property setCustomValidity
-    property type
-    property validationMessage
-    property validity
-    property value
-    property willValidate
-html element p
-    property align
-html element param
-    property name
-    property type
-    property value
-    property valueType
-html element picture
-html element plaintext
-html element popup
-    property anchor
-    property hide
-    property initiallyOpen
-    property open
-    property show
-html element pre
-    property width
-html element progress
-    property labels
-    property max
-    property position
-    property value
-html element q
-    property cite
-html element rb
-html element rp
-html element rt
-html element rtc
-html element ruby
-html element s
-html element samp
-html element script
-    property async
-    property charset
-    property crossOrigin
-    property defer
-    property event
-    property htmlFor
-    property importance
-    property integrity
-    property noModule
-    property referrerPolicy
-    property src
-    property text
-    property type
-html element section
-html element select
-    property add
-    property autocomplete
-    property checkValidity
-    property disabled
-    property form
-    property item
-    property labels
-    property length
-    property multiple
-    property name
-    property namedItem
-    property options
-    property reportValidity
-    property required
-    property selectedIndex
-    property selectedOptions
-    property setCustomValidity
-    property size
-    property type
-    property validationMessage
-    property validity
-    property value
-    property willValidate
-html element selectmenu
-    property open
-    property value
-html element slot
-    property assign
-    property assignedElements
-    property assignedNodes
-    property name
-html element small
-html element source
-    property height
-    property media
-    property sizes
-    property src
-    property srcset
-    property type
-    property width
-html element span
-html element strike
-html element strong
-html element style
-    property disabled
-    property media
-    property sheet
-    property type
-html element sub
-html element summary
-html element sup
-html element table
-    property align
-    property bgColor
-    property border
-    property caption
-    property cellPadding
-    property cellSpacing
-    property createCaption
-    property createTBody
-    property createTFoot
-    property createTHead
-    property deleteCaption
-    property deleteRow
-    property deleteTFoot
-    property deleteTHead
-    property frame
-    property insertRow
-    property rows
-    property rules
-    property summary
-    property tBodies
-    property tFoot
-    property tHead
-    property width
-html element tbody
-    property align
-    property ch
-    property chOff
-    property deleteRow
-    property insertRow
-    property rows
-    property vAlign
-html element td
-    property abbr
-    property align
-    property axis
-    property bgColor
-    property cellIndex
-    property ch
-    property chOff
-    property colSpan
-    property headers
-    property height
-    property noWrap
-    property rowSpan
-    property scope
-    property vAlign
-    property width
-html element template
-    property content
-html element textarea
-    property autocomplete
-    property checkValidity
-    property cols
-    property defaultValue
-    property dirName
-    property disabled
-    property form
-    property labels
-    property maxLength
-    property minLength
-    property name
-    property placeholder
-    property readOnly
-    property reportValidity
-    property required
-    property rows
-    property select
-    property selectionDirection
-    property selectionEnd
-    property selectionStart
-    property setCustomValidity
-    property setRangeText
-    property setSelectionRange
-    property textLength
-    property type
-    property validationMessage
-    property validity
-    property value
-    property willValidate
-    property wrap
-html element tfoot
-    property align
-    property ch
-    property chOff
-    property deleteRow
-    property insertRow
-    property rows
-    property vAlign
-html element th
-    property abbr
-    property align
-    property axis
-    property bgColor
-    property cellIndex
-    property ch
-    property chOff
-    property colSpan
-    property headers
-    property height
-    property noWrap
-    property rowSpan
-    property scope
-    property vAlign
-    property width
-html element thead
-    property align
-    property ch
-    property chOff
-    property deleteRow
-    property insertRow
-    property rows
-    property vAlign
-html element time
-    property dateTime
-html element title
-    property text
-html element tr
-    property align
-    property bgColor
-    property cells
-    property ch
-    property chOff
-    property deleteCell
-    property insertCell
-    property rowIndex
-    property sectionRowIndex
-    property vAlign
-html element track
-    property ERROR
-    property LOADED
-    property LOADING
-    property NONE
-    property default
-    property kind
-    property label
-    property readyState
-    property src
-    property srclang
-    property track
-html element tt
-html element u
-html element ul
-    property compact
-    property type
-html element var
-html element video
-    property HAVE_CURRENT_DATA
-    property HAVE_ENOUGH_DATA
-    property HAVE_FUTURE_DATA
-    property HAVE_METADATA
-    property HAVE_NOTHING
-    property NETWORK_EMPTY
-    property NETWORK_IDLE
-    property NETWORK_LOADING
-    property NETWORK_NO_SOURCE
-    property addTextTrack
-    property audioTracks
-    property autoPictureInPicture
-    property autoplay
-    property buffered
-    property canPlayType
-    property cancelVideoFrameCallback
-    property captureStream
-    property controls
-    property controlsList
-    property crossOrigin
-    property currentSrc
-    property currentTime
-    property defaultMuted
-    property defaultPlaybackRate
-    property disablePictureInPicture
-    property disableRemotePlayback
-    property duration
-    property ended
-    property error
-    property getVideoPlaybackQuality
-    property height
-    property latencyHint
-    property load
-    property loop
-    property mediaKeys
-    property muted
-    property networkState
-    property onencrypted
-    property onenterpictureinpicture
-    property onleavepictureinpicture
-    property onwaitingforkey
-    property pause
-    property paused
-    property play
-    property playbackRate
-    property played
-    property playsInline
-    property poster
-    property preload
-    property preservesPitch
-    property readyState
-    property remote
-    property requestPictureInPicture
-    property requestVideoFrameCallback
-    property seekable
-    property seeking
-    property setMediaKeys
-    property setSinkId
-    property sinkId
-    property src
-    property srcObject
-    property textTracks
-    property videoHeight
-    property videoTracks
-    property videoWidth
-    property volume
-    property webkitAudioDecodedByteCount
-    property webkitDecodedFrameCount
-    property webkitDisplayingFullscreen
-    property webkitDroppedFrameCount
-    property webkitEnterFullScreen
-    property webkitEnterFullscreen
-    property webkitExitFullScreen
-    property webkitExitFullscreen
-    property webkitSupportsFullscreen
-    property webkitVideoDecodedByteCount
-    property width
-html element wbr
-html element xmp
-    property width
-[SVG NAMESPACE ELEMENT PROPERTIES]
-namespace http://www.w3.org/2000/svg
-<common>
-    property ATTRIBUTE_NODE
-    property CDATA_SECTION_NODE
-    property COMMENT_NODE
-    property DOCUMENT_FRAGMENT_NODE
-    property DOCUMENT_NODE
-    property DOCUMENT_POSITION_CONTAINED_BY
-    property DOCUMENT_POSITION_CONTAINS
-    property DOCUMENT_POSITION_DISCONNECTED
-    property DOCUMENT_POSITION_FOLLOWING
-    property DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
-    property DOCUMENT_POSITION_PRECEDING
-    property DOCUMENT_TYPE_NODE
-    property ELEMENT_NODE
-    property ENTITY_NODE
-    property ENTITY_REFERENCE_NODE
-    property NOTATION_NODE
-    property PROCESSING_INSTRUCTION_NODE
-    property TEXT_NODE
-    property accessibleNode
-    property addEventListener
-    property after
-    property animate
-    property append
-    property appendChild
-    property ariaActiveDescendantElement
-    property ariaAtomic
-    property ariaAutoComplete
-    property ariaBusy
-    property ariaChecked
-    property ariaColCount
-    property ariaColIndex
-    property ariaColSpan
-    property ariaControlsElements
-    property ariaCurrent
-    property ariaDescribedByElements
-    property ariaDescription
-    property ariaDetailsElements
-    property ariaDisabled
-    property ariaErrorMessageElement
-    property ariaExpanded
-    property ariaFlowToElements
-    property ariaHasPopup
-    property ariaHidden
-    property ariaKeyShortcuts
-    property ariaLabel
-    property ariaLabelledByElements
-    property ariaLevel
-    property ariaLive
-    property ariaModal
-    property ariaMultiLine
-    property ariaMultiSelectable
-    property ariaOrientation
-    property ariaOwnsElements
-    property ariaPlaceholder
-    property ariaPosInSet
-    property ariaPressed
-    property ariaReadOnly
-    property ariaRelevant
-    property ariaRequired
-    property ariaRoleDescription
-    property ariaRowCount
-    property ariaRowIndex
-    property ariaRowSpan
-    property ariaSelected
-    property ariaSetSize
-    property ariaSort
-    property ariaValueMax
-    property ariaValueMin
-    property ariaValueNow
-    property ariaValueText
-    property ariaVirtualContent
-    property assignedSlot
-    property attachShadow
-    property attributeStyleMap
-    property attributes
-    property autofocus
-    property baseURI
-    property before
-    property blur
-    property childElementCount
-    property childNodes
-    property children
-    property classList
-    property className
-    property clientHeight
-    property clientLeft
-    property clientTop
-    property clientWidth
-    property cloneNode
-    property closest
-    property compareDocumentPosition
-    property computedName
-    property computedRole
-    property computedStyleMap
-    property contains
-    property dataset
-    property dispatchEvent
-    property editContext
-    property elementTiming
-    property firstChild
-    property firstElementChild
-    property focus
-    property getAnimations
-    property getAttribute
-    property getAttributeNS
-    property getAttributeNames
-    property getAttributeNode
-    property getAttributeNodeNS
-    property getBoundingClientRect
-    property getClientRects
-    property getElementsByClassName
-    property getElementsByTagName
-    property getElementsByTagNameNS
-    property getInnerHTML
-    property getRootNode
-    property hasAttribute
-    property hasAttributeNS
-    property hasAttributes
-    property hasChildNodes
-    property hasPointerCapture
-    property id
-    property innerHTML
-    property insertAdjacentElement
-    property insertAdjacentHTML
-    property insertAdjacentText
-    property insertBefore
-    property isConnected
-    property isDefaultNamespace
-    property isEqualNode
-    property isSameNode
-    property lastChild
-    property lastElementChild
-    property localName
-    property lookupNamespaceURI
-    property lookupPrefix
-    property matches
-    property namespaceURI
-    property nextElementSibling
-    property nextSibling
-    property nodeName
-    property nodeType
-    property nodeValue
-    property nonce
-    property normalize
-    property onabort
-    property onanimationend
-    property onanimationiteration
-    property onanimationstart
-    property onauxclick
-    property onbeforecopy
-    property onbeforecut
-    property onbeforematch
-    property onbeforepaste
-    property onbeforexrselect
-    property onblur
-    property oncancel
-    property oncanplay
-    property oncanplaythrough
-    property onchange
-    property onclick
-    property onclose
-    property oncontextmenu
-    property oncopy
-    property oncuechange
-    property oncut
-    property ondblclick
-    property ondrag
-    property ondragend
-    property ondragenter
-    property ondragleave
-    property ondragover
-    property ondragstart
-    property ondrop
-    property ondurationchange
-    property onemptied
-    property onended
-    property onerror
-    property onfocus
-    property onformdata
-    property onfullscreenchange
-    property onfullscreenerror
-    property ongotpointercapture
-    property oninput
-    property oninvalid
-    property onkeydown
-    property onkeypress
-    property onkeyup
-    property onload
-    property onloadeddata
-    property onloadedmetadata
-    property onloadstart
-    property onlostpointercapture
-    property onmousedown
-    property onmouseenter
-    property onmouseleave
-    property onmousemove
-    property onmouseout
-    property onmouseover
-    property onmouseup
-    property onmousewheel
-    property onoverscroll
-    property onpaste
-    property onpause
-    property onplay
-    property onplaying
-    property onpointercancel
-    property onpointerdown
-    property onpointerenter
-    property onpointerleave
-    property onpointermove
-    property onpointerout
-    property onpointerover
-    property onpointerrawupdate
-    property onpointerup
-    property onprogress
-    property onratechange
-    property onreset
-    property onresize
-    property onscroll
-    property onscrollend
-    property onsearch
-    property onseeked
-    property onseeking
-    property onselect
-    property onselectionchange
-    property onselectstart
-    property onstalled
-    property onsubmit
-    property onsuspend
-    property ontimeupdate
-    property ontoggle
-    property ontouchcancel
-    property ontouchend
-    property ontouchmove
-    property ontouchstart
-    property ontransitioncancel
-    property ontransitionend
-    property ontransitionrun
-    property ontransitionstart
-    property onvolumechange
-    property onwaiting
-    property onwebkitanimationend
-    property onwebkitanimationiteration
-    property onwebkitanimationstart
-    property onwebkitfullscreenchange
-    property onwebkitfullscreenerror
-    property onwebkittransitionend
-    property onwheel
-    property outerHTML
-    property ownerDocument
-    property ownerSVGElement
-    property parentElement
-    property parentNode
-    property part
-    property prefix
-    property prepend
-    property previousElementSibling
-    property previousSibling
-    property querySelector
-    property querySelectorAll
-    property releasePointerCapture
-    property remove
-    property removeAttribute
-    property removeAttributeNS
-    property removeAttributeNode
-    property removeChild
-    property removeEventListener
-    property replaceChild
-    property replaceChildren
-    property replaceWith
-    property requestFullscreen
-    property requestPointerLock
-    property role
-    property scroll
-    property scrollBy
-    property scrollHeight
-    property scrollIntoView
-    property scrollIntoViewIfNeeded
-    property scrollLeft
-    property scrollTo
-    property scrollTop
-    property scrollWidth
-    property setAttribute
-    property setAttributeNS
-    property setAttributeNode
-    property setAttributeNodeNS
-    property setPointerCapture
-    property shadowRoot
-    property slot
-    property style
-    property tabIndex
-    property tagName
-    property textContent
-    property toggleAttribute
-    property viewportElement
-    property webkitMatchesSelector
-    property webkitRequestFullScreen
-    property webkitRequestFullscreen
-svg element a
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property href
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property target
-    property transform
-svg element animate
-    property beginElement
-    property beginElementAt
-    property endElement
-    property endElementAt
-    property getCurrentTime
-    property getSimpleDuration
-    property getStartTime
-    property onbegin
-    property onend
-    property onrepeat
-    property requiredExtensions
-    property systemLanguage
-    property targetElement
-svg element animateColor
-svg element animateMotion
-    property beginElement
-    property beginElementAt
-    property endElement
-    property endElementAt
-    property getCurrentTime
-    property getSimpleDuration
-    property getStartTime
-    property onbegin
-    property onend
-    property onrepeat
-    property requiredExtensions
-    property systemLanguage
-    property targetElement
-svg element animateTransform
-    property beginElement
-    property beginElementAt
-    property endElement
-    property endElementAt
-    property getCurrentTime
-    property getSimpleDuration
-    property getStartTime
-    property onbegin
-    property onend
-    property onrepeat
-    property requiredExtensions
-    property systemLanguage
-    property targetElement
-svg element circle
-    property cx
-    property cy
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property r
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element clipPath
-    property clipPathUnits
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element defs
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element desc
-svg element ellipse
-    property cx
-    property cy
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property requiredExtensions
-    property rx
-    property ry
-    property systemLanguage
-    property transform
-svg element feBlend
-    property SVG_FEBLEND_MODE_COLOR
-    property SVG_FEBLEND_MODE_COLOR_BURN
-    property SVG_FEBLEND_MODE_COLOR_DODGE
-    property SVG_FEBLEND_MODE_DARKEN
-    property SVG_FEBLEND_MODE_DIFFERENCE
-    property SVG_FEBLEND_MODE_EXCLUSION
-    property SVG_FEBLEND_MODE_HARD_LIGHT
-    property SVG_FEBLEND_MODE_HUE
-    property SVG_FEBLEND_MODE_LIGHTEN
-    property SVG_FEBLEND_MODE_LUMINOSITY
-    property SVG_FEBLEND_MODE_MULTIPLY
-    property SVG_FEBLEND_MODE_NORMAL
-    property SVG_FEBLEND_MODE_OVERLAY
-    property SVG_FEBLEND_MODE_SATURATION
-    property SVG_FEBLEND_MODE_SCREEN
-    property SVG_FEBLEND_MODE_SOFT_LIGHT
-    property SVG_FEBLEND_MODE_UNKNOWN
-    property height
-    property in1
-    property in2
-    property mode
-    property result
-    property width
-    property x
-    property y
-svg element feColorMatrix
-    property SVG_FECOLORMATRIX_TYPE_HUEROTATE
-    property SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA
-    property SVG_FECOLORMATRIX_TYPE_MATRIX
-    property SVG_FECOLORMATRIX_TYPE_SATURATE
-    property SVG_FECOLORMATRIX_TYPE_UNKNOWN
-    property height
-    property in1
-    property result
-    property type
-    property values
-    property width
-    property x
-    property y
-svg element feComponentTransfer
-    property height
-    property in1
-    property result
-    property width
-    property x
-    property y
-svg element feComposite
-    property SVG_FECOMPOSITE_OPERATOR_ARITHMETIC
-    property SVG_FECOMPOSITE_OPERATOR_ATOP
-    property SVG_FECOMPOSITE_OPERATOR_IN
-    property SVG_FECOMPOSITE_OPERATOR_OUT
-    property SVG_FECOMPOSITE_OPERATOR_OVER
-    property SVG_FECOMPOSITE_OPERATOR_UNKNOWN
-    property SVG_FECOMPOSITE_OPERATOR_XOR
-    property height
-    property in1
-    property in2
-    property k1
-    property k2
-    property k3
-    property k4
-    property operator
-    property result
-    property width
-    property x
-    property y
-svg element feConvolveMatrix
-    property SVG_EDGEMODE_DUPLICATE
-    property SVG_EDGEMODE_NONE
-    property SVG_EDGEMODE_UNKNOWN
-    property SVG_EDGEMODE_WRAP
-    property bias
-    property divisor
-    property edgeMode
-    property height
-    property in1
-    property kernelMatrix
-    property kernelUnitLengthX
-    property kernelUnitLengthY
-    property orderX
-    property orderY
-    property preserveAlpha
-    property result
-    property targetX
-    property targetY
-    property width
-    property x
-    property y
-svg element feDiffuseLighting
-    property diffuseConstant
-    property height
-    property in1
-    property kernelUnitLengthX
-    property kernelUnitLengthY
-    property result
-    property surfaceScale
-    property width
-    property x
-    property y
-svg element feDisplacementMap
-    property SVG_CHANNEL_A
-    property SVG_CHANNEL_B
-    property SVG_CHANNEL_G
-    property SVG_CHANNEL_R
-    property SVG_CHANNEL_UNKNOWN
-    property height
-    property in1
-    property in2
-    property result
-    property scale
-    property width
-    property x
-    property xChannelSelector
-    property y
-    property yChannelSelector
-svg element feDistantLight
-    property azimuth
-    property elevation
-svg element feDropShadow
-    property dx
-    property dy
-    property height
-    property in1
-    property result
-    property setStdDeviation
-    property stdDeviationX
-    property stdDeviationY
-    property width
-    property x
-    property y
-svg element feFlood
-    property height
-    property result
-    property width
-    property x
-    property y
-svg element feFuncA
-    property SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
-    property SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
-    property SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-    property SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
-    property SVG_FECOMPONENTTRANSFER_TYPE_TABLE
-    property SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN
-    property amplitude
-    property exponent
-    property intercept
-    property offset
-    property slope
-    property tableValues
-    property type
-svg element feFuncB
-    property SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
-    property SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
-    property SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-    property SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
-    property SVG_FECOMPONENTTRANSFER_TYPE_TABLE
-    property SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN
-    property amplitude
-    property exponent
-    property intercept
-    property offset
-    property slope
-    property tableValues
-    property type
-svg element feFuncG
-    property SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
-    property SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
-    property SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-    property SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
-    property SVG_FECOMPONENTTRANSFER_TYPE_TABLE
-    property SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN
-    property amplitude
-    property exponent
-    property intercept
-    property offset
-    property slope
-    property tableValues
-    property type
-svg element feFuncR
-    property SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
-    property SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
-    property SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-    property SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
-    property SVG_FECOMPONENTTRANSFER_TYPE_TABLE
-    property SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN
-    property amplitude
-    property exponent
-    property intercept
-    property offset
-    property slope
-    property tableValues
-    property type
-svg element feGaussianBlur
-    property height
-    property in1
-    property result
-    property setStdDeviation
-    property stdDeviationX
-    property stdDeviationY
-    property width
-    property x
-    property y
-svg element feImage
-    property height
-    property href
-    property preserveAspectRatio
-    property result
-    property width
-    property x
-    property y
-svg element feMerge
-    property height
-    property result
-    property width
-    property x
-    property y
-svg element feMergeNode
-    property in1
-svg element feMorphology
-    property SVG_MORPHOLOGY_OPERATOR_DILATE
-    property SVG_MORPHOLOGY_OPERATOR_ERODE
-    property SVG_MORPHOLOGY_OPERATOR_UNKNOWN
-    property height
-    property in1
-    property operator
-    property radiusX
-    property radiusY
-    property result
-    property width
-    property x
-    property y
-svg element feOffset
-    property dx
-    property dy
-    property height
-    property in1
-    property result
-    property width
-    property x
-    property y
-svg element fePointLight
-    property x
-    property y
-    property z
-svg element feSpecularLighting
-    property height
-    property in1
-    property kernelUnitLengthX
-    property kernelUnitLengthY
-    property result
-    property specularConstant
-    property specularExponent
-    property surfaceScale
-    property width
-    property x
-    property y
-svg element feSpotLight
-    property limitingConeAngle
-    property pointsAtX
-    property pointsAtY
-    property pointsAtZ
-    property specularExponent
-    property x
-    property y
-    property z
-svg element feTile
-    property height
-    property in1
-    property result
-    property width
-    property x
-    property y
-svg element feTurbulence
-    property SVG_STITCHTYPE_NOSTITCH
-    property SVG_STITCHTYPE_STITCH
-    property SVG_STITCHTYPE_UNKNOWN
-    property SVG_TURBULENCE_TYPE_FRACTALNOISE
-    property SVG_TURBULENCE_TYPE_TURBULENCE
-    property SVG_TURBULENCE_TYPE_UNKNOWN
-    property baseFrequencyX
-    property baseFrequencyY
-    property height
-    property numOctaves
-    property result
-    property seed
-    property stitchTiles
-    property type
-    property width
-    property x
-    property y
-svg element filter
-    property filterUnits
-    property height
-    property href
-    property primitiveUnits
-    property width
-    property x
-    property y
-svg element foreignObject
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property height
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-    property width
-    property x
-    property y
-svg element g
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element image
-    property decode
-    property decoding
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property height
-    property href
-    property nearestViewportElement
-    property preserveAspectRatio
-    property requiredExtensions
-    property systemLanguage
-    property transform
-    property width
-    property x
-    property y
-svg element line
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property requiredExtensions
-    property systemLanguage
-    property transform
-    property x1
-    property x2
-    property y1
-    property y2
-svg element linearGradient
-    property SVG_SPREADMETHOD_PAD
-    property SVG_SPREADMETHOD_REFLECT
-    property SVG_SPREADMETHOD_REPEAT
-    property SVG_SPREADMETHOD_UNKNOWN
-    property gradientTransform
-    property gradientUnits
-    property href
-    property spreadMethod
-    property x1
-    property x2
-    property y1
-    property y2
-svg element marker
-    property SVG_MARKERUNITS_STROKEWIDTH
-    property SVG_MARKERUNITS_UNKNOWN
-    property SVG_MARKERUNITS_USERSPACEONUSE
-    property SVG_MARKER_ORIENT_ANGLE
-    property SVG_MARKER_ORIENT_AUTO
-    property SVG_MARKER_ORIENT_UNKNOWN
-    property markerHeight
-    property markerUnits
-    property markerWidth
-    property orientAngle
-    property orientType
-    property preserveAspectRatio
-    property refX
-    property refY
-    property setOrientToAngle
-    property setOrientToAuto
-    property viewBox
-svg element mask
-    property height
-    property maskContentUnits
-    property maskUnits
-    property requiredExtensions
-    property systemLanguage
-    property width
-    property x
-    property y
-svg element metadata
-svg element mpath
-    property href
-svg element path
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element pattern
-    property height
-    property href
-    property patternContentUnits
-    property patternTransform
-    property patternUnits
-    property preserveAspectRatio
-    property requiredExtensions
-    property systemLanguage
-    property viewBox
-    property width
-    property x
-    property y
-svg element polygon
-    property animatedPoints
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property points
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element polyline
-    property animatedPoints
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property points
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element radialGradient
-    property SVG_SPREADMETHOD_PAD
-    property SVG_SPREADMETHOD_REFLECT
-    property SVG_SPREADMETHOD_REPEAT
-    property SVG_SPREADMETHOD_UNKNOWN
-    property cx
-    property cy
-    property fr
-    property fx
-    property fy
-    property gradientTransform
-    property gradientUnits
-    property href
-    property r
-    property spreadMethod
-svg element rect
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getPointAtLength
-    property getScreenCTM
-    property getTotalLength
-    property height
-    property isPointInFill
-    property isPointInStroke
-    property nearestViewportElement
-    property pathLength
-    property requiredExtensions
-    property rx
-    property ry
-    property systemLanguage
-    property transform
-    property width
-    property x
-    property y
-svg element script
-    property href
-    property type
-svg element set
-    property beginElement
-    property beginElementAt
-    property endElement
-    property endElementAt
-    property getCurrentTime
-    property getSimpleDuration
-    property getStartTime
-    property onbegin
-    property onend
-    property onrepeat
-    property requiredExtensions
-    property systemLanguage
-    property targetElement
-svg element stop
-    property offset
-svg element style
-    property disabled
-    property media
-    property sheet
-    property title
-    property type
-svg element svg
-    property SVG_ZOOMANDPAN_DISABLE
-    property SVG_ZOOMANDPAN_MAGNIFY
-    property SVG_ZOOMANDPAN_UNKNOWN
-    property animationsPaused
-    property checkEnclosure
-    property checkIntersection
-    property createSVGAngle
-    property createSVGLength
-    property createSVGMatrix
-    property createSVGNumber
-    property createSVGPoint
-    property createSVGRect
-    property createSVGTransform
-    property createSVGTransformFromMatrix
-    property currentScale
-    property currentTranslate
-    property deselectAll
-    property farthestViewportElement
-    property forceRedraw
-    property getBBox
-    property getCTM
-    property getCurrentTime
-    property getElementById
-    property getEnclosureList
-    property getIntersectionList
-    property getScreenCTM
-    property height
-    property nearestViewportElement
-    property pauseAnimations
-    property preserveAspectRatio
-    property requiredExtensions
-    property setCurrentTime
-    property suspendRedraw
-    property systemLanguage
-    property transform
-    property unpauseAnimations
-    property unsuspendRedraw
-    property unsuspendRedrawAll
-    property viewBox
-    property width
-    property x
-    property y
-    property zoomAndPan
-svg element switch
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-svg element symbol
-    property preserveAspectRatio
-    property viewBox
-svg element text
-    property LENGTHADJUST_SPACING
-    property LENGTHADJUST_SPACINGANDGLYPHS
-    property LENGTHADJUST_UNKNOWN
-    property dx
-    property dy
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getCharNumAtPosition
-    property getComputedTextLength
-    property getEndPositionOfChar
-    property getExtentOfChar
-    property getNumberOfChars
-    property getRotationOfChar
-    property getScreenCTM
-    property getStartPositionOfChar
-    property getSubStringLength
-    property lengthAdjust
-    property nearestViewportElement
-    property requiredExtensions
-    property rotate
-    property selectSubString
-    property systemLanguage
-    property textLength
-    property transform
-    property x
-    property y
-svg element textPath
-    property LENGTHADJUST_SPACING
-    property LENGTHADJUST_SPACINGANDGLYPHS
-    property LENGTHADJUST_UNKNOWN
-    property TEXTPATH_METHODTYPE_ALIGN
-    property TEXTPATH_METHODTYPE_STRETCH
-    property TEXTPATH_METHODTYPE_UNKNOWN
-    property TEXTPATH_SPACINGTYPE_AUTO
-    property TEXTPATH_SPACINGTYPE_EXACT
-    property TEXTPATH_SPACINGTYPE_UNKNOWN
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getCharNumAtPosition
-    property getComputedTextLength
-    property getEndPositionOfChar
-    property getExtentOfChar
-    property getNumberOfChars
-    property getRotationOfChar
-    property getScreenCTM
-    property getStartPositionOfChar
-    property getSubStringLength
-    property href
-    property lengthAdjust
-    property method
-    property nearestViewportElement
-    property requiredExtensions
-    property selectSubString
-    property spacing
-    property startOffset
-    property systemLanguage
-    property textLength
-    property transform
-svg element title
-svg element tspan
-    property LENGTHADJUST_SPACING
-    property LENGTHADJUST_SPACINGANDGLYPHS
-    property LENGTHADJUST_UNKNOWN
-    property dx
-    property dy
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getCharNumAtPosition
-    property getComputedTextLength
-    property getEndPositionOfChar
-    property getExtentOfChar
-    property getNumberOfChars
-    property getRotationOfChar
-    property getScreenCTM
-    property getStartPositionOfChar
-    property getSubStringLength
-    property lengthAdjust
-    property nearestViewportElement
-    property requiredExtensions
-    property rotate
-    property selectSubString
-    property systemLanguage
-    property textLength
-    property transform
-    property x
-    property y
-svg element use
-    property farthestViewportElement
-    property getBBox
-    property getCTM
-    property getScreenCTM
-    property height
-    property href
-    property nearestViewportElement
-    property requiredExtensions
-    property systemLanguage
-    property transform
-    property width
-    property x
-    property y
-svg element view
-    property SVG_ZOOMANDPAN_DISABLE
-    property SVG_ZOOMANDPAN_MAGNIFY
-    property SVG_ZOOMANDPAN_UNKNOWN
-    property preserveAspectRatio
-    property viewBox
-    property zoomAndPan
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/global-interface-listing-expected.txt
deleted file mode 100644
index 78ddb2f..0000000
--- a/third_party/blink/web_tests/virtual/anonymous-iframe/webexposed/global-interface-listing-expected.txt
+++ /dev/null
@@ -1,11662 +0,0 @@
-This test documents all interface attributes and methods on the global window object and element instances.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-[INTERFACES]
-interface AbortController
-    attribute @@toStringTag
-    getter signal
-    method abort
-    method constructor
-interface AbortSignal : EventTarget
-    static method abort
-    attribute @@toStringTag
-    getter aborted
-    getter onabort
-    method constructor
-    setter onabort
-interface AbsoluteOrientationSensor : OrientationSensor
-    attribute @@toStringTag
-    method constructor
-interface AbstractRange
-    attribute @@toStringTag
-    getter collapsed
-    getter endContainer
-    getter endOffset
-    getter startContainer
-    getter startOffset
-    method constructor
-interface Accelerometer : Sensor
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-interface AccessibleNode : EventTarget
-    attribute @@toStringTag
-    getter activeDescendant
-    getter atomic
-    getter autocomplete
-    getter busy
-    getter checked
-    getter childNodes
-    getter colCount
-    getter colIndex
-    getter colSpan
-    getter controls
-    getter current
-    getter describedBy
-    getter details
-    getter disabled
-    getter errorMessage
-    getter expanded
-    getter flowTo
-    getter hasPopUp
-    getter hidden
-    getter invalid
-    getter keyShortcuts
-    getter label
-    getter labeledBy
-    getter level
-    getter live
-    getter modal
-    getter multiline
-    getter multiselectable
-    getter onaccessibleclick
-    getter onaccessiblecontextmenu
-    getter onaccessibledecrement
-    getter onaccessiblefocus
-    getter onaccessibleincrement
-    getter onaccessiblescrollintoview
-    getter orientation
-    getter owns
-    getter placeholder
-    getter posInSet
-    getter pressed
-    getter readOnly
-    getter relevant
-    getter required
-    getter role
-    getter roleDescription
-    getter rowCount
-    getter rowIndex
-    getter rowSpan
-    getter selected
-    getter setSize
-    getter sort
-    getter valueMax
-    getter valueMin
-    getter valueNow
-    getter valueText
-    method appendChild
-    method constructor
-    method removeChild
-    setter activeDescendant
-    setter atomic
-    setter autocomplete
-    setter busy
-    setter checked
-    setter colCount
-    setter colIndex
-    setter colSpan
-    setter controls
-    setter current
-    setter describedBy
-    setter details
-    setter disabled
-    setter errorMessage
-    setter expanded
-    setter flowTo
-    setter hasPopUp
-    setter hidden
-    setter invalid
-    setter keyShortcuts
-    setter label
-    setter labeledBy
-    setter level
-    setter live
-    setter modal
-    setter multiline
-    setter multiselectable
-    setter onaccessibleclick
-    setter onaccessiblecontextmenu
-    setter onaccessibledecrement
-    setter onaccessiblefocus
-    setter onaccessibleincrement
-    setter onaccessiblescrollintoview
-    setter orientation
-    setter owns
-    setter placeholder
-    setter posInSet
-    setter pressed
-    setter readOnly
-    setter relevant
-    setter required
-    setter role
-    setter roleDescription
-    setter rowCount
-    setter rowIndex
-    setter rowSpan
-    setter selected
-    setter setSize
-    setter sort
-    setter valueMax
-    setter valueMin
-    setter valueNow
-    setter valueText
-interface AccessibleNodeList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method add
-    method constructor
-    method item
-    method remove
-    setter length
-interface AmbientLightSensor : Sensor
-    attribute @@toStringTag
-    getter illuminance
-    method constructor
-interface AnalyserNode : AudioNode
-    attribute @@toStringTag
-    getter fftSize
-    getter frequencyBinCount
-    getter maxDecibels
-    getter minDecibels
-    getter smoothingTimeConstant
-    method constructor
-    method getByteFrequencyData
-    method getByteTimeDomainData
-    method getFloatFrequencyData
-    method getFloatTimeDomainData
-    setter fftSize
-    setter maxDecibels
-    setter minDecibels
-    setter smoothingTimeConstant
-interface Animation : EventTarget
-    attribute @@toStringTag
-    getter currentTime
-    getter effect
-    getter finished
-    getter id
-    getter oncancel
-    getter onfinish
-    getter onremove
-    getter pending
-    getter playState
-    getter playbackRate
-    getter ready
-    getter replaceState
-    getter startTime
-    getter timeline
-    method cancel
-    method commitStyles
-    method constructor
-    method finish
-    method pause
-    method persist
-    method play
-    method reverse
-    method updatePlaybackRate
-    setter currentTime
-    setter effect
-    setter id
-    setter oncancel
-    setter onfinish
-    setter onremove
-    setter playbackRate
-    setter startTime
-    setter timeline
-interface AnimationEffect
-    attribute @@toStringTag
-    method constructor
-    method getComputedTiming
-    method getTiming
-    method updateTiming
-interface AnimationEvent : Event
-    attribute @@toStringTag
-    getter animationName
-    getter elapsedTime
-    getter pseudoElement
-    method constructor
-interface AnimationPlaybackEvent : Event
-    attribute @@toStringTag
-    getter currentTime
-    getter timelineTime
-    method constructor
-interface AnimationTimeline
-    attribute @@toStringTag
-    getter currentTime
-    getter duration
-    getter phase
-    method constructor
-interface AppHistory : EventTarget
-    attribute @@toStringTag
-    getter canGoBack
-    getter canGoForward
-    getter current
-    getter onnavigate
-    getter onnavigateerror
-    getter onnavigatesuccess
-    method back
-    method constructor
-    method entries
-    method forward
-    method goTo
-    method navigate
-    setter onnavigate
-    setter onnavigateerror
-    setter onnavigatesuccess
-interface AppHistoryDestination
-    attribute @@toStringTag
-    getter sameDocument
-    getter url
-    method constructor
-    method getState
-interface AppHistoryEntry : EventTarget
-    attribute @@toStringTag
-    getter id
-    getter index
-    getter key
-    getter sameDocument
-    getter url
-    method constructor
-    method getState
-interface AppHistoryNavigateEvent : Event
-    attribute @@toStringTag
-    getter canRespond
-    getter destination
-    getter formData
-    getter hashChange
-    getter info
-    getter userInitiated
-    method constructor
-    method respondWith
-interface Attr : Node
-    attribute @@toStringTag
-    getter localName
-    getter name
-    getter namespaceURI
-    getter ownerElement
-    getter prefix
-    getter specified
-    getter value
-    method constructor
-    setter value
-interface AttributionReporting
-    attribute @@toStringTag
-    method constructor
-    method registerAttributionSource
-interface Audio
-    attribute @@toStringTag
-    method constructor
-interface AudioBuffer
-    attribute @@toStringTag
-    getter duration
-    getter length
-    getter numberOfChannels
-    getter sampleRate
-    method constructor
-    method copyFromChannel
-    method copyToChannel
-    method getChannelData
-interface AudioBufferSourceNode : AudioScheduledSourceNode
-    attribute @@toStringTag
-    getter buffer
-    getter detune
-    getter loop
-    getter loopEnd
-    getter loopStart
-    getter playbackRate
-    method constructor
-    method start
-    setter buffer
-    setter loop
-    setter loopEnd
-    setter loopStart
-interface AudioContext : BaseAudioContext
-    attribute @@toStringTag
-    getter baseLatency
-    method close
-    method constructor
-    method createMediaElementSource
-    method createMediaStreamDestination
-    method createMediaStreamSource
-    method getOutputTimestamp
-    method resume
-    method suspend
-interface AudioData
-    attribute @@toStringTag
-    getter buffer
-    getter timestamp
-    method clone
-    method close
-    method constructor
-interface AudioDecoder
-    static method isConfigSupported
-    attribute @@toStringTag
-    getter decodeQueueSize
-    getter state
-    method close
-    method configure
-    method constructor
-    method decode
-    method flush
-    method reset
-interface AudioDestinationNode : AudioNode
-    attribute @@toStringTag
-    getter maxChannelCount
-    method constructor
-interface AudioEncoder
-    static method isConfigSupported
-    attribute @@toStringTag
-    getter encodeQueueSize
-    getter state
-    method close
-    method configure
-    method constructor
-    method encode
-    method flush
-    method reset
-interface AudioListener
-    attribute @@toStringTag
-    getter forwardX
-    getter forwardY
-    getter forwardZ
-    getter positionX
-    getter positionY
-    getter positionZ
-    getter upX
-    getter upY
-    getter upZ
-    method constructor
-    method setOrientation
-    method setPosition
-interface AudioNode : EventTarget
-    attribute @@toStringTag
-    getter channelCount
-    getter channelCountMode
-    getter channelInterpretation
-    getter context
-    getter numberOfInputs
-    getter numberOfOutputs
-    method connect
-    method constructor
-    method disconnect
-    setter channelCount
-    setter channelCountMode
-    setter channelInterpretation
-interface AudioParam
-    attribute @@toStringTag
-    getter automationRate
-    getter defaultValue
-    getter maxValue
-    getter minValue
-    getter value
-    method cancelAndHoldAtTime
-    method cancelScheduledValues
-    method constructor
-    method exponentialRampToValueAtTime
-    method linearRampToValueAtTime
-    method setTargetAtTime
-    method setValueAtTime
-    method setValueCurveAtTime
-    setter automationRate
-    setter value
-interface AudioParamMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface AudioProcessingEvent : Event
-    attribute @@toStringTag
-    getter inputBuffer
-    getter outputBuffer
-    getter playbackTime
-    method constructor
-interface AudioScheduledSourceNode : AudioNode
-    attribute @@toStringTag
-    getter onended
-    method constructor
-    method start
-    method stop
-    setter onended
-interface AudioTrack
-    attribute @@toStringTag
-    getter enabled
-    getter id
-    getter kind
-    getter label
-    getter language
-    getter sourceBuffer
-    method constructor
-    setter enabled
-interface AudioTrackList : EventTarget
-    attribute @@toStringTag
-    getter length
-    getter onaddtrack
-    getter onchange
-    getter onremovetrack
-    method @@iterator
-    method constructor
-    method getTrackById
-    setter onaddtrack
-    setter onchange
-    setter onremovetrack
-interface AudioWorklet : Worklet
-    attribute @@toStringTag
-    method constructor
-interface AudioWorkletNode : AudioNode
-    attribute @@toStringTag
-    getter onprocessorerror
-    getter parameters
-    getter port
-    method constructor
-    setter onprocessorerror
-interface AuthenticatorAssertionResponse : AuthenticatorResponse
-    attribute @@toStringTag
-    getter authenticatorData
-    getter signature
-    getter userHandle
-    method constructor
-interface AuthenticatorAttestationResponse : AuthenticatorResponse
-    attribute @@toStringTag
-    getter attestationObject
-    method constructor
-    method getAuthenticatorData
-    method getPublicKey
-    method getPublicKeyAlgorithm
-    method getTransports
-interface AuthenticatorResponse
-    attribute @@toStringTag
-    getter clientDataJSON
-    method constructor
-interface BackgroundFetchManager
-    attribute @@toStringTag
-    method constructor
-    method fetch
-    method get
-    method getIds
-interface BackgroundFetchRecord
-    attribute @@toStringTag
-    getter request
-    getter responseReady
-    method constructor
-interface BackgroundFetchRegistration : EventTarget
-    attribute @@toStringTag
-    getter downloadTotal
-    getter downloaded
-    getter failureReason
-    getter id
-    getter onprogress
-    getter recordsAvailable
-    getter result
-    getter uploadTotal
-    getter uploaded
-    method abort
-    method constructor
-    method match
-    method matchAll
-    setter onprogress
-interface BarProp
-    attribute @@toStringTag
-    getter visible
-    method constructor
-interface BaseAudioContext : EventTarget
-    attribute @@toStringTag
-    getter audioWorklet
-    getter currentTime
-    getter destination
-    getter listener
-    getter onstatechange
-    getter sampleRate
-    getter state
-    method constructor
-    method createAnalyser
-    method createBiquadFilter
-    method createBuffer
-    method createBufferSource
-    method createChannelMerger
-    method createChannelSplitter
-    method createConstantSource
-    method createConvolver
-    method createDelay
-    method createDynamicsCompressor
-    method createGain
-    method createIIRFilter
-    method createOscillator
-    method createPanner
-    method createPeriodicWave
-    method createScriptProcessor
-    method createStereoPanner
-    method createWaveShaper
-    method decodeAudioData
-    setter onstatechange
-interface BatteryManager : EventTarget
-    attribute @@toStringTag
-    getter charging
-    getter chargingTime
-    getter dischargingTime
-    getter level
-    getter onchargingchange
-    getter onchargingtimechange
-    getter ondischargingtimechange
-    getter onlevelchange
-    method constructor
-    setter onchargingchange
-    setter onchargingtimechange
-    setter ondischargingtimechange
-    setter onlevelchange
-interface BeforeCreatePolicyEvent : Event
-    attribute @@toStringTag
-    getter policyName
-    method constructor
-    setter policyName
-interface BeforeInstallPromptEvent : Event
-    attribute @@toStringTag
-    getter platforms
-    getter userChoice
-    method constructor
-    method prompt
-interface BeforeUnloadEvent : Event
-    attribute @@toStringTag
-    getter returnValue
-    method constructor
-    setter returnValue
-interface BidirectionalStream
-    attribute @@toStringTag
-    getter readable
-    getter readingAborted
-    getter writable
-    getter writingAborted
-    method abortReading
-    method abortWriting
-    method constructor
-interface BiquadFilterNode : AudioNode
-    attribute @@toStringTag
-    getter Q
-    getter detune
-    getter frequency
-    getter gain
-    getter type
-    method constructor
-    method getFrequencyResponse
-    setter type
-interface Blob
-    attribute @@toStringTag
-    getter size
-    getter type
-    method arrayBuffer
-    method constructor
-    method slice
-    method stream
-    method text
-interface BlobEvent : Event
-    attribute @@toStringTag
-    getter data
-    getter timecode
-    method constructor
-interface BluetoothAdvertisingEvent : Event
-    attribute @@toStringTag
-    getter appearance
-    getter device
-    getter manufacturerData
-    getter name
-    getter rssi
-    getter serviceData
-    getter txPower
-    getter uuids
-    method constructor
-interface BluetoothLEScan
-    attribute @@toStringTag
-    getter acceptAllAdvertisements
-    getter active
-    getter filters
-    getter keepRepeatedDevices
-    method constructor
-    method stop
-interface BluetoothManufacturerDataMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface BluetoothServiceDataMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface BroadcastChannel : EventTarget
-    attribute @@toStringTag
-    getter name
-    getter onmessage
-    getter onmessageerror
-    method close
-    method constructor
-    method postMessage
-    setter onmessage
-    setter onmessageerror
-interface ByteLengthQueuingStrategy
-    attribute @@toStringTag
-    getter highWaterMark
-    getter size
-    method constructor
-interface CDATASection : Text
-    attribute @@toStringTag
-    method constructor
-interface CSSAnimation : Animation
-    attribute @@toStringTag
-    getter animationName
-    method constructor
-interface CSSColorValue
-    attribute @@toStringTag
-    method constructor
-    method toHSL
-    method toRGB
-interface CSSConditionRule : CSSGroupingRule
-    attribute @@toStringTag
-    getter conditionText
-    method constructor
-interface CSSCounterStyleRule : CSSRule
-    attribute @@toStringTag
-    getter additiveSymbols
-    getter fallback
-    getter name
-    getter negative
-    getter pad
-    getter prefix
-    getter range
-    getter speakAs
-    getter suffix
-    getter symbols
-    getter system
-    method constructor
-    setter additiveSymbols
-    setter fallback
-    setter name
-    setter negative
-    setter pad
-    setter prefix
-    setter range
-    setter speakAs
-    setter suffix
-    setter symbols
-    setter system
-interface CSSFontFaceRule : CSSRule
-    attribute @@toStringTag
-    getter style
-    method constructor
-interface CSSGroupingRule : CSSRule
-    attribute @@toStringTag
-    getter cssRules
-    method constructor
-    method deleteRule
-    method insertRule
-interface CSSHSL : CSSColorValue
-    attribute @@toStringTag
-    getter alpha
-    getter h
-    getter l
-    getter s
-    method constructor
-    setter alpha
-    setter h
-    setter l
-    setter s
-interface CSSImageValue : CSSStyleValue
-    attribute @@toStringTag
-    method constructor
-interface CSSImportRule : CSSRule
-    attribute @@toStringTag
-    getter href
-    getter media
-    getter styleSheet
-    method constructor
-    setter media
-interface CSSKeyframeRule : CSSRule
-    attribute @@toStringTag
-    getter keyText
-    getter style
-    method constructor
-    setter keyText
-    setter style
-interface CSSKeyframesRule : CSSRule
-    attribute @@toStringTag
-    getter cssRules
-    getter name
-    method @@iterator
-    method appendRule
-    method constructor
-    method deleteRule
-    method findRule
-    setter name
-interface CSSKeywordValue : CSSStyleValue
-    attribute @@toStringTag
-    getter value
-    method constructor
-    setter value
-interface CSSMathInvert : CSSMathValue
-    attribute @@toStringTag
-    getter value
-    method constructor
-interface CSSMathMax : CSSMathValue
-    attribute @@toStringTag
-    getter values
-    method constructor
-interface CSSMathMin : CSSMathValue
-    attribute @@toStringTag
-    getter values
-    method constructor
-interface CSSMathNegate : CSSMathValue
-    attribute @@toStringTag
-    getter value
-    method constructor
-interface CSSMathProduct : CSSMathValue
-    attribute @@toStringTag
-    getter values
-    method constructor
-interface CSSMathSum : CSSMathValue
-    attribute @@toStringTag
-    getter values
-    method constructor
-interface CSSMathValue : CSSNumericValue
-    attribute @@toStringTag
-    getter operator
-    method constructor
-interface CSSMatrixComponent : CSSTransformComponent
-    attribute @@toStringTag
-    getter matrix
-    method constructor
-    setter matrix
-interface CSSMediaRule : CSSConditionRule
-    attribute @@toStringTag
-    getter media
-    method constructor
-    setter media
-interface CSSNamespaceRule : CSSRule
-    attribute @@toStringTag
-    getter namespaceURI
-    getter prefix
-    method constructor
-interface CSSNumericArray
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method keys
-    method values
-interface CSSNumericValue : CSSStyleValue
-    attribute @@toStringTag
-    method add
-    method constructor
-    method div
-    method equals
-    method max
-    method min
-    method mul
-    method sub
-    method to
-    method toSum
-    method type
-interface CSSPageRule : CSSRule
-    attribute @@toStringTag
-    getter selectorText
-    getter style
-    method constructor
-    setter selectorText
-    setter style
-interface CSSPerspective : CSSTransformComponent
-    attribute @@toStringTag
-    getter length
-    method constructor
-    setter length
-interface CSSPositionValue : CSSStyleValue
-    attribute @@toStringTag
-    getter x
-    getter y
-    method constructor
-    setter x
-    setter y
-interface CSSPropertyRule : CSSRule
-    attribute @@toStringTag
-    getter inherits
-    getter initialValue
-    getter name
-    getter syntax
-    method constructor
-interface CSSRGB : CSSColorValue
-    attribute @@toStringTag
-    getter alpha
-    getter b
-    getter g
-    getter r
-    method constructor
-    setter alpha
-    setter b
-    setter g
-    setter r
-interface CSSRotate : CSSTransformComponent
-    attribute @@toStringTag
-    getter angle
-    getter x
-    getter y
-    getter z
-    method constructor
-    setter angle
-    setter x
-    setter y
-    setter z
-interface CSSRule
-    attribute @@toStringTag
-    attribute CHARSET_RULE
-    attribute COUNTER_STYLE_RULE
-    attribute FONT_FACE_RULE
-    attribute IMPORT_RULE
-    attribute KEYFRAMES_RULE
-    attribute KEYFRAME_RULE
-    attribute MEDIA_RULE
-    attribute NAMESPACE_RULE
-    attribute PAGE_RULE
-    attribute STYLE_RULE
-    attribute SUPPORTS_RULE
-    getter cssText
-    getter parentRule
-    getter parentStyleSheet
-    getter type
-    method constructor
-    setter cssText
-interface CSSRuleList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-interface CSSScale : CSSTransformComponent
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-    setter x
-    setter y
-    setter z
-interface CSSScrollTimelineRule : CSSRule
-    attribute @@toStringTag
-    getter end
-    getter name
-    getter orientation
-    getter source
-    getter start
-    getter timeRange
-    method constructor
-interface CSSSkew : CSSTransformComponent
-    attribute @@toStringTag
-    getter ax
-    getter ay
-    method constructor
-    setter ax
-    setter ay
-interface CSSSkewX : CSSTransformComponent
-    attribute @@toStringTag
-    getter ax
-    method constructor
-    setter ax
-interface CSSSkewY : CSSTransformComponent
-    attribute @@toStringTag
-    getter ay
-    method constructor
-    setter ay
-interface CSSStyleDeclaration
-    attribute @@toStringTag
-    getter cssFloat
-    getter cssText
-    getter length
-    getter parentRule
-    method @@iterator
-    method constructor
-    method getPropertyPriority
-    method getPropertyValue
-    method item
-    method removeProperty
-    method setProperty
-    setter cssFloat
-    setter cssText
-interface CSSStyleRule : CSSRule
-    attribute @@toStringTag
-    getter selectorText
-    getter style
-    getter styleMap
-    method constructor
-    setter selectorText
-    setter style
-interface CSSStyleSheet : StyleSheet
-    attribute @@toStringTag
-    getter cssRules
-    getter ownerRule
-    getter rules
-    method addRule
-    method constructor
-    method deleteRule
-    method insertRule
-    method removeRule
-    method replace
-    method replaceSync
-interface CSSStyleValue
-    static method parse
-    static method parseAll
-    attribute @@toStringTag
-    method constructor
-    method toString
-interface CSSSupportsRule : CSSConditionRule
-    attribute @@toStringTag
-    method constructor
-interface CSSTransformComponent
-    attribute @@toStringTag
-    getter is2D
-    method constructor
-    method toMatrix
-    method toString
-    setter is2D
-interface CSSTransformValue : CSSStyleValue
-    attribute @@toStringTag
-    getter is2D
-    getter length
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method keys
-    method toMatrix
-    method values
-interface CSSTransition : Animation
-    attribute @@toStringTag
-    getter transitionProperty
-    method constructor
-interface CSSTranslate : CSSTransformComponent
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-    setter x
-    setter y
-    setter z
-interface CSSUnitValue : CSSNumericValue
-    attribute @@toStringTag
-    getter unit
-    getter value
-    method constructor
-    setter value
-interface CSSUnparsedValue : CSSStyleValue
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method keys
-    method values
-interface CSSVariableReferenceValue
-    attribute @@toStringTag
-    getter fallback
-    getter variable
-    method constructor
-    setter variable
-interface Cache
-    attribute @@toStringTag
-    method add
-    method addAll
-    method constructor
-    method delete
-    method keys
-    method match
-    method matchAll
-    method put
-interface CacheStorage
-    attribute @@toStringTag
-    method constructor
-    method delete
-    method has
-    method keys
-    method match
-    method open
-interface CanvasCaptureMediaStreamTrack : MediaStreamTrack
-    attribute @@toStringTag
-    getter canvas
-    method constructor
-    method requestFrame
-interface CanvasFilter
-    attribute @@toStringTag
-    method constructor
-interface CanvasFormattedText
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method appendRun
-    method constructor
-    method deleteRun
-    method getRun
-    method insertRun
-    method setRun
-interface CanvasFormattedTextRun
-    attribute @@toStringTag
-    getter text
-    method constructor
-    setter text
-interface CanvasGradient
-    attribute @@toStringTag
-    method addColorStop
-    method constructor
-interface CanvasPattern
-    attribute @@toStringTag
-    method constructor
-    method setTransform
-interface CanvasRenderingContext2D
-    attribute @@toStringTag
-    getter canvas
-    getter direction
-    getter fillStyle
-    getter filter
-    getter font
-    getter fontKerning
-    getter fontStretch
-    getter fontVariantCaps
-    getter globalAlpha
-    getter globalCompositeOperation
-    getter imageSmoothingEnabled
-    getter imageSmoothingQuality
-    getter lineCap
-    getter lineDashOffset
-    getter lineJoin
-    getter lineWidth
-    getter miterLimit
-    getter shadowBlur
-    getter shadowColor
-    getter shadowOffsetX
-    getter shadowOffsetY
-    getter strokeStyle
-    getter textAlign
-    getter textBaseline
-    getter textLetterSpacing
-    getter textRendering
-    getter textWordSpacing
-    method addHitRegion
-    method arc
-    method arcTo
-    method beginPath
-    method bezierCurveTo
-    method clearHitRegions
-    method clearRect
-    method clip
-    method closePath
-    method constructor
-    method createConicGradient
-    method createImageData
-    method createLinearGradient
-    method createPattern
-    method createRadialGradient
-    method drawFocusIfNeeded
-    method drawImage
-    method ellipse
-    method fill
-    method fillFormattedText
-    method fillRect
-    method fillText
-    method getContextAttributes
-    method getImageData
-    method getLineDash
-    method getTransform
-    method isContextLost
-    method isPointInPath
-    method isPointInStroke
-    method lineTo
-    method measureText
-    method moveTo
-    method perspective
-    method putImageData
-    method quadraticCurveTo
-    method rect
-    method removeHitRegion
-    method reset
-    method resetTransform
-    method restore
-    method rotate
-    method rotate3d
-    method rotateAxis
-    method roundRect
-    method save
-    method scale
-    method scrollPathIntoView
-    method setLineDash
-    method setTransform
-    method stroke
-    method strokeRect
-    method strokeText
-    method transform
-    method translate
-    setter direction
-    setter fillStyle
-    setter filter
-    setter font
-    setter fontKerning
-    setter fontStretch
-    setter fontVariantCaps
-    setter globalAlpha
-    setter globalCompositeOperation
-    setter imageSmoothingEnabled
-    setter imageSmoothingQuality
-    setter lineCap
-    setter lineDashOffset
-    setter lineJoin
-    setter lineWidth
-    setter miterLimit
-    setter shadowBlur
-    setter shadowColor
-    setter shadowOffsetX
-    setter shadowOffsetY
-    setter strokeStyle
-    setter textAlign
-    setter textBaseline
-    setter textLetterSpacing
-    setter textRendering
-    setter textWordSpacing
-interface CaptureHandleChangeEvent : Event
-    attribute @@toStringTag
-    method captureHandle
-    method constructor
-interface ChannelMergerNode : AudioNode
-    attribute @@toStringTag
-    method constructor
-interface ChannelSplitterNode : AudioNode
-    attribute @@toStringTag
-    method constructor
-interface CharacterData : Node
-    attribute @@toStringTag
-    attribute @@unscopables
-    getter data
-    getter length
-    getter nextElementSibling
-    getter previousElementSibling
-    method after
-    method appendData
-    method before
-    method constructor
-    method deleteData
-    method insertData
-    method remove
-    method replaceData
-    method replaceWith
-    method substringData
-    setter data
-interface Clipboard : EventTarget
-    attribute @@toStringTag
-    method constructor
-    method read
-    method readText
-    method write
-    method writeText
-interface ClipboardEvent : Event
-    attribute @@toStringTag
-    getter clipboardData
-    method constructor
-interface ClipboardItem
-    attribute @@toStringTag
-    getter types
-    method constructor
-    method getType
-interface CloseEvent : Event
-    attribute @@toStringTag
-    getter code
-    getter reason
-    getter wasClean
-    method constructor
-interface ColorSelectEvent : PointerEvent
-    attribute @@toStringTag
-    getter value
-    method constructor
-interface Comment : CharacterData
-    attribute @@toStringTag
-    method constructor
-interface CompositionEvent : UIEvent
-    attribute @@toStringTag
-    getter data
-    method constructor
-    method initCompositionEvent
-interface CompressionStream
-    attribute @@toStringTag
-    getter readable
-    getter writable
-    method constructor
-interface ComputePressureObserver
-    attribute @@toStringTag
-    method constructor
-    method observe
-    method stop
-interface ComputedAccessibleNode
-    attribute @@toStringTag
-    getter atomic
-    getter autocomplete
-    getter busy
-    getter checked
-    getter colCount
-    getter colIndex
-    getter colSpan
-    getter disabled
-    getter expanded
-    getter firstChild
-    getter keyShortcuts
-    getter lastChild
-    getter level
-    getter modal
-    getter multiline
-    getter multiselectable
-    getter name
-    getter nextSibling
-    getter parent
-    getter placeholder
-    getter posInSet
-    getter previousSibling
-    getter readOnly
-    getter required
-    getter role
-    getter roleDescription
-    getter rowCount
-    getter rowIndex
-    getter rowSpan
-    getter selected
-    getter setSize
-    getter valueMax
-    getter valueMin
-    getter valueNow
-    getter valueText
-    method constructor
-    method ensureUpToDate
-interface ConstantSourceNode : AudioScheduledSourceNode
-    attribute @@toStringTag
-    getter offset
-    method constructor
-interface ContactAddress : PaymentAddress
-    attribute @@toStringTag
-    method constructor
-interface ContactsManager
-    attribute @@toStringTag
-    method constructor
-    method getProperties
-    method select
-interface ContentIndex
-    attribute @@toStringTag
-    method add
-    method constructor
-    method delete
-    method getAll
-interface ConvolverNode : AudioNode
-    attribute @@toStringTag
-    getter buffer
-    getter normalize
-    method constructor
-    setter buffer
-    setter normalize
-interface CookieChangeEvent : Event
-    attribute @@toStringTag
-    getter changed
-    getter deleted
-    method constructor
-interface CookieStore : EventTarget
-    attribute @@toStringTag
-    getter onchange
-    method constructor
-    method delete
-    method get
-    method getAll
-    method set
-    setter onchange
-interface CookieStoreManager
-    attribute @@toStringTag
-    method constructor
-    method getSubscriptions
-    method subscribe
-    method unsubscribe
-interface CountQueuingStrategy
-    attribute @@toStringTag
-    getter highWaterMark
-    getter size
-    method constructor
-interface Credential
-    attribute @@toStringTag
-    getter id
-    getter type
-    method constructor
-interface CredentialsContainer
-    attribute @@toStringTag
-    method constructor
-    method create
-    method get
-    method preventSilentAccess
-    method store
-interface Crypto
-    attribute @@toStringTag
-    getter subtle
-    method constructor
-    method getRandomValues
-    method randomUUID
-interface CryptoKey
-    attribute @@toStringTag
-    getter algorithm
-    getter extractable
-    getter type
-    getter usages
-    method constructor
-interface CustomElementRegistry
-    attribute @@toStringTag
-    method constructor
-    method define
-    method get
-    method upgrade
-    method whenDefined
-interface CustomEvent : Event
-    attribute @@toStringTag
-    getter detail
-    method constructor
-    method initCustomEvent
-interface CustomStateSet
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method add
-    method clear
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method has
-    method keys
-    method values
-interface DOMError
-    attribute @@toStringTag
-    getter message
-    getter name
-    method constructor
-interface DOMException
-    attribute @@toStringTag
-    attribute ABORT_ERR
-    attribute DATA_CLONE_ERR
-    attribute DOMSTRING_SIZE_ERR
-    attribute HIERARCHY_REQUEST_ERR
-    attribute INDEX_SIZE_ERR
-    attribute INUSE_ATTRIBUTE_ERR
-    attribute INVALID_ACCESS_ERR
-    attribute INVALID_CHARACTER_ERR
-    attribute INVALID_MODIFICATION_ERR
-    attribute INVALID_NODE_TYPE_ERR
-    attribute INVALID_STATE_ERR
-    attribute NAMESPACE_ERR
-    attribute NETWORK_ERR
-    attribute NOT_FOUND_ERR
-    attribute NOT_SUPPORTED_ERR
-    attribute NO_DATA_ALLOWED_ERR
-    attribute NO_MODIFICATION_ALLOWED_ERR
-    attribute QUOTA_EXCEEDED_ERR
-    attribute SECURITY_ERR
-    attribute SYNTAX_ERR
-    attribute TIMEOUT_ERR
-    attribute TYPE_MISMATCH_ERR
-    attribute URL_MISMATCH_ERR
-    attribute VALIDATION_ERR
-    attribute WRONG_DOCUMENT_ERR
-    getter code
-    getter message
-    getter name
-    method constructor
-interface DOMImplementation
-    attribute @@toStringTag
-    method constructor
-    method createDocument
-    method createDocumentType
-    method createHTMLDocument
-    method hasFeature
-interface DOMMatrix : DOMMatrixReadOnly
-    attribute @@toStringTag
-    getter a
-    getter b
-    getter c
-    getter d
-    getter e
-    getter f
-    getter m11
-    getter m12
-    getter m13
-    getter m14
-    getter m21
-    getter m22
-    getter m23
-    getter m24
-    getter m31
-    getter m32
-    getter m33
-    getter m34
-    getter m41
-    getter m42
-    getter m43
-    getter m44
-    method constructor
-    method invertSelf
-    method multiplySelf
-    method preMultiplySelf
-    method rotateAxisAngleSelf
-    method rotateFromVectorSelf
-    method rotateSelf
-    method scale3dSelf
-    method scaleSelf
-    method setMatrixValue
-    method skewXSelf
-    method skewYSelf
-    method translateSelf
-    setter a
-    setter b
-    setter c
-    setter d
-    setter e
-    setter f
-    setter m11
-    setter m12
-    setter m13
-    setter m14
-    setter m21
-    setter m22
-    setter m23
-    setter m24
-    setter m31
-    setter m32
-    setter m33
-    setter m34
-    setter m41
-    setter m42
-    setter m43
-    setter m44
-interface DOMMatrixReadOnly
-    static method fromFloat32Array
-    static method fromFloat64Array
-    static method fromMatrix
-    attribute @@toStringTag
-    getter a
-    getter b
-    getter c
-    getter d
-    getter e
-    getter f
-    getter is2D
-    getter isIdentity
-    getter m11
-    getter m12
-    getter m13
-    getter m14
-    getter m21
-    getter m22
-    getter m23
-    getter m24
-    getter m31
-    getter m32
-    getter m33
-    getter m34
-    getter m41
-    getter m42
-    getter m43
-    getter m44
-    method constructor
-    method flipX
-    method flipY
-    method inverse
-    method multiply
-    method rotate
-    method rotateAxisAngle
-    method rotateFromVector
-    method scale
-    method scale3d
-    method scaleNonUniform
-    method skewX
-    method skewY
-    method toFloat32Array
-    method toFloat64Array
-    method toJSON
-    method toString
-    method transformPoint
-    method translate
-interface DOMParser
-    attribute @@toStringTag
-    method constructor
-    method parseFromString
-interface DOMPoint : DOMPointReadOnly
-    attribute @@toStringTag
-    getter w
-    getter x
-    getter y
-    getter z
-    method constructor
-    setter w
-    setter x
-    setter y
-    setter z
-interface DOMPointReadOnly
-    static method fromPoint
-    attribute @@toStringTag
-    getter w
-    getter x
-    getter y
-    getter z
-    method constructor
-    method matrixTransform
-    method toJSON
-interface DOMQuad
-    static method fromQuad
-    static method fromRect
-    attribute @@toStringTag
-    getter p1
-    getter p2
-    getter p3
-    getter p4
-    method constructor
-    method getBounds
-    method toJSON
-interface DOMRect : DOMRectReadOnly
-    attribute @@toStringTag
-    getter height
-    getter width
-    getter x
-    getter y
-    method constructor
-    setter height
-    setter width
-    setter x
-    setter y
-interface DOMRectList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-interface DOMRectReadOnly
-    static method fromRect
-    attribute @@toStringTag
-    getter bottom
-    getter height
-    getter left
-    getter right
-    getter top
-    getter width
-    getter x
-    getter y
-    method constructor
-    method toJSON
-interface DOMStringList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method contains
-    method item
-interface DOMStringMap
-    attribute @@toStringTag
-    method constructor
-interface DOMTokenList
-    attribute @@toStringTag
-    getter length
-    getter value
-    method @@iterator
-    method add
-    method constructor
-    method contains
-    method entries
-    method forEach
-    method item
-    method keys
-    method remove
-    method replace
-    method supports
-    method toString
-    method toggle
-    method values
-    setter value
-interface DataTransfer
-    attribute @@toStringTag
-    getter dropEffect
-    getter effectAllowed
-    getter files
-    getter items
-    getter types
-    method clearData
-    method constructor
-    method getData
-    method setData
-    method setDragImage
-    setter dropEffect
-    setter effectAllowed
-interface DataTransferItem
-    attribute @@toStringTag
-    getter kind
-    getter type
-    method constructor
-    method getAsFile
-    method getAsFileSystemHandle
-    method getAsString
-    method webkitGetAsEntry
-interface DataTransferItemList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method add
-    method clear
-    method constructor
-    method remove
-interface DatagramDuplexStream
-    attribute @@toStringTag
-    getter incomingHighWaterMark
-    getter incomingMaxAge
-    getter outgoingHighWaterMark
-    getter outgoingMaxAge
-    getter readable
-    getter writable
-    method constructor
-    setter incomingHighWaterMark
-    setter incomingMaxAge
-    setter outgoingHighWaterMark
-    setter outgoingMaxAge
-interface DecompressionStream
-    attribute @@toStringTag
-    getter readable
-    getter writable
-    method constructor
-interface DelayNode : AudioNode
-    attribute @@toStringTag
-    getter delayTime
-    method constructor
-interface DelegatedInkTrailPresenter
-    attribute @@toStringTag
-    getter expectedImprovement
-    getter presentationArea
-    method constructor
-    method updateInkTrailStartPoint
-interface DeviceMotionEvent : Event
-    attribute @@toStringTag
-    getter acceleration
-    getter accelerationIncludingGravity
-    getter interval
-    getter rotationRate
-    method constructor
-interface DeviceMotionEventAcceleration
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-interface DeviceMotionEventRotationRate
-    attribute @@toStringTag
-    getter alpha
-    getter beta
-    getter gamma
-    method constructor
-interface DeviceOrientationEvent : Event
-    attribute @@toStringTag
-    getter absolute
-    getter alpha
-    getter beta
-    getter gamma
-    method constructor
-interface DevicePosture : EventTarget
-    attribute @@toStringTag
-    getter onchange
-    getter type
-    method constructor
-    setter onchange
-interface Document : Node
-    attribute @@toStringTag
-    attribute @@unscopables
-    getter URL
-    getter activeElement
-    getter addressSpace
-    getter adoptedStyleSheets
-    getter alinkColor
-    getter all
-    getter anchors
-    getter applets
-    getter bgColor
-    getter body
-    getter characterSet
-    getter charset
-    getter childElementCount
-    getter children
-    getter compatMode
-    getter contentType
-    getter cookie
-    getter currentScript
-    getter defaultView
-    getter designMode
-    getter dir
-    getter doctype
-    getter documentElement
-    getter documentURI
-    getter domain
-    getter embeds
-    getter featurePolicy
-    getter fgColor
-    getter firstElementChild
-    getter fonts
-    getter forms
-    getter fragmentDirective
-    getter fullscreen
-    getter fullscreenElement
-    getter fullscreenEnabled
-    getter head
-    getter hidden
-    getter images
-    getter implementation
-    getter inputEncoding
-    getter lastElementChild
-    getter lastModified
-    getter linkColor
-    getter links
-    getter onabort
-    getter onanimationend
-    getter onanimationiteration
-    getter onanimationstart
-    getter onauxclick
-    getter onbeforecopy
-    getter onbeforecut
-    getter onbeforepaste
-    getter onbeforexrselect
-    getter onblur
-    getter oncancel
-    getter oncanplay
-    getter oncanplaythrough
-    getter onchange
-    getter onclick
-    getter onclose
-    getter oncontextmenu
-    getter oncopy
-    getter oncuechange
-    getter oncut
-    getter ondblclick
-    getter ondrag
-    getter ondragend
-    getter ondragenter
-    getter ondragleave
-    getter ondragover
-    getter ondragstart
-    getter ondrop
-    getter ondurationchange
-    getter onemptied
-    getter onended
-    getter onerror
-    getter onfocus
-    getter onformdata
-    getter onfreeze
-    getter onfullscreenchange
-    getter onfullscreenerror
-    getter ongotpointercapture
-    getter oninput
-    getter oninvalid
-    getter onkeydown
-    getter onkeypress
-    getter onkeyup
-    getter onload
-    getter onloadeddata
-    getter onloadedmetadata
-    getter onloadstart
-    getter onlostpointercapture
-    getter onmousedown
-    getter onmouseenter
-    getter onmouseleave
-    getter onmousemove
-    getter onmouseout
-    getter onmouseover
-    getter onmouseup
-    getter onmousewheel
-    getter onoverscroll
-    getter onpaste
-    getter onpause
-    getter onplay
-    getter onplaying
-    getter onpointercancel
-    getter onpointerdown
-    getter onpointerenter
-    getter onpointerleave
-    getter onpointerlockchange
-    getter onpointerlockerror
-    getter onpointermove
-    getter onpointerout
-    getter onpointerover
-    getter onpointerrawupdate
-    getter onpointerup
-    getter onprogress
-    getter onratechange
-    getter onreadystatechange
-    getter onreset
-    getter onresize
-    getter onresume
-    getter onscroll
-    getter onscrollend
-    getter onsearch
-    getter onsecuritypolicyviolation
-    getter onseeked
-    getter onseeking
-    getter onselect
-    getter onselectionchange
-    getter onselectstart
-    getter onstalled
-    getter onsubmit
-    getter onsuspend
-    getter ontimeupdate
-    getter ontoggle
-    getter ontouchcancel
-    getter ontouchend
-    getter ontouchmove
-    getter ontouchstart
-    getter ontransitioncancel
-    getter ontransitionend
-    getter ontransitionrun
-    getter ontransitionstart
-    getter onvisibilitychange
-    getter onvolumechange
-    getter onwaiting
-    getter onwebkitanimationend
-    getter onwebkitanimationiteration
-    getter onwebkitanimationstart
-    getter onwebkitfullscreenchange
-    getter onwebkitfullscreenerror
-    getter onwebkittransitionend
-    getter onwheel
-    getter pictureInPictureElement
-    getter pictureInPictureEnabled
-    getter plugins
-    getter pointerLockElement
-    getter readyState
-    getter referrer
-    getter rootElement
-    getter scripts
-    getter scrollingElement
-    getter styleSheets
-    getter timeline
-    getter title
-    getter visibilityState
-    getter vlinkColor
-    getter wasDiscarded
-    getter webkitCurrentFullScreenElement
-    getter webkitFullscreenElement
-    getter webkitFullscreenEnabled
-    getter webkitHidden
-    getter webkitIsFullScreen
-    getter webkitVisibilityState
-    getter xmlEncoding
-    getter xmlStandalone
-    getter xmlVersion
-    method adoptNode
-    method append
-    method captureEvents
-    method caretRangeFromPoint
-    method clear
-    method close
-    method constructor
-    method createAttribute
-    method createAttributeNS
-    method createCDATASection
-    method createComment
-    method createDocumentFragment
-    method createElement
-    method createElementNS
-    method createEvent
-    method createExpression
-    method createNSResolver
-    method createNodeIterator
-    method createProcessingInstruction
-    method createRange
-    method createTextNode
-    method createTreeWalker
-    method elementFromPoint
-    method elementsFromPoint
-    method evaluate
-    method execCommand
-    method exitFullscreen
-    method exitPictureInPicture
-    method exitPointerLock
-    method getAnimations
-    method getElementById
-    method getElementsByClassName
-    method getElementsByName
-    method getElementsByTagName
-    method getElementsByTagNameNS
-    method getSelection
-    method hasFocus
-    method hasStorageAccess
-    method importNode
-    method open
-    method prepend
-    method queryCommandEnabled
-    method queryCommandIndeterm
-    method queryCommandState
-    method queryCommandSupported
-    method queryCommandValue
-    method querySelector
-    method querySelectorAll
-    method releaseEvents
-    method replaceChildren
-    method requestStorageAccess
-    method webkitCancelFullScreen
-    method webkitExitFullscreen
-    method write
-    method writeln
-    setter adoptedStyleSheets
-    setter alinkColor
-    setter bgColor
-    setter body
-    setter cookie
-    setter designMode
-    setter dir
-    setter domain
-    setter fgColor
-    setter fullscreen
-    setter fullscreenElement
-    setter fullscreenEnabled
-    setter linkColor
-    setter onabort
-    setter onanimationend
-    setter onanimationiteration
-    setter onanimationstart
-    setter onauxclick
-    setter onbeforecopy
-    setter onbeforecut
-    setter onbeforepaste
-    setter onbeforexrselect
-    setter onblur
-    setter oncancel
-    setter oncanplay
-    setter oncanplaythrough
-    setter onchange
-    setter onclick
-    setter onclose
-    setter oncontextmenu
-    setter oncopy
-    setter oncuechange
-    setter oncut
-    setter ondblclick
-    setter ondrag
-    setter ondragend
-    setter ondragenter
-    setter ondragleave
-    setter ondragover
-    setter ondragstart
-    setter ondrop
-    setter ondurationchange
-    setter onemptied
-    setter onended
-    setter onerror
-    setter onfocus
-    setter onformdata
-    setter onfreeze
-    setter onfullscreenchange
-    setter onfullscreenerror
-    setter ongotpointercapture
-    setter oninput
-    setter oninvalid
-    setter onkeydown
-    setter onkeypress
-    setter onkeyup
-    setter onload
-    setter onloadeddata
-    setter onloadedmetadata
-    setter onloadstart
-    setter onlostpointercapture
-    setter onmousedown
-    setter onmouseenter
-    setter onmouseleave
-    setter onmousemove
-    setter onmouseout
-    setter onmouseover
-    setter onmouseup
-    setter onmousewheel
-    setter onoverscroll
-    setter onpaste
-    setter onpause
-    setter onplay
-    setter onplaying
-    setter onpointercancel
-    setter onpointerdown
-    setter onpointerenter
-    setter onpointerleave
-    setter onpointerlockchange
-    setter onpointerlockerror
-    setter onpointermove
-    setter onpointerout
-    setter onpointerover
-    setter onpointerrawupdate
-    setter onpointerup
-    setter onprogress
-    setter onratechange
-    setter onreadystatechange
-    setter onreset
-    setter onresize
-    setter onresume
-    setter onscroll
-    setter onscrollend
-    setter onsearch
-    setter onsecuritypolicyviolation
-    setter onseeked
-    setter onseeking
-    setter onselect
-    setter onselectionchange
-    setter onselectstart
-    setter onstalled
-    setter onsubmit
-    setter onsuspend
-    setter ontimeupdate
-    setter ontoggle
-    setter ontouchcancel
-    setter ontouchend
-    setter ontouchmove
-    setter ontouchstart
-    setter ontransitioncancel
-    setter ontransitionend
-    setter ontransitionrun
-    setter ontransitionstart
-    setter onvisibilitychange
-    setter onvolumechange
-    setter onwaiting
-    setter onwebkitanimationend
-    setter onwebkitanimationiteration
-    setter onwebkitanimationstart
-    setter onwebkitfullscreenchange
-    setter onwebkitfullscreenerror
-    setter onwebkittransitionend
-    setter onwheel
-    setter title
-    setter vlinkColor
-    setter xmlStandalone
-    setter xmlVersion
-interface DocumentFragment : Node
-    attribute @@toStringTag
-    attribute @@unscopables
-    getter childElementCount
-    getter children
-    getter firstElementChild
-    getter lastElementChild
-    method append
-    method constructor
-    method getElementById
-    method prepend
-    method querySelector
-    method querySelectorAll
-    method replaceChildren
-interface DocumentTimeline : AnimationTimeline
-    attribute @@toStringTag
-    method constructor
-interface DocumentType : Node
-    attribute @@toStringTag
-    attribute @@unscopables
-    getter name
-    getter publicId
-    getter systemId
-    method after
-    method before
-    method constructor
-    method remove
-    method replaceWith
-interface DragEvent : MouseEvent
-    attribute @@toStringTag
-    getter dataTransfer
-    method constructor
-interface DynamicsCompressorNode : AudioNode
-    attribute @@toStringTag
-    getter attack
-    getter knee
-    getter ratio
-    getter reduction
-    getter release
-    getter threshold
-    method constructor
-interface EditContext : EventTarget
-    attribute @@toStringTag
-    getter enterKeyHint
-    getter inputMode
-    getter inputPanelPolicy
-    getter oncompositionend
-    getter oncompositionstart
-    getter ontextformatupdate
-    getter ontextupdate
-    getter selectionEnd
-    getter selectionStart
-    getter text
-    method constructor
-    method updateLayout
-    method updateSelection
-    method updateText
-    setter enterKeyHint
-    setter inputMode
-    setter inputPanelPolicy
-    setter oncompositionend
-    setter oncompositionstart
-    setter ontextformatupdate
-    setter ontextupdate
-    setter selectionEnd
-    setter selectionStart
-    setter text
-interface Element : Node
-    attribute @@toStringTag
-    attribute @@unscopables
-    getter accessibleNode
-    getter ariaActiveDescendantElement
-    getter ariaAtomic
-    getter ariaAutoComplete
-    getter ariaBusy
-    getter ariaChecked
-    getter ariaColCount
-    getter ariaColIndex
-    getter ariaColSpan
-    getter ariaControlsElements
-    getter ariaCurrent
-    getter ariaDescribedByElements
-    getter ariaDescription
-    getter ariaDetailsElements
-    getter ariaDisabled
-    getter ariaErrorMessageElement
-    getter ariaExpanded
-    getter ariaFlowToElements
-    getter ariaHasPopup
-    getter ariaHidden
-    getter ariaKeyShortcuts
-    getter ariaLabel
-    getter ariaLabelledByElements
-    getter ariaLevel
-    getter ariaLive
-    getter ariaModal
-    getter ariaMultiLine
-    getter ariaMultiSelectable
-    getter ariaOrientation
-    getter ariaOwnsElements
-    getter ariaPlaceholder
-    getter ariaPosInSet
-    getter ariaPressed
-    getter ariaReadOnly
-    getter ariaRelevant
-    getter ariaRequired
-    getter ariaRoleDescription
-    getter ariaRowCount
-    getter ariaRowIndex
-    getter ariaRowSpan
-    getter ariaSelected
-    getter ariaSetSize
-    getter ariaSort
-    getter ariaValueMax
-    getter ariaValueMin
-    getter ariaValueNow
-    getter ariaValueText
-    getter ariaVirtualContent
-    getter assignedSlot
-    getter attributeStyleMap
-    getter attributes
-    getter childElementCount
-    getter children
-    getter classList
-    getter className
-    getter clientHeight
-    getter clientLeft
-    getter clientTop
-    getter clientWidth
-    getter computedName
-    getter computedRole
-    getter editContext
-    getter elementTiming
-    getter firstElementChild
-    getter id
-    getter innerHTML
-    getter lastElementChild
-    getter localName
-    getter namespaceURI
-    getter nextElementSibling
-    getter onbeforecopy
-    getter onbeforecut
-    getter onbeforematch
-    getter onbeforepaste
-    getter onfullscreenchange
-    getter onfullscreenerror
-    getter onsearch
-    getter onwebkitfullscreenchange
-    getter onwebkitfullscreenerror
-    getter outerHTML
-    getter part
-    getter prefix
-    getter previousElementSibling
-    getter role
-    getter scrollHeight
-    getter scrollLeft
-    getter scrollTop
-    getter scrollWidth
-    getter shadowRoot
-    getter slot
-    getter tagName
-    method after
-    method animate
-    method append
-    method attachShadow
-    method before
-    method closest
-    method computedStyleMap
-    method constructor
-    method getAnimations
-    method getAttribute
-    method getAttributeNS
-    method getAttributeNames
-    method getAttributeNode
-    method getAttributeNodeNS
-    method getBoundingClientRect
-    method getClientRects
-    method getElementsByClassName
-    method getElementsByTagName
-    method getElementsByTagNameNS
-    method getInnerHTML
-    method hasAttribute
-    method hasAttributeNS
-    method hasAttributes
-    method hasPointerCapture
-    method insertAdjacentElement
-    method insertAdjacentHTML
-    method insertAdjacentText
-    method matches
-    method prepend
-    method querySelector
-    method querySelectorAll
-    method releasePointerCapture
-    method remove
-    method removeAttribute
-    method removeAttributeNS
-    method removeAttributeNode
-    method replaceChildren
-    method replaceWith
-    method requestFullscreen
-    method requestPointerLock
-    method scroll
-    method scrollBy
-    method scrollIntoView
-    method scrollIntoViewIfNeeded
-    method scrollTo
-    method setAttribute
-    method setAttributeNS
-    method setAttributeNode
-    method setAttributeNodeNS
-    method setPointerCapture
-    method toggleAttribute
-    method webkitMatchesSelector
-    method webkitRequestFullScreen
-    method webkitRequestFullscreen
-    setter ariaActiveDescendantElement
-    setter ariaAtomic
-    setter ariaAutoComplete
-    setter ariaBusy
-    setter ariaChecked
-    setter ariaColCount
-    setter ariaColIndex
-    setter ariaColSpan
-    setter ariaControlsElements
-    setter ariaCurrent
-    setter ariaDescribedByElements
-    setter ariaDescription
-    setter ariaDetailsElements
-    setter ariaDisabled
-    setter ariaErrorMessageElement
-    setter ariaExpanded
-    setter ariaFlowToElements
-    setter ariaHasPopup
-    setter ariaHidden
-    setter ariaKeyShortcuts
-    setter ariaLabel
-    setter ariaLabelledByElements
-    setter ariaLevel
-    setter ariaLive
-    setter ariaModal
-    setter ariaMultiLine
-    setter ariaMultiSelectable
-    setter ariaOrientation
-    setter ariaOwnsElements
-    setter ariaPlaceholder
-    setter ariaPosInSet
-    setter ariaPressed
-    setter ariaReadOnly
-    setter ariaRelevant
-    setter ariaRequired
-    setter ariaRoleDescription
-    setter ariaRowCount
-    setter ariaRowIndex
-    setter ariaRowSpan
-    setter ariaSelected
-    setter ariaSetSize
-    setter ariaSort
-    setter ariaValueMax
-    setter ariaValueMin
-    setter ariaValueNow
-    setter ariaValueText
-    setter ariaVirtualContent
-    setter classList
-    setter className
-    setter editContext
-    setter elementTiming
-    setter id
-    setter innerHTML
-    setter onbeforecopy
-    setter onbeforecut
-    setter onbeforematch
-    setter onbeforepaste
-    setter onfullscreenchange
-    setter onfullscreenerror
-    setter onsearch
-    setter onwebkitfullscreenchange
-    setter onwebkitfullscreenerror
-    setter outerHTML
-    setter part
-    setter role
-    setter scrollLeft
-    setter scrollTop
-    setter slot
-interface ElementInternals
-    attribute @@toStringTag
-    getter ariaActiveDescendantElement
-    getter ariaAtomic
-    getter ariaAutoComplete
-    getter ariaBusy
-    getter ariaChecked
-    getter ariaColCount
-    getter ariaColIndex
-    getter ariaColSpan
-    getter ariaControlsElements
-    getter ariaCurrent
-    getter ariaDescribedByElements
-    getter ariaDescription
-    getter ariaDetailsElements
-    getter ariaDisabled
-    getter ariaErrorMessageElement
-    getter ariaExpanded
-    getter ariaFlowToElements
-    getter ariaHasPopup
-    getter ariaHidden
-    getter ariaKeyShortcuts
-    getter ariaLabel
-    getter ariaLabelledByElements
-    getter ariaLevel
-    getter ariaLive
-    getter ariaModal
-    getter ariaMultiLine
-    getter ariaMultiSelectable
-    getter ariaOrientation
-    getter ariaOwnsElements
-    getter ariaPlaceholder
-    getter ariaPosInSet
-    getter ariaPressed
-    getter ariaReadOnly
-    getter ariaRelevant
-    getter ariaRequired
-    getter ariaRoleDescription
-    getter ariaRowCount
-    getter ariaRowIndex
-    getter ariaRowSpan
-    getter ariaSelected
-    getter ariaSetSize
-    getter ariaSort
-    getter ariaValueMax
-    getter ariaValueMin
-    getter ariaValueNow
-    getter ariaValueText
-    getter ariaVirtualContent
-    getter form
-    getter labels
-    getter role
-    getter shadowRoot
-    getter states
-    getter validationMessage
-    getter validity
-    getter willValidate
-    method checkValidity
-    method constructor
-    method reportValidity
-    method setFormValue
-    method setValidity
-    setter ariaActiveDescendantElement
-    setter ariaAtomic
-    setter ariaAutoComplete
-    setter ariaBusy
-    setter ariaChecked
-    setter ariaColCount
-    setter ariaColIndex
-    setter ariaColSpan
-    setter ariaControlsElements
-    setter ariaCurrent
-    setter ariaDescribedByElements
-    setter ariaDescription
-    setter ariaDetailsElements
-    setter ariaDisabled
-    setter ariaErrorMessageElement
-    setter ariaExpanded
-    setter ariaFlowToElements
-    setter ariaHasPopup
-    setter ariaHidden
-    setter ariaKeyShortcuts
-    setter ariaLabel
-    setter ariaLabelledByElements
-    setter ariaLevel
-    setter ariaLive
-    setter ariaModal
-    setter ariaMultiLine
-    setter ariaMultiSelectable
-    setter ariaOrientation
-    setter ariaOwnsElements
-    setter ariaPlaceholder
-    setter ariaPosInSet
-    setter ariaPressed
-    setter ariaReadOnly
-    setter ariaRelevant
-    setter ariaRequired
-    setter ariaRoleDescription
-    setter ariaRowCount
-    setter ariaRowIndex
-    setter ariaRowSpan
-    setter ariaSelected
-    setter ariaSetSize
-    setter ariaSort
-    setter ariaValueMax
-    setter ariaValueMin
-    setter ariaValueNow
-    setter ariaValueText
-    setter ariaVirtualContent
-    setter role
-interface EncodedAudioChunk
-    attribute @@toStringTag
-    getter byteLength
-    getter timestamp
-    getter type
-    method constructor
-    method copyTo
-interface EncodedVideoChunk
-    attribute @@toStringTag
-    getter byteLength
-    getter duration
-    getter timestamp
-    getter type
-    method constructor
-    method copyTo
-interface ErrorEvent : Event
-    attribute @@toStringTag
-    getter colno
-    getter error
-    getter filename
-    getter lineno
-    getter message
-    method constructor
-interface Event
-    attribute @@toStringTag
-    attribute AT_TARGET
-    attribute BUBBLING_PHASE
-    attribute CAPTURING_PHASE
-    attribute NONE
-    getter bubbles
-    getter cancelBubble
-    getter cancelable
-    getter composed
-    getter currentTarget
-    getter defaultPrevented
-    getter eventPhase
-    getter path
-    getter returnValue
-    getter srcElement
-    getter target
-    getter timeStamp
-    getter type
-    method composedPath
-    method constructor
-    method initEvent
-    method preventDefault
-    method stopImmediatePropagation
-    method stopPropagation
-    setter cancelBubble
-    setter returnValue
-interface EventCounts
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface EventSource : EventTarget
-    attribute @@toStringTag
-    attribute CLOSED
-    attribute CONNECTING
-    attribute OPEN
-    getter onerror
-    getter onmessage
-    getter onopen
-    getter readyState
-    getter url
-    getter withCredentials
-    method close
-    method constructor
-    setter onerror
-    setter onmessage
-    setter onopen
-interface EventTarget
-    attribute @@toStringTag
-    method addEventListener
-    method constructor
-    method dispatchEvent
-    method removeEventListener
-interface External
-    attribute @@toStringTag
-    method AddSearchProvider
-    method IsSearchProviderInstalled
-    method constructor
-interface EyeDropper : EventTarget
-    attribute @@toStringTag
-    getter onclose
-    getter oncolorselect
-    getter opened
-    method close
-    method constructor
-    method open
-    setter onclose
-    setter oncolorselect
-interface FaceDetector
-    attribute @@toStringTag
-    method constructor
-    method detect
-interface FeaturePolicy
-    attribute @@toStringTag
-    method allowedFeatures
-    method allowsFeature
-    method constructor
-    method features
-    method getAllowlistForFeature
-interface FederatedCredential : Credential
-    attribute @@toStringTag
-    getter iconURL
-    getter name
-    getter protocol
-    getter provider
-    method constructor
-interface File : Blob
-    attribute @@toStringTag
-    getter lastModified
-    getter lastModifiedDate
-    getter name
-    getter webkitRelativePath
-    method constructor
-interface FileList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-interface FileReader : EventTarget
-    attribute @@toStringTag
-    attribute DONE
-    attribute EMPTY
-    attribute LOADING
-    getter error
-    getter onabort
-    getter onerror
-    getter onload
-    getter onloadend
-    getter onloadstart
-    getter onprogress
-    getter readyState
-    getter result
-    method abort
-    method constructor
-    method readAsArrayBuffer
-    method readAsBinaryString
-    method readAsDataURL
-    method readAsText
-    setter onabort
-    setter onerror
-    setter onload
-    setter onloadend
-    setter onloadstart
-    setter onprogress
-interface FileSystemDirectoryHandle : FileSystemHandle
-    attribute @@toStringTag
-    method @@asyncIterator
-    method constructor
-    method entries
-    method getDirectoryHandle
-    method getFileHandle
-    method keys
-    method removeEntry
-    method resolve
-    method values
-interface FileSystemFileHandle : FileSystemHandle
-    attribute @@toStringTag
-    method constructor
-    method createWritable
-    method getFile
-interface FileSystemHandle
-    attribute @@toStringTag
-    getter kind
-    getter name
-    method constructor
-    method isSameEntry
-    method queryPermission
-    method remove
-    method requestPermission
-interface FileSystemWritableFileStream : WritableStream
-    attribute @@toStringTag
-    method constructor
-    method seek
-    method truncate
-    method write
-interface FocusEvent : UIEvent
-    attribute @@toStringTag
-    getter relatedTarget
-    method constructor
-interface FontFace
-    attribute @@toStringTag
-    getter ascentOverride
-    getter descentOverride
-    getter display
-    getter family
-    getter featureSettings
-    getter lineGapOverride
-    getter loaded
-    getter sizeAdjust
-    getter status
-    getter stretch
-    getter style
-    getter unicodeRange
-    getter variant
-    getter weight
-    method constructor
-    method load
-    setter ascentOverride
-    setter descentOverride
-    setter display
-    setter family
-    setter featureSettings
-    setter lineGapOverride
-    setter sizeAdjust
-    setter stretch
-    setter style
-    setter unicodeRange
-    setter variant
-    setter weight
-interface FontFaceSetLoadEvent : Event
-    attribute @@toStringTag
-    getter fontfaces
-    method constructor
-interface FormData
-    attribute @@toStringTag
-    method @@iterator
-    method append
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method get
-    method getAll
-    method has
-    method keys
-    method set
-    method values
-interface FormDataEvent : Event
-    attribute @@toStringTag
-    getter formData
-    method constructor
-interface FragmentDirective
-    attribute @@toStringTag
-    method constructor
-interface GainNode : AudioNode
-    attribute @@toStringTag
-    getter gain
-    method constructor
-interface Gamepad
-    attribute @@toStringTag
-    getter axes
-    getter buttons
-    getter connected
-    getter id
-    getter index
-    getter mapping
-    getter timestamp
-    getter vibrationActuator
-    method constructor
-interface GamepadAxisEvent : GamepadEvent
-    attribute @@toStringTag
-    getter axis
-    getter value
-    method constructor
-interface GamepadButton
-    attribute @@toStringTag
-    getter pressed
-    getter touched
-    getter value
-    method constructor
-interface GamepadButtonEvent : GamepadEvent
-    attribute @@toStringTag
-    getter button
-    getter value
-    method constructor
-interface GamepadEvent : Event
-    attribute @@toStringTag
-    getter gamepad
-    method constructor
-interface GamepadHapticActuator
-    attribute @@toStringTag
-    getter type
-    method constructor
-    method playEffect
-    method reset
-interface Geolocation
-    attribute @@toStringTag
-    method clearWatch
-    method constructor
-    method getCurrentPosition
-    method watchPosition
-interface GeolocationCoordinates
-    attribute @@toStringTag
-    getter accuracy
-    getter altitude
-    getter altitudeAccuracy
-    getter heading
-    getter latitude
-    getter longitude
-    getter speed
-    method constructor
-interface GeolocationPosition
-    attribute @@toStringTag
-    getter coords
-    getter timestamp
-    method constructor
-interface GeolocationPositionError
-    attribute @@toStringTag
-    attribute PERMISSION_DENIED
-    attribute POSITION_UNAVAILABLE
-    attribute TIMEOUT
-    getter code
-    getter message
-    method constructor
-interface GravitySensor : Accelerometer
-    attribute @@toStringTag
-    method constructor
-interface Gyroscope : Sensor
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-interface HID : EventTarget
-    attribute @@toStringTag
-    getter onconnect
-    getter ondisconnect
-    method constructor
-    method getDevices
-    method requestDevice
-    setter onconnect
-    setter ondisconnect
-interface HIDConnectionEvent : Event
-    attribute @@toStringTag
-    getter device
-    method constructor
-interface HIDDevice : EventTarget
-    attribute @@toStringTag
-    getter collections
-    getter oninputreport
-    getter opened
-    getter productId
-    getter productName
-    getter vendorId
-    method close
-    method constructor
-    method open
-    method receiveFeatureReport
-    method sendFeatureReport
-    method sendReport
-    setter oninputreport
-interface HIDInputReportEvent : Event
-    attribute @@toStringTag
-    getter data
-    getter device
-    getter reportId
-    method constructor
-interface HTMLAllCollection
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-    method namedItem
-interface HTMLAnchorElement : HTMLElement
-    attribute @@toStringTag
-    getter attributionDestination
-    getter attributionExpiry
-    getter attributionReportTo
-    getter attributionSourceEventId
-    getter attributionSourcePriority
-    getter charset
-    getter coords
-    getter download
-    getter hash
-    getter host
-    getter hostname
-    getter href
-    getter hrefTranslate
-    getter hreflang
-    getter name
-    getter origin
-    getter password
-    getter pathname
-    getter ping
-    getter port
-    getter protocol
-    getter referrerPolicy
-    getter registerAttributionSource
-    getter rel
-    getter relList
-    getter rev
-    getter search
-    getter shape
-    getter target
-    getter text
-    getter type
-    getter username
-    method constructor
-    method toString
-    setter attributionDestination
-    setter attributionExpiry
-    setter attributionReportTo
-    setter attributionSourceEventId
-    setter attributionSourcePriority
-    setter charset
-    setter coords
-    setter download
-    setter hash
-    setter host
-    setter hostname
-    setter href
-    setter hrefTranslate
-    setter hreflang
-    setter name
-    setter password
-    setter pathname
-    setter ping
-    setter port
-    setter protocol
-    setter referrerPolicy
-    setter registerAttributionSource
-    setter rel
-    setter relList
-    setter rev
-    setter search
-    setter shape
-    setter target
-    setter text
-    setter type
-    setter username
-interface HTMLAreaElement : HTMLElement
-    attribute @@toStringTag
-    getter alt
-    getter coords
-    getter download
-    getter hash
-    getter host
-    getter hostname
-    getter href
-    getter noHref
-    getter origin
-    getter password
-    getter pathname
-    getter ping
-    getter port
-    getter protocol
-    getter referrerPolicy
-    getter rel
-    getter relList
-    getter search
-    getter shape
-    getter target
-    getter username
-    method constructor
-    method toString
-    setter alt
-    setter coords
-    setter download
-    setter hash
-    setter host
-    setter hostname
-    setter href
-    setter noHref
-    setter password
-    setter pathname
-    setter ping
-    setter port
-    setter protocol
-    setter referrerPolicy
-    setter rel
-    setter relList
-    setter search
-    setter shape
-    setter target
-    setter username
-interface HTMLAudioElement : HTMLMediaElement
-    attribute @@toStringTag
-    method constructor
-interface HTMLBRElement : HTMLElement
-    attribute @@toStringTag
-    getter clear
-    method constructor
-    setter clear
-interface HTMLBaseElement : HTMLElement
-    attribute @@toStringTag
-    getter href
-    getter target
-    method constructor
-    setter href
-    setter target
-interface HTMLBodyElement : HTMLElement
-    attribute @@toStringTag
-    getter aLink
-    getter background
-    getter bgColor
-    getter link
-    getter onafterprint
-    getter onbeforeprint
-    getter onbeforeunload
-    getter onblur
-    getter onerror
-    getter onfocus
-    getter onhashchange
-    getter onlanguagechange
-    getter onload
-    getter onmessage
-    getter onmessageerror
-    getter onoffline
-    getter ononline
-    getter onpagehide
-    getter onpageshow
-    getter onpopstate
-    getter onrejectionhandled
-    getter onresize
-    getter onscroll
-    getter onstorage
-    getter ontimezonechange
-    getter onunhandledrejection
-    getter onunload
-    getter text
-    getter vLink
-    method constructor
-    setter aLink
-    setter background
-    setter bgColor
-    setter link
-    setter onafterprint
-    setter onbeforeprint
-    setter onbeforeunload
-    setter onblur
-    setter onerror
-    setter onfocus
-    setter onhashchange
-    setter onlanguagechange
-    setter onload
-    setter onmessage
-    setter onmessageerror
-    setter onoffline
-    setter ononline
-    setter onpagehide
-    setter onpageshow
-    setter onpopstate
-    setter onrejectionhandled
-    setter onresize
-    setter onscroll
-    setter onstorage
-    setter ontimezonechange
-    setter onunhandledrejection
-    setter onunload
-    setter text
-    setter vLink
-interface HTMLButtonElement : HTMLElement
-    attribute @@toStringTag
-    getter disabled
-    getter form
-    getter formAction
-    getter formEnctype
-    getter formMethod
-    getter formNoValidate
-    getter formTarget
-    getter labels
-    getter name
-    getter type
-    getter validationMessage
-    getter validity
-    getter value
-    getter willValidate
-    method checkValidity
-    method constructor
-    method reportValidity
-    method setCustomValidity
-    setter disabled
-    setter formAction
-    setter formEnctype
-    setter formMethod
-    setter formNoValidate
-    setter formTarget
-    setter name
-    setter type
-    setter value
-interface HTMLCanvasElement : HTMLElement
-    attribute @@toStringTag
-    getter height
-    getter width
-    method captureStream
-    method constructor
-    method convertToBlob
-    method getContext
-    method toBlob
-    method toDataURL
-    method transferControlToOffscreen
-    setter height
-    setter width
-interface HTMLCollection
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-    method namedItem
-interface HTMLDListElement : HTMLElement
-    attribute @@toStringTag
-    getter compact
-    method constructor
-    setter compact
-interface HTMLDataElement : HTMLElement
-    attribute @@toStringTag
-    getter value
-    method constructor
-    setter value
-interface HTMLDataListElement : HTMLElement
-    attribute @@toStringTag
-    getter options
-    method constructor
-interface HTMLDetailsElement : HTMLElement
-    attribute @@toStringTag
-    getter open
-    method constructor
-    setter open
-interface HTMLDialogElement : HTMLElement
-    attribute @@toStringTag
-    getter open
-    getter returnValue
-    method close
-    method constructor
-    method show
-    method showModal
-    setter open
-    setter returnValue
-interface HTMLDirectoryElement : HTMLElement
-    attribute @@toStringTag
-    getter compact
-    method constructor
-    setter compact
-interface HTMLDivElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    method constructor
-    setter align
-interface HTMLDocument : Document
-    attribute @@toStringTag
-    method constructor
-interface HTMLElement : Element
-    attribute @@toStringTag
-    getter accessKey
-    getter autocapitalize
-    getter autofocus
-    getter contentEditable
-    getter dataset
-    getter dir
-    getter draggable
-    getter enterKeyHint
-    getter hidden
-    getter inert
-    getter innerText
-    getter inputMode
-    getter isContentEditable
-    getter lang
-    getter nonce
-    getter offsetHeight
-    getter offsetLeft
-    getter offsetParent
-    getter offsetTop
-    getter offsetWidth
-    getter onabort
-    getter onanimationend
-    getter onanimationiteration
-    getter onanimationstart
-    getter onauxclick
-    getter onbeforexrselect
-    getter onblur
-    getter oncancel
-    getter oncanplay
-    getter oncanplaythrough
-    getter onchange
-    getter onclick
-    getter onclose
-    getter oncontextmenu
-    getter oncopy
-    getter oncuechange
-    getter oncut
-    getter ondblclick
-    getter ondrag
-    getter ondragend
-    getter ondragenter
-    getter ondragleave
-    getter ondragover
-    getter ondragstart
-    getter ondrop
-    getter ondurationchange
-    getter onemptied
-    getter onended
-    getter onerror
-    getter onfocus
-    getter onformdata
-    getter ongotpointercapture
-    getter oninput
-    getter oninvalid
-    getter onkeydown
-    getter onkeypress
-    getter onkeyup
-    getter onload
-    getter onloadeddata
-    getter onloadedmetadata
-    getter onloadstart
-    getter onlostpointercapture
-    getter onmousedown
-    getter onmouseenter
-    getter onmouseleave
-    getter onmousemove
-    getter onmouseout
-    getter onmouseover
-    getter onmouseup
-    getter onmousewheel
-    getter onoverscroll
-    getter onpaste
-    getter onpause
-    getter onplay
-    getter onplaying
-    getter onpointercancel
-    getter onpointerdown
-    getter onpointerenter
-    getter onpointerleave
-    getter onpointermove
-    getter onpointerout
-    getter onpointerover
-    getter onpointerrawupdate
-    getter onpointerup
-    getter onprogress
-    getter onratechange
-    getter onreset
-    getter onresize
-    getter onscroll
-    getter onscrollend
-    getter onseeked
-    getter onseeking
-    getter onselect
-    getter onselectionchange
-    getter onselectstart
-    getter onstalled
-    getter onsubmit
-    getter onsuspend
-    getter ontimeupdate
-    getter ontoggle
-    getter ontouchcancel
-    getter ontouchend
-    getter ontouchmove
-    getter ontouchstart
-    getter ontransitioncancel
-    getter ontransitionend
-    getter ontransitionrun
-    getter ontransitionstart
-    getter onvolumechange
-    getter onwaiting
-    getter onwebkitanimationend
-    getter onwebkitanimationiteration
-    getter onwebkitanimationstart
-    getter onwebkittransitionend
-    getter onwheel
-    getter outerText
-    getter spellcheck
-    getter style
-    getter tabIndex
-    getter title
-    getter translate
-    getter virtualKeyboardPolicy
-    method attachInternals
-    method blur
-    method click
-    method constructor
-    method focus
-    setter accessKey
-    setter autocapitalize
-    setter autofocus
-    setter contentEditable
-    setter dir
-    setter draggable
-    setter enterKeyHint
-    setter hidden
-    setter inert
-    setter innerText
-    setter inputMode
-    setter lang
-    setter nonce
-    setter onabort
-    setter onanimationend
-    setter onanimationiteration
-    setter onanimationstart
-    setter onauxclick
-    setter onbeforexrselect
-    setter onblur
-    setter oncancel
-    setter oncanplay
-    setter oncanplaythrough
-    setter onchange
-    setter onclick
-    setter onclose
-    setter oncontextmenu
-    setter oncopy
-    setter oncuechange
-    setter oncut
-    setter ondblclick
-    setter ondrag
-    setter ondragend
-    setter ondragenter
-    setter ondragleave
-    setter ondragover
-    setter ondragstart
-    setter ondrop
-    setter ondurationchange
-    setter onemptied
-    setter onended
-    setter onerror
-    setter onfocus
-    setter onformdata
-    setter ongotpointercapture
-    setter oninput
-    setter oninvalid
-    setter onkeydown
-    setter onkeypress
-    setter onkeyup
-    setter onload
-    setter onloadeddata
-    setter onloadedmetadata
-    setter onloadstart
-    setter onlostpointercapture
-    setter onmousedown
-    setter onmouseenter
-    setter onmouseleave
-    setter onmousemove
-    setter onmouseout
-    setter onmouseover
-    setter onmouseup
-    setter onmousewheel
-    setter onoverscroll
-    setter onpaste
-    setter onpause
-    setter onplay
-    setter onplaying
-    setter onpointercancel
-    setter onpointerdown
-    setter onpointerenter
-    setter onpointerleave
-    setter onpointermove
-    setter onpointerout
-    setter onpointerover
-    setter onpointerrawupdate
-    setter onpointerup
-    setter onprogress
-    setter onratechange
-    setter onreset
-    setter onresize
-    setter onscroll
-    setter onscrollend
-    setter onseeked
-    setter onseeking
-    setter onselect
-    setter onselectionchange
-    setter onselectstart
-    setter onstalled
-    setter onsubmit
-    setter onsuspend
-    setter ontimeupdate
-    setter ontoggle
-    setter ontouchcancel
-    setter ontouchend
-    setter ontouchmove
-    setter ontouchstart
-    setter ontransitioncancel
-    setter ontransitionend
-    setter ontransitionrun
-    setter ontransitionstart
-    setter onvolumechange
-    setter onwaiting
-    setter onwebkitanimationend
-    setter onwebkitanimationiteration
-    setter onwebkitanimationstart
-    setter onwebkittransitionend
-    setter onwheel
-    setter outerText
-    setter spellcheck
-    setter style
-    setter tabIndex
-    setter title
-    setter translate
-    setter virtualKeyboardPolicy
-interface HTMLEmbedElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter height
-    getter name
-    getter src
-    getter type
-    getter width
-    method constructor
-    method getSVGDocument
-    setter align
-    setter height
-    setter name
-    setter src
-    setter type
-    setter width
-interface HTMLFencedFrameElement : HTMLElement
-    attribute @@toStringTag
-    getter src
-    method constructor
-    setter src
-interface HTMLFieldSetElement : HTMLElement
-    attribute @@toStringTag
-    getter disabled
-    getter elements
-    getter form
-    getter name
-    getter type
-    getter validationMessage
-    getter validity
-    getter willValidate
-    method checkValidity
-    method constructor
-    method reportValidity
-    method setCustomValidity
-    setter disabled
-    setter name
-interface HTMLFontElement : HTMLElement
-    attribute @@toStringTag
-    getter color
-    getter face
-    getter size
-    method constructor
-    setter color
-    setter face
-    setter size
-interface HTMLFormControlsCollection : HTMLCollection
-    attribute @@toStringTag
-    method @@iterator
-    method constructor
-    method namedItem
-interface HTMLFormElement : HTMLElement
-    attribute @@toStringTag
-    getter acceptCharset
-    getter action
-    getter autocomplete
-    getter elements
-    getter encoding
-    getter enctype
-    getter length
-    getter method
-    getter name
-    getter noValidate
-    getter target
-    method @@iterator
-    method checkValidity
-    method constructor
-    method reportValidity
-    method requestSubmit
-    method reset
-    method submit
-    setter acceptCharset
-    setter action
-    setter autocomplete
-    setter encoding
-    setter enctype
-    setter method
-    setter name
-    setter noValidate
-    setter target
-interface HTMLFrameElement : HTMLElement
-    attribute @@toStringTag
-    getter contentDocument
-    getter contentWindow
-    getter frameBorder
-    getter longDesc
-    getter marginHeight
-    getter marginWidth
-    getter name
-    getter noResize
-    getter scrolling
-    getter src
-    method constructor
-    setter frameBorder
-    setter longDesc
-    setter marginHeight
-    setter marginWidth
-    setter name
-    setter noResize
-    setter scrolling
-    setter src
-interface HTMLFrameSetElement : HTMLElement
-    attribute @@toStringTag
-    getter cols
-    getter onafterprint
-    getter onbeforeprint
-    getter onbeforeunload
-    getter onblur
-    getter onerror
-    getter onfocus
-    getter onhashchange
-    getter onlanguagechange
-    getter onload
-    getter onmessage
-    getter onmessageerror
-    getter onoffline
-    getter ononline
-    getter onpagehide
-    getter onpageshow
-    getter onpopstate
-    getter onrejectionhandled
-    getter onresize
-    getter onscroll
-    getter onstorage
-    getter ontimezonechange
-    getter onunhandledrejection
-    getter onunload
-    getter rows
-    method constructor
-    setter cols
-    setter onafterprint
-    setter onbeforeprint
-    setter onbeforeunload
-    setter onblur
-    setter onerror
-    setter onfocus
-    setter onhashchange
-    setter onlanguagechange
-    setter onload
-    setter onmessage
-    setter onmessageerror
-    setter onoffline
-    setter ononline
-    setter onpagehide
-    setter onpageshow
-    setter onpopstate
-    setter onrejectionhandled
-    setter onresize
-    setter onscroll
-    setter onstorage
-    setter ontimezonechange
-    setter onunhandledrejection
-    setter onunload
-    setter rows
-interface HTMLHRElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter color
-    getter noShade
-    getter size
-    getter width
-    method constructor
-    setter align
-    setter color
-    setter noShade
-    setter size
-    setter width
-interface HTMLHeadElement : HTMLElement
-    attribute @@toStringTag
-    method constructor
-interface HTMLHeadingElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    method constructor
-    setter align
-interface HTMLHtmlElement : HTMLElement
-    attribute @@toStringTag
-    getter version
-    method constructor
-    setter version
-interface HTMLIFrameElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter allow
-    getter allowFullscreen
-    getter allowPaymentRequest
-    getter anonymous
-    getter contentDocument
-    getter contentWindow
-    getter csp
-    getter featurePolicy
-    getter frameBorder
-    getter height
-    getter loading
-    getter longDesc
-    getter marginHeight
-    getter marginWidth
-    getter name
-    getter policy
-    getter referrerPolicy
-    getter sandbox
-    getter scrolling
-    getter src
-    getter srcdoc
-    getter width
-    method constructor
-    method getSVGDocument
-    setter align
-    setter allow
-    setter allowFullscreen
-    setter allowPaymentRequest
-    setter anonymous
-    setter csp
-    setter frameBorder
-    setter height
-    setter loading
-    setter longDesc
-    setter marginHeight
-    setter marginWidth
-    setter name
-    setter policy
-    setter referrerPolicy
-    setter sandbox
-    setter scrolling
-    setter src
-    setter srcdoc
-    setter width
-interface HTMLImageElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter alt
-    getter border
-    getter complete
-    getter crossOrigin
-    getter currentSrc
-    getter decoding
-    getter height
-    getter hspace
-    getter importance
-    getter isMap
-    getter loading
-    getter longDesc
-    getter lowsrc
-    getter name
-    getter naturalHeight
-    getter naturalWidth
-    getter referrerPolicy
-    getter sizes
-    getter src
-    getter srcset
-    getter useMap
-    getter vspace
-    getter width
-    getter x
-    getter y
-    method constructor
-    method decode
-    setter align
-    setter alt
-    setter border
-    setter crossOrigin
-    setter decoding
-    setter height
-    setter hspace
-    setter importance
-    setter isMap
-    setter loading
-    setter longDesc
-    setter lowsrc
-    setter name
-    setter referrerPolicy
-    setter sizes
-    setter src
-    setter srcset
-    setter useMap
-    setter vspace
-    setter width
-interface HTMLInputElement : HTMLElement
-    attribute @@toStringTag
-    getter accept
-    getter align
-    getter alt
-    getter autocomplete
-    getter checked
-    getter defaultChecked
-    getter defaultValue
-    getter dirName
-    getter disabled
-    getter files
-    getter form
-    getter formAction
-    getter formEnctype
-    getter formMethod
-    getter formNoValidate
-    getter formTarget
-    getter height
-    getter incremental
-    getter indeterminate
-    getter labels
-    getter list
-    getter max
-    getter maxLength
-    getter min
-    getter minLength
-    getter multiple
-    getter name
-    getter pattern
-    getter placeholder
-    getter readOnly
-    getter required
-    getter selectionDirection
-    getter selectionEnd
-    getter selectionStart
-    getter size
-    getter src
-    getter step
-    getter type
-    getter useMap
-    getter validationMessage
-    getter validity
-    getter value
-    getter valueAsDate
-    getter valueAsNumber
-    getter webkitEntries
-    getter webkitdirectory
-    getter width
-    getter willValidate
-    method checkValidity
-    method constructor
-    method reportValidity
-    method select
-    method setCustomValidity
-    method setRangeText
-    method setSelectionRange
-    method stepDown
-    method stepUp
-    setter accept
-    setter align
-    setter alt
-    setter autocomplete
-    setter checked
-    setter defaultChecked
-    setter defaultValue
-    setter dirName
-    setter disabled
-    setter files
-    setter formAction
-    setter formEnctype
-    setter formMethod
-    setter formNoValidate
-    setter formTarget
-    setter height
-    setter incremental
-    setter indeterminate
-    setter max
-    setter maxLength
-    setter min
-    setter minLength
-    setter multiple
-    setter name
-    setter pattern
-    setter placeholder
-    setter readOnly
-    setter required
-    setter selectionDirection
-    setter selectionEnd
-    setter selectionStart
-    setter size
-    setter src
-    setter step
-    setter type
-    setter useMap
-    setter value
-    setter valueAsDate
-    setter valueAsNumber
-    setter webkitdirectory
-    setter width
-interface HTMLLIElement : HTMLElement
-    attribute @@toStringTag
-    getter type
-    getter value
-    method constructor
-    setter type
-    setter value
-interface HTMLLabelElement : HTMLElement
-    attribute @@toStringTag
-    getter control
-    getter form
-    getter htmlFor
-    method constructor
-    setter htmlFor
-interface HTMLLegendElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter form
-    method constructor
-    setter align
-interface HTMLLinkElement : HTMLElement
-    attribute @@toStringTag
-    getter as
-    getter charset
-    getter crossOrigin
-    getter disabled
-    getter href
-    getter hreflang
-    getter imageSizes
-    getter imageSrcset
-    getter importance
-    getter integrity
-    getter media
-    getter referrerPolicy
-    getter rel
-    getter relList
-    getter resources
-    getter rev
-    getter scopes
-    getter sheet
-    getter sizes
-    getter target
-    getter type
-    method constructor
-    setter as
-    setter charset
-    setter crossOrigin
-    setter disabled
-    setter href
-    setter hreflang
-    setter imageSizes
-    setter imageSrcset
-    setter importance
-    setter integrity
-    setter media
-    setter referrerPolicy
-    setter rel
-    setter relList
-    setter resources
-    setter rev
-    setter scopes
-    setter sizes
-    setter target
-    setter type
-interface HTMLMapElement : HTMLElement
-    attribute @@toStringTag
-    getter areas
-    getter name
-    method constructor
-    setter name
-interface HTMLMarqueeElement : HTMLElement
-    attribute @@toStringTag
-    getter behavior
-    getter bgColor
-    getter direction
-    getter height
-    getter hspace
-    getter loop
-    getter scrollAmount
-    getter scrollDelay
-    getter trueSpeed
-    getter vspace
-    getter width
-    method constructor
-    method start
-    method stop
-    setter behavior
-    setter bgColor
-    setter direction
-    setter height
-    setter hspace
-    setter loop
-    setter scrollAmount
-    setter scrollDelay
-    setter trueSpeed
-    setter vspace
-    setter width
-interface HTMLMediaElement : HTMLElement
-    attribute @@toStringTag
-    attribute HAVE_CURRENT_DATA
-    attribute HAVE_ENOUGH_DATA
-    attribute HAVE_FUTURE_DATA
-    attribute HAVE_METADATA
-    attribute HAVE_NOTHING
-    attribute NETWORK_EMPTY
-    attribute NETWORK_IDLE
-    attribute NETWORK_LOADING
-    attribute NETWORK_NO_SOURCE
-    getter audioTracks
-    getter autoplay
-    getter buffered
-    getter controls
-    getter controlsList
-    getter crossOrigin
-    getter currentSrc
-    getter currentTime
-    getter defaultMuted
-    getter defaultPlaybackRate
-    getter disableRemotePlayback
-    getter duration
-    getter ended
-    getter error
-    getter latencyHint
-    getter loop
-    getter mediaKeys
-    getter muted
-    getter networkState
-    getter onencrypted
-    getter onwaitingforkey
-    getter paused
-    getter playbackRate
-    getter played
-    getter preload
-    getter preservesPitch
-    getter readyState
-    getter remote
-    getter seekable
-    getter seeking
-    getter sinkId
-    getter src
-    getter srcObject
-    getter textTracks
-    getter videoTracks
-    getter volume
-    getter webkitAudioDecodedByteCount
-    getter webkitVideoDecodedByteCount
-    method addTextTrack
-    method canPlayType
-    method captureStream
-    method constructor
-    method load
-    method pause
-    method play
-    method setMediaKeys
-    method setSinkId
-    setter autoplay
-    setter controls
-    setter controlsList
-    setter crossOrigin
-    setter currentTime
-    setter defaultMuted
-    setter defaultPlaybackRate
-    setter disableRemotePlayback
-    setter latencyHint
-    setter loop
-    setter muted
-    setter onencrypted
-    setter onwaitingforkey
-    setter playbackRate
-    setter preload
-    setter preservesPitch
-    setter src
-    setter srcObject
-    setter volume
-interface HTMLMenuElement : HTMLElement
-    attribute @@toStringTag
-    getter compact
-    method constructor
-    setter compact
-interface HTMLMetaElement : HTMLElement
-    attribute @@toStringTag
-    getter content
-    getter httpEquiv
-    getter media
-    getter name
-    getter scheme
-    method constructor
-    setter content
-    setter httpEquiv
-    setter media
-    setter name
-    setter scheme
-interface HTMLMeterElement : HTMLElement
-    attribute @@toStringTag
-    getter high
-    getter labels
-    getter low
-    getter max
-    getter min
-    getter optimum
-    getter value
-    method constructor
-    setter high
-    setter low
-    setter max
-    setter min
-    setter optimum
-    setter value
-interface HTMLModElement : HTMLElement
-    attribute @@toStringTag
-    getter cite
-    getter dateTime
-    method constructor
-    setter cite
-    setter dateTime
-interface HTMLOListElement : HTMLElement
-    attribute @@toStringTag
-    getter compact
-    getter reversed
-    getter start
-    getter type
-    method constructor
-    setter compact
-    setter reversed
-    setter start
-    setter type
-interface HTMLObjectElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter archive
-    getter border
-    getter code
-    getter codeBase
-    getter codeType
-    getter contentDocument
-    getter contentWindow
-    getter data
-    getter declare
-    getter form
-    getter height
-    getter hspace
-    getter name
-    getter standby
-    getter type
-    getter useMap
-    getter validationMessage
-    getter validity
-    getter vspace
-    getter width
-    getter willValidate
-    method checkValidity
-    method constructor
-    method getSVGDocument
-    method reportValidity
-    method setCustomValidity
-    setter align
-    setter archive
-    setter border
-    setter code
-    setter codeBase
-    setter codeType
-    setter data
-    setter declare
-    setter height
-    setter hspace
-    setter name
-    setter standby
-    setter type
-    setter useMap
-    setter vspace
-    setter width
-interface HTMLOptGroupElement : HTMLElement
-    attribute @@toStringTag
-    getter disabled
-    getter label
-    method constructor
-    setter disabled
-    setter label
-interface HTMLOptionElement : HTMLElement
-    attribute @@toStringTag
-    getter defaultSelected
-    getter disabled
-    getter form
-    getter index
-    getter label
-    getter selected
-    getter text
-    getter value
-    method constructor
-    setter defaultSelected
-    setter disabled
-    setter label
-    setter selected
-    setter text
-    setter value
-interface HTMLOptionsCollection : HTMLCollection
-    attribute @@toStringTag
-    getter length
-    getter selectedIndex
-    method @@iterator
-    method add
-    method constructor
-    method remove
-    setter length
-    setter selectedIndex
-interface HTMLOutputElement : HTMLElement
-    attribute @@toStringTag
-    getter defaultValue
-    getter form
-    getter htmlFor
-    getter labels
-    getter name
-    getter type
-    getter validationMessage
-    getter validity
-    getter value
-    getter willValidate
-    method checkValidity
-    method constructor
-    method reportValidity
-    method setCustomValidity
-    setter defaultValue
-    setter htmlFor
-    setter name
-    setter value
-interface HTMLParagraphElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    method constructor
-    setter align
-interface HTMLParamElement : HTMLElement
-    attribute @@toStringTag
-    getter name
-    getter type
-    getter value
-    getter valueType
-    method constructor
-    setter name
-    setter type
-    setter value
-    setter valueType
-interface HTMLPictureElement : HTMLElement
-    attribute @@toStringTag
-    method constructor
-interface HTMLPopupElement : HTMLElement
-    attribute @@toStringTag
-    getter anchor
-    getter initiallyOpen
-    getter open
-    method constructor
-    method hide
-    method show
-    setter initiallyOpen
-interface HTMLPreElement : HTMLElement
-    attribute @@toStringTag
-    getter width
-    method constructor
-    setter width
-interface HTMLProgressElement : HTMLElement
-    attribute @@toStringTag
-    getter labels
-    getter max
-    getter position
-    getter value
-    method constructor
-    setter max
-    setter value
-interface HTMLQuoteElement : HTMLElement
-    attribute @@toStringTag
-    getter cite
-    method constructor
-    setter cite
-interface HTMLScriptElement : HTMLElement
-    attribute @@toStringTag
-    getter async
-    getter charset
-    getter crossOrigin
-    getter defer
-    getter event
-    getter htmlFor
-    getter importance
-    getter integrity
-    getter noModule
-    getter referrerPolicy
-    getter src
-    getter text
-    getter type
-    method constructor
-    setter async
-    setter charset
-    setter crossOrigin
-    setter defer
-    setter event
-    setter htmlFor
-    setter importance
-    setter integrity
-    setter noModule
-    setter referrerPolicy
-    setter src
-    setter text
-    setter type
-interface HTMLSelectElement : HTMLElement
-    attribute @@toStringTag
-    getter autocomplete
-    getter disabled
-    getter form
-    getter labels
-    getter length
-    getter multiple
-    getter name
-    getter options
-    getter required
-    getter selectedIndex
-    getter selectedOptions
-    getter size
-    getter type
-    getter validationMessage
-    getter validity
-    getter value
-    getter willValidate
-    method @@iterator
-    method add
-    method checkValidity
-    method constructor
-    method item
-    method namedItem
-    method remove
-    method reportValidity
-    method setCustomValidity
-    setter autocomplete
-    setter disabled
-    setter length
-    setter multiple
-    setter name
-    setter required
-    setter selectedIndex
-    setter size
-    setter value
-interface HTMLSelectMenuElement : HTMLElement
-    attribute @@toStringTag
-    getter open
-    getter value
-    method constructor
-    setter value
-interface HTMLSlotElement : HTMLElement
-    attribute @@toStringTag
-    getter name
-    method assign
-    method assignedElements
-    method assignedNodes
-    method constructor
-    setter name
-interface HTMLSourceElement : HTMLElement
-    attribute @@toStringTag
-    getter height
-    getter media
-    getter sizes
-    getter src
-    getter srcset
-    getter type
-    getter width
-    method constructor
-    setter height
-    setter media
-    setter sizes
-    setter src
-    setter srcset
-    setter type
-    setter width
-interface HTMLSpanElement : HTMLElement
-    attribute @@toStringTag
-    method constructor
-interface HTMLStyleElement : HTMLElement
-    attribute @@toStringTag
-    getter disabled
-    getter media
-    getter sheet
-    getter type
-    method constructor
-    setter disabled
-    setter media
-    setter type
-interface HTMLTableCaptionElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    method constructor
-    setter align
-interface HTMLTableCellElement : HTMLElement
-    attribute @@toStringTag
-    getter abbr
-    getter align
-    getter axis
-    getter bgColor
-    getter cellIndex
-    getter ch
-    getter chOff
-    getter colSpan
-    getter headers
-    getter height
-    getter noWrap
-    getter rowSpan
-    getter scope
-    getter vAlign
-    getter width
-    method constructor
-    setter abbr
-    setter align
-    setter axis
-    setter bgColor
-    setter ch
-    setter chOff
-    setter colSpan
-    setter headers
-    setter height
-    setter noWrap
-    setter rowSpan
-    setter scope
-    setter vAlign
-    setter width
-interface HTMLTableColElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter ch
-    getter chOff
-    getter span
-    getter vAlign
-    getter width
-    method constructor
-    setter align
-    setter ch
-    setter chOff
-    setter span
-    setter vAlign
-    setter width
-interface HTMLTableElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter bgColor
-    getter border
-    getter caption
-    getter cellPadding
-    getter cellSpacing
-    getter frame
-    getter rows
-    getter rules
-    getter summary
-    getter tBodies
-    getter tFoot
-    getter tHead
-    getter width
-    method constructor
-    method createCaption
-    method createTBody
-    method createTFoot
-    method createTHead
-    method deleteCaption
-    method deleteRow
-    method deleteTFoot
-    method deleteTHead
-    method insertRow
-    setter align
-    setter bgColor
-    setter border
-    setter caption
-    setter cellPadding
-    setter cellSpacing
-    setter frame
-    setter rules
-    setter summary
-    setter tFoot
-    setter tHead
-    setter width
-interface HTMLTableRowElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter bgColor
-    getter cells
-    getter ch
-    getter chOff
-    getter rowIndex
-    getter sectionRowIndex
-    getter vAlign
-    method constructor
-    method deleteCell
-    method insertCell
-    setter align
-    setter bgColor
-    setter ch
-    setter chOff
-    setter vAlign
-interface HTMLTableSectionElement : HTMLElement
-    attribute @@toStringTag
-    getter align
-    getter ch
-    getter chOff
-    getter rows
-    getter vAlign
-    method constructor
-    method deleteRow
-    method insertRow
-    setter align
-    setter ch
-    setter chOff
-    setter vAlign
-interface HTMLTemplateElement : HTMLElement
-    attribute @@toStringTag
-    getter content
-    getter shadowRoot
-    method constructor
-interface HTMLTextAreaElement : HTMLElement
-    attribute @@toStringTag
-    getter autocomplete
-    getter cols
-    getter defaultValue
-    getter dirName
-    getter disabled
-    getter form
-    getter labels
-    getter maxLength
-    getter minLength
-    getter name
-    getter placeholder
-    getter readOnly
-    getter required
-    getter rows
-    getter selectionDirection
-    getter selectionEnd
-    getter selectionStart
-    getter textLength
-    getter type
-    getter validationMessage
-    getter validity
-    getter value
-    getter willValidate
-    getter wrap
-    method checkValidity
-    method constructor
-    method reportValidity
-    method select
-    method setCustomValidity
-    method setRangeText
-    method setSelectionRange
-    setter autocomplete
-    setter cols
-    setter defaultValue
-    setter dirName
-    setter disabled
-    setter maxLength
-    setter minLength
-    setter name
-    setter placeholder
-    setter readOnly
-    setter required
-    setter rows
-    setter selectionDirection
-    setter selectionEnd
-    setter selectionStart
-    setter value
-    setter wrap
-interface HTMLTimeElement : HTMLElement
-    attribute @@toStringTag
-    getter dateTime
-    method constructor
-    setter dateTime
-interface HTMLTitleElement : HTMLElement
-    attribute @@toStringTag
-    getter text
-    method constructor
-    setter text
-interface HTMLTrackElement : HTMLElement
-    attribute @@toStringTag
-    attribute ERROR
-    attribute LOADED
-    attribute LOADING
-    attribute NONE
-    getter default
-    getter kind
-    getter label
-    getter readyState
-    getter src
-    getter srclang
-    getter track
-    method constructor
-    setter default
-    setter kind
-    setter label
-    setter src
-    setter srclang
-interface HTMLUListElement : HTMLElement
-    attribute @@toStringTag
-    getter compact
-    getter type
-    method constructor
-    setter compact
-    setter type
-interface HTMLUnknownElement : HTMLElement
-    attribute @@toStringTag
-    method constructor
-interface HTMLVideoElement : HTMLMediaElement
-    attribute @@toStringTag
-    getter autoPictureInPicture
-    getter disablePictureInPicture
-    getter height
-    getter onenterpictureinpicture
-    getter onleavepictureinpicture
-    getter playsInline
-    getter poster
-    getter videoHeight
-    getter videoWidth
-    getter webkitDecodedFrameCount
-    getter webkitDisplayingFullscreen
-    getter webkitDroppedFrameCount
-    getter webkitSupportsFullscreen
-    getter width
-    method cancelVideoFrameCallback
-    method constructor
-    method getVideoPlaybackQuality
-    method requestPictureInPicture
-    method requestVideoFrameCallback
-    method webkitEnterFullScreen
-    method webkitEnterFullscreen
-    method webkitExitFullScreen
-    method webkitExitFullscreen
-    setter autoPictureInPicture
-    setter disablePictureInPicture
-    setter height
-    setter onenterpictureinpicture
-    setter onleavepictureinpicture
-    setter playsInline
-    setter poster
-    setter width
-interface HandwritingStroke
-    attribute @@toStringTag
-    method addPoint
-    method clear
-    method constructor
-    method getPoints
-interface HashChangeEvent : Event
-    attribute @@toStringTag
-    getter newURL
-    getter oldURL
-    method constructor
-interface Headers
-    attribute @@toStringTag
-    method @@iterator
-    method append
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method set
-    method values
-interface Highlight
-    attribute @@toStringTag
-    getter priority
-    getter size
-    method @@iterator
-    method add
-    method clear
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method has
-    method keys
-    method values
-    setter priority
-interface HighlightRegistry
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method clear
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method set
-    method values
-interface History
-    attribute @@toStringTag
-    getter length
-    getter scrollRestoration
-    getter state
-    method back
-    method constructor
-    method forward
-    method go
-    method pushState
-    method replaceState
-    setter scrollRestoration
-interface IDBCursor
-    attribute @@toStringTag
-    getter direction
-    getter key
-    getter primaryKey
-    getter request
-    getter source
-    method advance
-    method constructor
-    method continue
-    method continuePrimaryKey
-    method delete
-    method update
-interface IDBCursorWithValue : IDBCursor
-    attribute @@toStringTag
-    getter value
-    method constructor
-interface IDBDatabase : EventTarget
-    attribute @@toStringTag
-    getter name
-    getter objectStoreNames
-    getter onabort
-    getter onclose
-    getter onerror
-    getter onversionchange
-    getter version
-    method close
-    method constructor
-    method createObjectStore
-    method deleteObjectStore
-    method transaction
-    setter onabort
-    setter onclose
-    setter onerror
-    setter onversionchange
-interface IDBFactory
-    attribute @@toStringTag
-    method cmp
-    method constructor
-    method databases
-    method deleteDatabase
-    method open
-interface IDBIndex
-    attribute @@toStringTag
-    getter keyPath
-    getter multiEntry
-    getter name
-    getter objectStore
-    getter unique
-    method constructor
-    method count
-    method get
-    method getAll
-    method getAllKeys
-    method getKey
-    method openCursor
-    method openKeyCursor
-    setter name
-interface IDBKeyRange
-    static method bound
-    static method lowerBound
-    static method only
-    static method upperBound
-    attribute @@toStringTag
-    getter lower
-    getter lowerOpen
-    getter upper
-    getter upperOpen
-    method constructor
-    method includes
-interface IDBObjectStore
-    attribute @@toStringTag
-    getter autoIncrement
-    getter indexNames
-    getter keyPath
-    getter name
-    getter transaction
-    method add
-    method clear
-    method constructor
-    method count
-    method createIndex
-    method delete
-    method deleteIndex
-    method get
-    method getAll
-    method getAllKeys
-    method getKey
-    method index
-    method openCursor
-    method openKeyCursor
-    method put
-    method putAllValues
-    setter name
-interface IDBOpenDBRequest : IDBRequest
-    attribute @@toStringTag
-    getter onblocked
-    getter onupgradeneeded
-    method constructor
-    setter onblocked
-    setter onupgradeneeded
-interface IDBRequest : EventTarget
-    attribute @@toStringTag
-    getter error
-    getter onerror
-    getter onsuccess
-    getter readyState
-    getter result
-    getter source
-    getter transaction
-    method constructor
-    setter onerror
-    setter onsuccess
-interface IDBTransaction : EventTarget
-    attribute @@toStringTag
-    getter db
-    getter durability
-    getter error
-    getter mode
-    getter objectStoreNames
-    getter onabort
-    getter oncomplete
-    getter onerror
-    method abort
-    method commit
-    method constructor
-    method objectStore
-    setter onabort
-    setter oncomplete
-    setter onerror
-interface IDBVersionChangeEvent : Event
-    attribute @@toStringTag
-    getter dataLoss
-    getter dataLossMessage
-    getter newVersion
-    getter oldVersion
-    method constructor
-interface IIRFilterNode : AudioNode
-    attribute @@toStringTag
-    method constructor
-    method getFrequencyResponse
-interface IdleDeadline
-    attribute @@toStringTag
-    getter didTimeout
-    method constructor
-    method timeRemaining
-interface IdleDetector : EventTarget
-    static method requestPermission
-    attribute @@toStringTag
-    getter onchange
-    getter screenState
-    getter userState
-    method constructor
-    method start
-    setter onchange
-interface Image
-    attribute @@toStringTag
-    getter align
-    getter alt
-    getter border
-    getter complete
-    getter crossOrigin
-    getter currentSrc
-    getter decoding
-    getter height
-    getter hspace
-    getter importance
-    getter isMap
-    getter loading
-    getter longDesc
-    getter lowsrc
-    getter name
-    getter naturalHeight
-    getter naturalWidth
-    getter referrerPolicy
-    getter sizes
-    getter src
-    getter srcset
-    getter useMap
-    getter vspace
-    getter width
-    getter x
-    getter y
-    method constructor
-    method decode
-    setter align
-    setter alt
-    setter border
-    setter crossOrigin
-    setter decoding
-    setter height
-    setter hspace
-    setter importance
-    setter isMap
-    setter loading
-    setter longDesc
-    setter lowsrc
-    setter name
-    setter referrerPolicy
-    setter sizes
-    setter src
-    setter srcset
-    setter useMap
-    setter vspace
-    setter width
-interface ImageBitmap
-    attribute @@toStringTag
-    getter height
-    getter width
-    method close
-    method constructor
-interface ImageBitmapRenderingContext
-    attribute @@toStringTag
-    getter canvas
-    method constructor
-    method transferFromImageBitmap
-interface ImageCapture
-    attribute @@toStringTag
-    getter track
-    method constructor
-    method getPhotoCapabilities
-    method getPhotoSettings
-    method grabFrame
-    method takePhoto
-interface ImageData
-    attribute @@toStringTag
-    getter colorSpace
-    getter data
-    getter height
-    getter storageFormat
-    getter width
-    method constructor
-    method getSettings
-interface ImageDecoder
-    static method isTypeSupported
-    attribute @@toStringTag
-    getter complete
-    getter completed
-    getter tracks
-    getter type
-    method close
-    method constructor
-    method decode
-    method reset
-interface ImageTrack
-    attribute @@toStringTag
-    getter animated
-    getter frameCount
-    getter repetitionCount
-    getter selected
-    method constructor
-    setter selected
-interface ImageTrackList
-    attribute @@toStringTag
-    getter length
-    getter ready
-    getter selectedIndex
-    getter selectedTrack
-    method @@iterator
-    method constructor
-interface Ink
-    attribute @@toStringTag
-    method constructor
-    method requestPresenter
-interface InputDeviceCapabilities
-    attribute @@toStringTag
-    getter firesTouchEvents
-    method constructor
-interface InputDeviceInfo : MediaDeviceInfo
-    attribute @@toStringTag
-    method constructor
-    method getCapabilities
-interface InputEvent : UIEvent
-    attribute @@toStringTag
-    getter data
-    getter dataTransfer
-    getter inputType
-    getter isComposing
-    method constructor
-    method getTargetRanges
-interface IntersectionObserver
-    attribute @@toStringTag
-    getter delay
-    getter root
-    getter rootMargin
-    getter thresholds
-    getter trackVisibility
-    method constructor
-    method disconnect
-    method observe
-    method takeRecords
-    method unobserve
-interface IntersectionObserverEntry
-    attribute @@toStringTag
-    getter boundingClientRect
-    getter intersectionRatio
-    getter intersectionRect
-    getter isIntersecting
-    getter isVisible
-    getter rootBounds
-    getter target
-    getter time
-    method constructor
-interface Keyboard
-    attribute @@toStringTag
-    method constructor
-    method getLayoutMap
-    method lock
-    method unlock
-interface KeyboardEvent : UIEvent
-    attribute @@toStringTag
-    attribute DOM_KEY_LOCATION_LEFT
-    attribute DOM_KEY_LOCATION_NUMPAD
-    attribute DOM_KEY_LOCATION_RIGHT
-    attribute DOM_KEY_LOCATION_STANDARD
-    getter altKey
-    getter charCode
-    getter code
-    getter ctrlKey
-    getter isComposing
-    getter key
-    getter keyCode
-    getter location
-    getter metaKey
-    getter repeat
-    getter shiftKey
-    method constructor
-    method getModifierState
-    method initKeyboardEvent
-interface KeyboardLayoutMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface KeyframeEffect : AnimationEffect
-    attribute @@toStringTag
-    getter composite
-    getter pseudoElement
-    getter target
-    method constructor
-    method getKeyframes
-    method setKeyframes
-    setter composite
-    setter pseudoElement
-    setter target
-interface LargestContentfulPaint : PerformanceEntry
-    attribute @@toStringTag
-    getter element
-    getter id
-    getter loadTime
-    getter renderTime
-    getter size
-    getter url
-    method constructor
-    method toJSON
-interface LaunchParams
-    attribute @@toStringTag
-    getter files
-    method constructor
-interface LaunchQueue
-    attribute @@toStringTag
-    method constructor
-    method setConsumer
-interface LayoutShift : PerformanceEntry
-    attribute @@toStringTag
-    getter hadRecentInput
-    getter lastInputTime
-    getter sources
-    getter value
-    method constructor
-    method toJSON
-interface LayoutShiftAttribution
-    attribute @@toStringTag
-    getter currentRect
-    getter node
-    getter previousRect
-    method constructor
-    method toJSON
-interface LinearAccelerationSensor : Accelerometer
-    attribute @@toStringTag
-    method constructor
-interface Location
-    attribute @@toStringTag
-    method constructor
-interface Lock
-    attribute @@toStringTag
-    getter mode
-    getter name
-    method constructor
-interface LockManager
-    attribute @@toStringTag
-    method constructor
-    method query
-    method request
-interface MIDIAccess : EventTarget
-    attribute @@toStringTag
-    getter inputs
-    getter onstatechange
-    getter outputs
-    getter sysexEnabled
-    method constructor
-    setter onstatechange
-interface MIDIConnectionEvent : Event
-    attribute @@toStringTag
-    getter port
-    method constructor
-interface MIDIInput : MIDIPort
-    attribute @@toStringTag
-    getter onmidimessage
-    method constructor
-    setter onmidimessage
-interface MIDIInputMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface MIDIMessageEvent : Event
-    attribute @@toStringTag
-    getter data
-    method constructor
-interface MIDIOutput : MIDIPort
-    attribute @@toStringTag
-    method constructor
-    method send
-interface MIDIOutputMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface MIDIPort : EventTarget
-    attribute @@toStringTag
-    getter connection
-    getter id
-    getter manufacturer
-    getter name
-    getter onstatechange
-    getter state
-    getter type
-    getter version
-    method close
-    method constructor
-    method open
-    setter onstatechange
-interface Magnetometer : Sensor
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-interface MathMLElement : Element
-    attribute @@toStringTag
-    getter autofocus
-    getter dataset
-    getter nonce
-    getter onabort
-    getter onanimationend
-    getter onanimationiteration
-    getter onanimationstart
-    getter onauxclick
-    getter onbeforexrselect
-    getter onblur
-    getter oncancel
-    getter oncanplay
-    getter oncanplaythrough
-    getter onchange
-    getter onclick
-    getter onclose
-    getter oncontextmenu
-    getter oncopy
-    getter oncuechange
-    getter oncut
-    getter ondblclick
-    getter ondrag
-    getter ondragend
-    getter ondragenter
-    getter ondragleave
-    getter ondragover
-    getter ondragstart
-    getter ondrop
-    getter ondurationchange
-    getter onemptied
-    getter onended
-    getter onerror
-    getter onfocus
-    getter onformdata
-    getter ongotpointercapture
-    getter oninput
-    getter oninvalid
-    getter onkeydown
-    getter onkeypress
-    getter onkeyup
-    getter onload
-    getter onloadeddata
-    getter onloadedmetadata
-    getter onloadstart
-    getter onlostpointercapture
-    getter onmousedown
-    getter onmouseenter
-    getter onmouseleave
-    getter onmousemove
-    getter onmouseout
-    getter onmouseover
-    getter onmouseup
-    getter onmousewheel
-    getter onoverscroll
-    getter onpaste
-    getter onpause
-    getter onplay
-    getter onplaying
-    getter onpointercancel
-    getter onpointerdown
-    getter onpointerenter
-    getter onpointerleave
-    getter onpointermove
-    getter onpointerout
-    getter onpointerover
-    getter onpointerrawupdate
-    getter onpointerup
-    getter onprogress
-    getter onratechange
-    getter onreset
-    getter onresize
-    getter onscroll
-    getter onscrollend
-    getter onseeked
-    getter onseeking
-    getter onselect
-    getter onselectionchange
-    getter onselectstart
-    getter onstalled
-    getter onsubmit
-    getter onsuspend
-    getter ontimeupdate
-    getter ontoggle
-    getter ontouchcancel
-    getter ontouchend
-    getter ontouchmove
-    getter ontouchstart
-    getter ontransitioncancel
-    getter ontransitionend
-    getter ontransitionrun
-    getter ontransitionstart
-    getter onvolumechange
-    getter onwaiting
-    getter onwebkitanimationend
-    getter onwebkitanimationiteration
-    getter onwebkitanimationstart
-    getter onwebkittransitionend
-    getter onwheel
-    getter style
-    getter tabIndex
-    method blur
-    method constructor
-    method focus
-    setter autofocus
-    setter nonce
-    setter onabort
-    setter onanimationend
-    setter onanimationiteration
-    setter onanimationstart
-    setter onauxclick
-    setter onbeforexrselect
-    setter onblur
-    setter oncancel
-    setter oncanplay
-    setter oncanplaythrough
-    setter onchange
-    setter onclick
-    setter onclose
-    setter oncontextmenu
-    setter oncopy
-    setter oncuechange
-    setter oncut
-    setter ondblclick
-    setter ondrag
-    setter ondragend
-    setter ondragenter
-    setter ondragleave
-    setter ondragover
-    setter ondragstart
-    setter ondrop
-    setter ondurationchange
-    setter onemptied
-    setter onended
-    setter onerror
-    setter onfocus
-    setter onformdata
-    setter ongotpointercapture
-    setter oninput
-    setter oninvalid
-    setter onkeydown
-    setter onkeypress
-    setter onkeyup
-    setter onload
-    setter onloadeddata
-    setter onloadedmetadata
-    setter onloadstart
-    setter onlostpointercapture
-    setter onmousedown
-    setter onmouseenter
-    setter onmouseleave
-    setter onmousemove
-    setter onmouseout
-    setter onmouseover
-    setter onmouseup
-    setter onmousewheel
-    setter onoverscroll
-    setter onpaste
-    setter onpause
-    setter onplay
-    setter onplaying
-    setter onpointercancel
-    setter onpointerdown
-    setter onpointerenter
-    setter onpointerleave
-    setter onpointermove
-    setter onpointerout
-    setter onpointerover
-    setter onpointerrawupdate
-    setter onpointerup
-    setter onprogress
-    setter onratechange
-    setter onreset
-    setter onresize
-    setter onscroll
-    setter onscrollend
-    setter onseeked
-    setter onseeking
-    setter onselect
-    setter onselectionchange
-    setter onselectstart
-    setter onstalled
-    setter onsubmit
-    setter onsuspend
-    setter ontimeupdate
-    setter ontoggle
-    setter ontouchcancel
-    setter ontouchend
-    setter ontouchmove
-    setter ontouchstart
-    setter ontransitioncancel
-    setter ontransitionend
-    setter ontransitionrun
-    setter ontransitionstart
-    setter onvolumechange
-    setter onwaiting
-    setter onwebkitanimationend
-    setter onwebkitanimationiteration
-    setter onwebkitanimationstart
-    setter onwebkittransitionend
-    setter onwheel
-    setter style
-    setter tabIndex
-interface MediaCapabilities
-    attribute @@toStringTag
-    method constructor
-    method decodingInfo
-    method encodingInfo
-interface MediaDeviceInfo
-    attribute @@toStringTag
-    getter deviceId
-    getter groupId
-    getter kind
-    getter label
-    method constructor
-    method toJSON
-interface MediaDevices : EventTarget
-    attribute @@toStringTag
-    getter ondevicechange
-    method constructor
-    method enumerateDevices
-    method getCurrentBrowsingContextMedia
-    method getDisplayMedia
-    method getSupportedConstraints
-    method getUserMedia
-    method setCaptureHandleConfig
-    setter ondevicechange
-interface MediaElementAudioSourceNode : AudioNode
-    attribute @@toStringTag
-    getter mediaElement
-    method constructor
-interface MediaEncryptedEvent : Event
-    attribute @@toStringTag
-    getter initData
-    getter initDataType
-    method constructor
-interface MediaError
-    attribute @@toStringTag
-    attribute MEDIA_ERR_ABORTED
-    attribute MEDIA_ERR_DECODE
-    attribute MEDIA_ERR_NETWORK
-    attribute MEDIA_ERR_SRC_NOT_SUPPORTED
-    getter code
-    getter message
-    method constructor
-interface MediaKeyMessageEvent : Event
-    attribute @@toStringTag
-    getter message
-    getter messageType
-    method constructor
-interface MediaKeySession : EventTarget
-    attribute @@toStringTag
-    getter closed
-    getter expiration
-    getter keyStatuses
-    getter onkeystatuseschange
-    getter onmessage
-    getter sessionId
-    method close
-    method constructor
-    method generateRequest
-    method load
-    method remove
-    method update
-    setter onkeystatuseschange
-    setter onmessage
-interface MediaKeyStatusMap
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface MediaKeySystemAccess
-    attribute @@toStringTag
-    getter keySystem
-    method constructor
-    method createMediaKeys
-    method getConfiguration
-interface MediaKeys
-    attribute @@toStringTag
-    method constructor
-    method createSession
-    method getStatusForPolicy
-    method setServerCertificate
-interface MediaList
-    attribute @@toStringTag
-    getter length
-    getter mediaText
-    method @@iterator
-    method appendMedium
-    method constructor
-    method deleteMedium
-    method item
-    method toString
-    setter mediaText
-interface MediaMetadata
-    attribute @@toStringTag
-    getter album
-    getter artist
-    getter artwork
-    getter title
-    method constructor
-    setter album
-    setter artist
-    setter artwork
-    setter title
-interface MediaQueryList : EventTarget
-    attribute @@toStringTag
-    getter matches
-    getter media
-    getter onchange
-    method addListener
-    method constructor
-    method removeListener
-    setter onchange
-interface MediaQueryListEvent : Event
-    attribute @@toStringTag
-    getter matches
-    getter media
-    method constructor
-interface MediaRecorder : EventTarget
-    static method isTypeSupported
-    attribute @@toStringTag
-    getter audioBitrateMode
-    getter audioBitsPerSecond
-    getter mimeType
-    getter ondataavailable
-    getter onerror
-    getter onpause
-    getter onresume
-    getter onstart
-    getter onstop
-    getter state
-    getter stream
-    getter videoBitsPerSecond
-    method constructor
-    method pause
-    method requestData
-    method resume
-    method start
-    method stop
-    setter ondataavailable
-    setter onerror
-    setter onpause
-    setter onresume
-    setter onstart
-    setter onstop
-interface MediaSession
-    attribute @@toStringTag
-    getter metadata
-    getter playbackState
-    method constructor
-    method setActionHandler
-    method setCameraActive
-    method setMicrophoneActive
-    method setPositionState
-    setter metadata
-    setter playbackState
-interface MediaSource : EventTarget
-    static getter canConstructInDedicatedWorker
-    static method isTypeSupported
-    attribute @@toStringTag
-    getter activeSourceBuffers
-    getter duration
-    getter onsourceclose
-    getter onsourceended
-    getter onsourceopen
-    getter readyState
-    getter sourceBuffers
-    method addSourceBuffer
-    method clearLiveSeekableRange
-    method constructor
-    method endOfStream
-    method removeSourceBuffer
-    method setLiveSeekableRange
-    setter duration
-    setter onsourceclose
-    setter onsourceended
-    setter onsourceopen
-interface MediaStream : EventTarget
-    attribute @@toStringTag
-    getter active
-    getter id
-    getter onactive
-    getter onaddtrack
-    getter oninactive
-    getter onremovetrack
-    method addTrack
-    method clone
-    method constructor
-    method getAudioTracks
-    method getTrackById
-    method getTracks
-    method getVideoTracks
-    method removeTrack
-    setter onactive
-    setter onaddtrack
-    setter oninactive
-    setter onremovetrack
-interface MediaStreamAudioDestinationNode : AudioNode
-    attribute @@toStringTag
-    getter stream
-    method constructor
-interface MediaStreamAudioSourceNode : AudioNode
-    attribute @@toStringTag
-    getter mediaStream
-    method constructor
-interface MediaStreamEvent : Event
-    attribute @@toStringTag
-    getter stream
-    method constructor
-interface MediaStreamTrack : EventTarget
-    attribute @@toStringTag
-    getter contentHint
-    getter enabled
-    getter id
-    getter kind
-    getter label
-    getter muted
-    getter oncapturehandlechange
-    getter onended
-    getter onmute
-    getter onunmute
-    getter readyState
-    method applyConstraints
-    method clone
-    method constructor
-    method getCapabilities
-    method getCaptureHandle
-    method getConstraints
-    method getSettings
-    method stop
-    setter contentHint
-    setter enabled
-    setter oncapturehandlechange
-    setter onended
-    setter onmute
-    setter onunmute
-interface MediaStreamTrackEvent : Event
-    attribute @@toStringTag
-    getter track
-    method constructor
-interface MediaStreamTrackGenerator : MediaStreamTrack
-    attribute @@toStringTag
-    getter readableControl
-    getter writable
-    method constructor
-interface MediaStreamTrackProcessor
-    attribute @@toStringTag
-    getter readable
-    getter writableControl
-    method constructor
-interface MerchantValidationEvent : Event
-    attribute @@toStringTag
-    getter methodName
-    getter validationURL
-    method complete
-    method constructor
-interface MessageChannel
-    attribute @@toStringTag
-    getter port1
-    getter port2
-    method constructor
-interface MessageEvent : Event
-    attribute @@toStringTag
-    getter data
-    getter lastEventId
-    getter origin
-    getter ports
-    getter source
-    getter userActivation
-    method constructor
-    method initMessageEvent
-interface MessagePort : EventTarget
-    attribute @@toStringTag
-    getter onmessage
-    getter onmessageerror
-    method close
-    method constructor
-    method postMessage
-    method start
-    setter onmessage
-    setter onmessageerror
-interface MimeType
-    attribute @@toStringTag
-    getter description
-    getter enabledPlugin
-    getter suffixes
-    getter type
-    method constructor
-interface MimeTypeArray
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-    method namedItem
-interface ModalCloseWatcher : EventTarget
-    attribute @@toStringTag
-    getter onbeforeclose
-    getter onclose
-    method constructor
-    method destroy
-    method signalClosed
-    setter onbeforeclose
-    setter onclose
-interface Mojo
-    static method bindInterface
-    static method createDataPipe
-    static method createMessagePipe
-    static method createSharedBuffer
-    attribute @@toStringTag
-    attribute RESULT_ABORTED
-    attribute RESULT_ALREADY_EXISTS
-    attribute RESULT_BUSY
-    attribute RESULT_CANCELLED
-    attribute RESULT_DATA_LOSS
-    attribute RESULT_DEADLINE_EXCEEDED
-    attribute RESULT_FAILED_PRECONDITION
-    attribute RESULT_INTERNAL
-    attribute RESULT_INVALID_ARGUMENT
-    attribute RESULT_NOT_FOUND
-    attribute RESULT_OK
-    attribute RESULT_OUT_OF_RANGE
-    attribute RESULT_PERMISSION_DENIED
-    attribute RESULT_RESOURCE_EXHAUSTED
-    attribute RESULT_SHOULD_WAIT
-    attribute RESULT_UNAVAILABLE
-    attribute RESULT_UNIMPLEMENTED
-    attribute RESULT_UNKNOWN
-    method constructor
-interface MojoHandle
-    attribute @@toStringTag
-    method close
-    method constructor
-    method discardData
-    method duplicateBufferHandle
-    method mapBuffer
-    method queryData
-    method readData
-    method readMessage
-    method watch
-    method writeData
-    method writeMessage
-interface MojoInterfaceInterceptor : EventTarget
-    attribute @@toStringTag
-    getter oninterfacerequest
-    method constructor
-    method start
-    method stop
-    setter oninterfacerequest
-interface MojoInterfaceRequestEvent : Event
-    attribute @@toStringTag
-    getter handle
-    method constructor
-interface MojoWatcher
-    attribute @@toStringTag
-    method cancel
-    method constructor
-interface MouseEvent : UIEvent
-    attribute @@toStringTag
-    getter altKey
-    getter button
-    getter buttons
-    getter clientX
-    getter clientY
-    getter ctrlKey
-    getter fromElement
-    getter layerX
-    getter layerY
-    getter metaKey
-    getter movementX
-    getter movementY
-    getter offsetX
-    getter offsetY
-    getter pageX
-    getter pageY
-    getter region
-    getter relatedTarget
-    getter screenX
-    getter screenY
-    getter shiftKey
-    getter toElement
-    getter x
-    getter y
-    method constructor
-    method getModifierState
-    method initMouseEvent
-interface MutationEvent : Event
-    attribute @@toStringTag
-    attribute ADDITION
-    attribute MODIFICATION
-    attribute REMOVAL
-    getter attrChange
-    getter attrName
-    getter newValue
-    getter prevValue
-    getter relatedNode
-    method constructor
-    method initMutationEvent
-interface MutationObserver
-    attribute @@toStringTag
-    method constructor
-    method disconnect
-    method observe
-    method takeRecords
-interface MutationRecord
-    attribute @@toStringTag
-    getter addedNodes
-    getter attributeName
-    getter attributeNamespace
-    getter nextSibling
-    getter oldValue
-    getter previousSibling
-    getter removedNodes
-    getter target
-    getter type
-    method constructor
-interface NDEFMessage
-    attribute @@toStringTag
-    getter records
-    method constructor
-interface NDEFReader : EventTarget
-    attribute @@toStringTag
-    getter onreading
-    getter onreadingerror
-    method constructor
-    method scan
-    method write
-    setter onreading
-    setter onreadingerror
-interface NDEFReadingEvent : Event
-    attribute @@toStringTag
-    getter message
-    getter serialNumber
-    method constructor
-interface NDEFRecord
-    attribute @@toStringTag
-    getter data
-    getter encoding
-    getter id
-    getter lang
-    getter mediaType
-    getter recordType
-    method constructor
-    method toRecords
-interface NamedNodeMap
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method getNamedItem
-    method getNamedItemNS
-    method item
-    method removeNamedItem
-    method removeNamedItemNS
-    method setNamedItem
-    method setNamedItemNS
-interface NativeIOFile
-    attribute @@toStringTag
-    method close
-    method constructor
-    method flush
-    method getLength
-    method read
-    method setLength
-    method write
-interface NativeIOFileManager
-    attribute @@toStringTag
-    method constructor
-    method delete
-    method getAll
-    method getRemainingCapacity
-    method open
-    method releaseCapacity
-    method rename
-    method requestCapacity
-interface NavigationPreloadManager
-    attribute @@toStringTag
-    method constructor
-    method disable
-    method enable
-    method getState
-    method setHeaderValue
-interface Navigator
-    attribute @@toStringTag
-    getter appCodeName
-    getter appName
-    getter appVersion
-    getter clipboard
-    getter connection
-    getter contacts
-    getter cookieEnabled
-    getter credentials
-    getter deviceMemory
-    getter devicePosture
-    getter doNotTrack
-    getter geolocation
-    getter hardwareConcurrency
-    getter hid
-    getter ink
-    getter keyboard
-    getter language
-    getter languages
-    getter locks
-    getter managed
-    getter maxTouchPoints
-    getter mediaCapabilities
-    getter mediaDevices
-    getter mediaSession
-    getter mimeTypes
-    getter onLine
-    getter permissions
-    getter platform
-    getter plugins
-    getter presentation
-    getter product
-    getter productSub
-    getter scheduling
-    getter serial
-    getter serviceWorker
-    getter storage
-    getter storageBuckets
-    getter usb
-    getter userActivation
-    getter userAgent
-    getter userAgentData
-    getter vendor
-    getter vendorSub
-    getter virtualKeyboard
-    getter wakeLock
-    getter webdriver
-    getter webkitPersistentStorage
-    getter webkitTemporaryStorage
-    getter xr
-    method canShare
-    method clearAppBadge
-    method constructor
-    method createHandwritingRecognizer
-    method getBattery
-    method getGamepads
-    method getInstalledRelatedApps
-    method getUserMedia
-    method javaEnabled
-    method queryHandwritingRecognizerSupport
-    method registerProtocolHandler
-    method requestMIDIAccess
-    method requestMediaKeySystemAccess
-    method sendBeacon
-    method setAppBadge
-    method share
-    method unregisterProtocolHandler
-    method vibrate
-    method webkitGetUserMedia
-interface NavigatorManagedData : EventTarget
-    attribute @@toStringTag
-    getter onmanagedconfigurationchange
-    method constructor
-    method getAnnotatedAssetId
-    method getAnnotatedLocation
-    method getDirectoryId
-    method getHostname
-    method getManagedConfiguration
-    method getSerialNumber
-    setter onmanagedconfigurationchange
-interface NavigatorUAData
-    attribute @@toStringTag
-    getter brands
-    getter mobile
-    getter platform
-    method constructor
-    method getHighEntropyValues
-    method toJSON
-interface NetworkInformation : EventTarget
-    attribute @@toStringTag
-    getter downlink
-    getter downlinkMax
-    getter effectiveType
-    getter onchange
-    getter ontypechange
-    getter rtt
-    getter saveData
-    getter type
-    method constructor
-    setter onchange
-    setter ontypechange
-interface Node : EventTarget
-    attribute @@toStringTag
-    attribute ATTRIBUTE_NODE
-    attribute CDATA_SECTION_NODE
-    attribute COMMENT_NODE
-    attribute DOCUMENT_FRAGMENT_NODE
-    attribute DOCUMENT_NODE
-    attribute DOCUMENT_POSITION_CONTAINED_BY
-    attribute DOCUMENT_POSITION_CONTAINS
-    attribute DOCUMENT_POSITION_DISCONNECTED
-    attribute DOCUMENT_POSITION_FOLLOWING
-    attribute DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
-    attribute DOCUMENT_POSITION_PRECEDING
-    attribute DOCUMENT_TYPE_NODE
-    attribute ELEMENT_NODE
-    attribute ENTITY_NODE
-    attribute ENTITY_REFERENCE_NODE
-    attribute NOTATION_NODE
-    attribute PROCESSING_INSTRUCTION_NODE
-    attribute TEXT_NODE
-    getter baseURI
-    getter childNodes
-    getter firstChild
-    getter isConnected
-    getter lastChild
-    getter nextSibling
-    getter nodeName
-    getter nodeType
-    getter nodeValue
-    getter ownerDocument
-    getter parentElement
-    getter parentNode
-    getter previousSibling
-    getter textContent
-    method appendChild
-    method cloneNode
-    method compareDocumentPosition
-    method constructor
-    method contains
-    method getRootNode
-    method hasChildNodes
-    method insertBefore
-    method isDefaultNamespace
-    method isEqualNode
-    method isSameNode
-    method lookupNamespaceURI
-    method lookupPrefix
-    method normalize
-    method removeChild
-    method replaceChild
-    setter nodeValue
-    setter textContent
-interface NodeIterator
-    attribute @@toStringTag
-    getter filter
-    getter pointerBeforeReferenceNode
-    getter referenceNode
-    getter root
-    getter whatToShow
-    method constructor
-    method detach
-    method nextNode
-    method previousNode
-interface NodeList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method item
-    method keys
-    method values
-interface Notification : EventTarget
-    static getter maxActions
-    static getter permission
-    static method requestPermission
-    attribute @@toStringTag
-    getter actions
-    getter badge
-    getter body
-    getter data
-    getter dir
-    getter icon
-    getter lang
-    getter onclick
-    getter onclose
-    getter onerror
-    getter onshow
-    getter renotify
-    getter requireInteraction
-    getter showTrigger
-    getter silent
-    getter tag
-    getter timestamp
-    getter title
-    getter vibrate
-    method close
-    method constructor
-    setter onclick
-    setter onclose
-    setter onerror
-    setter onshow
-interface OTPCredential : Credential
-    attribute @@toStringTag
-    getter code
-    method constructor
-interface OfflineAudioCompletionEvent : Event
-    attribute @@toStringTag
-    getter renderedBuffer
-    method constructor
-interface OfflineAudioContext : BaseAudioContext
-    attribute @@toStringTag
-    getter length
-    getter oncomplete
-    method constructor
-    method resume
-    method startRendering
-    method suspend
-    setter oncomplete
-interface OffscreenCanvas : EventTarget
-    attribute @@toStringTag
-    getter height
-    getter width
-    method constructor
-    method convertToBlob
-    method getContext
-    method transferToImageBitmap
-    setter height
-    setter width
-interface OffscreenCanvasRenderingContext2D
-    attribute @@toStringTag
-    getter canvas
-    getter direction
-    getter fillStyle
-    getter filter
-    getter font
-    getter fontKerning
-    getter fontStretch
-    getter fontVariantCaps
-    getter globalAlpha
-    getter globalCompositeOperation
-    getter imageSmoothingEnabled
-    getter imageSmoothingQuality
-    getter lineCap
-    getter lineDashOffset
-    getter lineJoin
-    getter lineWidth
-    getter miterLimit
-    getter shadowBlur
-    getter shadowColor
-    getter shadowOffsetX
-    getter shadowOffsetY
-    getter strokeStyle
-    getter textAlign
-    getter textBaseline
-    getter textLetterSpacing
-    getter textRendering
-    getter textWordSpacing
-    method arc
-    method arcTo
-    method beginPath
-    method bezierCurveTo
-    method clearRect
-    method clip
-    method closePath
-    method commit
-    method constructor
-    method createConicGradient
-    method createImageData
-    method createLinearGradient
-    method createPattern
-    method createRadialGradient
-    method drawImage
-    method ellipse
-    method fill
-    method fillRect
-    method fillText
-    method getImageData
-    method getLineDash
-    method getTransform
-    method isContextLost
-    method isPointInPath
-    method isPointInStroke
-    method lineTo
-    method measureText
-    method moveTo
-    method perspective
-    method putImageData
-    method quadraticCurveTo
-    method rect
-    method reset
-    method resetTransform
-    method restore
-    method rotate
-    method rotate3d
-    method rotateAxis
-    method roundRect
-    method save
-    method scale
-    method setLineDash
-    method setTransform
-    method stroke
-    method strokeRect
-    method strokeText
-    method transform
-    method translate
-    setter direction
-    setter fillStyle
-    setter filter
-    setter font
-    setter fontKerning
-    setter fontStretch
-    setter fontVariantCaps
-    setter globalAlpha
-    setter globalCompositeOperation
-    setter imageSmoothingEnabled
-    setter imageSmoothingQuality
-    setter lineCap
-    setter lineDashOffset
-    setter lineJoin
-    setter lineWidth
-    setter miterLimit
-    setter shadowBlur
-    setter shadowColor
-    setter shadowOffsetX
-    setter shadowOffsetY
-    setter strokeStyle
-    setter textAlign
-    setter textBaseline
-    setter textLetterSpacing
-    setter textRendering
-    setter textWordSpacing
-interface Option
-    attribute @@toStringTag
-    getter defaultSelected
-    getter disabled
-    getter form
-    getter index
-    getter label
-    getter selected
-    getter text
-    getter value
-    method constructor
-    setter defaultSelected
-    setter disabled
-    setter label
-    setter selected
-    setter text
-    setter value
-interface OrientationSensor : Sensor
-    attribute @@toStringTag
-    getter quaternion
-    method constructor
-    method populateMatrix
-interface OscillatorNode : AudioScheduledSourceNode
-    attribute @@toStringTag
-    getter detune
-    getter frequency
-    getter type
-    method constructor
-    method setPeriodicWave
-    setter type
-interface OverconstrainedError
-    attribute @@toStringTag
-    getter constraint
-    getter message
-    getter name
-    method constructor
-interface OverscrollEvent : Event
-    attribute @@toStringTag
-    getter deltaX
-    getter deltaY
-    method constructor
-interface PageTransitionEvent : Event
-    attribute @@toStringTag
-    getter persisted
-    method constructor
-interface PannerNode : AudioNode
-    attribute @@toStringTag
-    getter coneInnerAngle
-    getter coneOuterAngle
-    getter coneOuterGain
-    getter distanceModel
-    getter maxDistance
-    getter orientationX
-    getter orientationY
-    getter orientationZ
-    getter panningModel
-    getter positionX
-    getter positionY
-    getter positionZ
-    getter refDistance
-    getter rolloffFactor
-    method constructor
-    method setOrientation
-    method setPosition
-    setter coneInnerAngle
-    setter coneOuterAngle
-    setter coneOuterGain
-    setter distanceModel
-    setter maxDistance
-    setter panningModel
-    setter refDistance
-    setter rolloffFactor
-interface PasswordCredential : Credential
-    attribute @@toStringTag
-    getter iconURL
-    getter name
-    getter password
-    method constructor
-interface Path2D
-    attribute @@toStringTag
-    method addPath
-    method arc
-    method arcTo
-    method bezierCurveTo
-    method closePath
-    method constructor
-    method ellipse
-    method lineTo
-    method moveTo
-    method quadraticCurveTo
-    method rect
-    method roundRect
-interface PaymentAddress
-    attribute @@toStringTag
-    getter addressLine
-    getter city
-    getter country
-    getter dependentLocality
-    getter organization
-    getter phone
-    getter postalCode
-    getter recipient
-    getter region
-    getter sortingCode
-    method constructor
-    method toJSON
-interface PaymentCredential : PublicKeyCredential
-    attribute @@toStringTag
-    method constructor
-interface PaymentInstruments
-    attribute @@toStringTag
-    method clear
-    method constructor
-    method delete
-    method get
-    method has
-    method keys
-    method set
-interface PaymentManager
-    attribute @@toStringTag
-    getter instruments
-    getter userHint
-    method constructor
-    method enableDelegations
-    setter userHint
-interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent
-    attribute @@toStringTag
-    getter methodDetails
-    getter methodName
-    method constructor
-interface PaymentRequest : EventTarget
-    attribute @@toStringTag
-    getter id
-    getter onpaymentmethodchange
-    getter onshippingaddresschange
-    getter onshippingoptionchange
-    getter shippingAddress
-    getter shippingOption
-    getter shippingType
-    method abort
-    method canMakePayment
-    method constructor
-    method hasEnrolledInstrument
-    method show
-    setter onpaymentmethodchange
-    setter onshippingaddresschange
-    setter onshippingoptionchange
-interface PaymentRequestUpdateEvent : Event
-    attribute @@toStringTag
-    method constructor
-    method updateWith
-interface PaymentResponse : EventTarget
-    attribute @@toStringTag
-    getter details
-    getter methodName
-    getter onpayerdetailchange
-    getter payerEmail
-    getter payerName
-    getter payerPhone
-    getter requestId
-    getter shippingAddress
-    getter shippingOption
-    method complete
-    method constructor
-    method retry
-    method toJSON
-    setter onpayerdetailchange
-interface Performance : EventTarget
-    attribute @@toStringTag
-    getter eventCounts
-    getter memory
-    getter navigation
-    getter onresourcetimingbufferfull
-    getter timeOrigin
-    getter timing
-    method clearMarks
-    method clearMeasures
-    method clearResourceTimings
-    method constructor
-    method getEntries
-    method getEntriesByName
-    method getEntriesByType
-    method mark
-    method measure
-    method now
-    method setResourceTimingBufferSize
-    method toJSON
-    setter onresourcetimingbufferfull
-interface PerformanceElementTiming : PerformanceEntry
-    attribute @@toStringTag
-    getter element
-    getter id
-    getter identifier
-    getter intersectionRect
-    getter loadTime
-    getter naturalHeight
-    getter naturalWidth
-    getter renderTime
-    getter url
-    method constructor
-    method toJSON
-interface PerformanceEntry
-    attribute @@toStringTag
-    getter duration
-    getter entryType
-    getter name
-    getter startTime
-    method constructor
-    method toJSON
-interface PerformanceEventTiming : PerformanceEntry
-    attribute @@toStringTag
-    getter cancelable
-    getter processingEnd
-    getter processingStart
-    getter target
-    method constructor
-    method toJSON
-interface PerformanceLongTaskTiming : PerformanceEntry
-    attribute @@toStringTag
-    getter attribution
-    method constructor
-    method toJSON
-interface PerformanceMark : PerformanceEntry
-    attribute @@toStringTag
-    getter detail
-    method constructor
-interface PerformanceMeasure : PerformanceEntry
-    attribute @@toStringTag
-    getter detail
-    method constructor
-interface PerformanceNavigation
-    attribute @@toStringTag
-    attribute TYPE_BACK_FORWARD
-    attribute TYPE_NAVIGATE
-    attribute TYPE_RELOAD
-    attribute TYPE_RESERVED
-    getter redirectCount
-    getter type
-    method constructor
-    method toJSON
-interface PerformanceNavigationTiming : PerformanceResourceTiming
-    attribute @@toStringTag
-    getter domComplete
-    getter domContentLoadedEventEnd
-    getter domContentLoadedEventStart
-    getter domInteractive
-    getter loadEventEnd
-    getter loadEventStart
-    getter redirectCount
-    getter type
-    getter unloadEventEnd
-    getter unloadEventStart
-    method constructor
-    method toJSON
-interface PerformanceObserver
-    static getter supportedEntryTypes
-    attribute @@toStringTag
-    method constructor
-    method disconnect
-    method observe
-    method takeRecords
-interface PerformanceObserverEntryList
-    attribute @@toStringTag
-    method constructor
-    method getEntries
-    method getEntriesByName
-    method getEntriesByType
-interface PerformancePaintTiming : PerformanceEntry
-    attribute @@toStringTag
-    method constructor
-interface PerformanceResourceTiming : PerformanceEntry
-    attribute @@toStringTag
-    getter connectEnd
-    getter connectStart
-    getter decodedBodySize
-    getter domainLookupEnd
-    getter domainLookupStart
-    getter encodedBodySize
-    getter fetchStart
-    getter initiatorType
-    getter nextHopProtocol
-    getter redirectEnd
-    getter redirectStart
-    getter requestStart
-    getter responseEnd
-    getter responseStart
-    getter secureConnectionStart
-    getter serverTiming
-    getter transferSize
-    getter workerStart
-    getter workerTiming
-    method constructor
-    method toJSON
-interface PerformanceServerTiming
-    attribute @@toStringTag
-    getter description
-    getter duration
-    getter name
-    method constructor
-    method toJSON
-interface PerformanceTiming
-    attribute @@toStringTag
-    getter connectEnd
-    getter connectStart
-    getter domComplete
-    getter domContentLoadedEventEnd
-    getter domContentLoadedEventStart
-    getter domInteractive
-    getter domLoading
-    getter domainLookupEnd
-    getter domainLookupStart
-    getter fetchStart
-    getter loadEventEnd
-    getter loadEventStart
-    getter navigationStart
-    getter redirectEnd
-    getter redirectStart
-    getter requestStart
-    getter responseEnd
-    getter responseStart
-    getter secureConnectionStart
-    getter unloadEventEnd
-    getter unloadEventStart
-    method constructor
-    method toJSON
-interface PeriodicSyncManager
-    attribute @@toStringTag
-    method constructor
-    method getTags
-    method register
-    method unregister
-interface PeriodicWave
-    attribute @@toStringTag
-    method constructor
-interface PermissionStatus : EventTarget
-    attribute @@toStringTag
-    getter onchange
-    getter state
-    method constructor
-    setter onchange
-interface Permissions
-    attribute @@toStringTag
-    method constructor
-    method query
-    method request
-    method requestAll
-    method revoke
-interface PictureInPictureEvent : Event
-    attribute @@toStringTag
-    getter pictureInPictureWindow
-    method constructor
-interface PictureInPictureWindow : EventTarget
-    attribute @@toStringTag
-    getter height
-    getter onresize
-    getter width
-    method constructor
-    setter onresize
-interface Plane
-    attribute @@toStringTag
-    getter length
-    getter rows
-    getter stride
-    method constructor
-    method readInto
-interface Plugin
-    attribute @@toStringTag
-    getter description
-    getter filename
-    getter length
-    getter name
-    method @@iterator
-    method constructor
-    method item
-    method namedItem
-interface PluginArray
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-    method namedItem
-    method refresh
-interface PointerEvent : MouseEvent
-    attribute @@toStringTag
-    getter altitudeAngle
-    getter azimuthAngle
-    getter height
-    getter isPrimary
-    getter pointerId
-    getter pointerType
-    getter pressure
-    getter tangentialPressure
-    getter tiltX
-    getter tiltY
-    getter twist
-    getter width
-    method constructor
-    method getCoalescedEvents
-    method getPredictedEvents
-interface PopStateEvent : Event
-    attribute @@toStringTag
-    getter state
-    method constructor
-interface Presentation
-    attribute @@toStringTag
-    getter defaultRequest
-    getter receiver
-    method constructor
-    setter defaultRequest
-interface PresentationAvailability : EventTarget
-    attribute @@toStringTag
-    getter onchange
-    getter value
-    method constructor
-    setter onchange
-interface PresentationConnection : EventTarget
-    attribute @@toStringTag
-    getter binaryType
-    getter id
-    getter onclose
-    getter onconnect
-    getter onmessage
-    getter onterminate
-    getter state
-    getter url
-    method close
-    method constructor
-    method send
-    method terminate
-    setter binaryType
-    setter onclose
-    setter onconnect
-    setter onmessage
-    setter onterminate
-interface PresentationConnectionAvailableEvent : Event
-    attribute @@toStringTag
-    getter connection
-    method constructor
-interface PresentationConnectionCloseEvent : Event
-    attribute @@toStringTag
-    getter message
-    getter reason
-    method constructor
-interface PresentationConnectionList : EventTarget
-    attribute @@toStringTag
-    getter connections
-    getter onconnectionavailable
-    method constructor
-    setter onconnectionavailable
-interface PresentationReceiver
-    attribute @@toStringTag
-    getter connectionList
-    method constructor
-interface PresentationRequest : EventTarget
-    attribute @@toStringTag
-    getter onconnectionavailable
-    method constructor
-    method getAvailability
-    method reconnect
-    method start
-    setter onconnectionavailable
-interface ProcessingInstruction : CharacterData
-    attribute @@toStringTag
-    getter sheet
-    getter target
-    method constructor
-interface Profiler : EventTarget
-    attribute @@toStringTag
-    getter sampleInterval
-    getter stopped
-    method constructor
-    method stop
-interface ProgressEvent : Event
-    attribute @@toStringTag
-    getter lengthComputable
-    getter loaded
-    getter total
-    method constructor
-interface PromiseRejectionEvent : Event
-    attribute @@toStringTag
-    getter promise
-    getter reason
-    method constructor
-interface PublicKeyCredential : Credential
-    static method isUserVerifyingPlatformAuthenticatorAvailable
-    attribute @@toStringTag
-    getter rawId
-    getter response
-    method constructor
-    method getClientExtensionResults
-interface PushManager
-    static getter supportedContentEncodings
-    attribute @@toStringTag
-    method constructor
-    method getSubscription
-    method permissionState
-    method subscribe
-interface PushSubscription
-    attribute @@toStringTag
-    getter endpoint
-    getter expirationTime
-    getter options
-    method constructor
-    method getKey
-    method toJSON
-    method unsubscribe
-interface PushSubscriptionOptions
-    attribute @@toStringTag
-    getter applicationServerKey
-    getter userVisibleOnly
-    method constructor
-interface RTCCertificate
-    attribute @@toStringTag
-    getter expires
-    method constructor
-    method getFingerprints
-interface RTCDTMFSender : EventTarget
-    attribute @@toStringTag
-    getter canInsertDTMF
-    getter ontonechange
-    getter toneBuffer
-    method constructor
-    method insertDTMF
-    setter ontonechange
-interface RTCDTMFToneChangeEvent : Event
-    attribute @@toStringTag
-    getter tone
-    method constructor
-interface RTCDataChannel : EventTarget
-    attribute @@toStringTag
-    getter binaryType
-    getter bufferedAmount
-    getter bufferedAmountLowThreshold
-    getter id
-    getter label
-    getter maxPacketLifeTime
-    getter maxRetransmits
-    getter negotiated
-    getter onbufferedamountlow
-    getter onclose
-    getter onclosing
-    getter onerror
-    getter onmessage
-    getter onopen
-    getter ordered
-    getter protocol
-    getter readyState
-    getter reliable
-    method close
-    method constructor
-    method send
-    setter binaryType
-    setter bufferedAmountLowThreshold
-    setter onbufferedamountlow
-    setter onclose
-    setter onclosing
-    setter onerror
-    setter onmessage
-    setter onopen
-interface RTCDataChannelEvent : Event
-    attribute @@toStringTag
-    getter channel
-    method constructor
-interface RTCDtlsTransport : EventTarget
-    attribute @@toStringTag
-    getter iceTransport
-    getter onerror
-    getter onstatechange
-    getter state
-    method constructor
-    method getRemoteCertificates
-    setter onerror
-    setter onstatechange
-interface RTCEncodedAudioFrame
-    attribute @@toStringTag
-    getter additionalData
-    getter contributingSources
-    getter data
-    getter synchronizationSource
-    getter timestamp
-    method constructor
-    method getMetadata
-    method toString
-    setter data
-interface RTCEncodedVideoFrame
-    attribute @@toStringTag
-    getter additionalData
-    getter data
-    getter synchronizationSource
-    getter timestamp
-    getter type
-    method constructor
-    method getMetadata
-    method toString
-    setter data
-interface RTCError : DOMException
-    attribute @@toStringTag
-    getter errorDetail
-    getter httpRequestStatusCode
-    getter receivedAlert
-    getter sctpCauseCode
-    getter sdpLineNumber
-    getter sentAlert
-    method constructor
-interface RTCErrorEvent : Event
-    attribute @@toStringTag
-    getter error
-    method constructor
-interface RTCIceCandidate
-    attribute @@toStringTag
-    getter address
-    getter candidate
-    getter component
-    getter foundation
-    getter port
-    getter priority
-    getter protocol
-    getter relatedAddress
-    getter relatedPort
-    getter sdpMLineIndex
-    getter sdpMid
-    getter tcpType
-    getter type
-    getter usernameFragment
-    method constructor
-    method toJSON
-interface RTCIceTransport : EventTarget
-    attribute @@toStringTag
-    getter gatheringState
-    getter ongatheringstatechange
-    getter onicecandidate
-    getter onselectedcandidatepairchange
-    getter onstatechange
-    getter role
-    getter state
-    method addRemoteCandidate
-    method constructor
-    method gather
-    method getLocalCandidates
-    method getLocalParameters
-    method getRemoteCandidates
-    method getRemoteParameters
-    method getSelectedCandidatePair
-    method start
-    method stop
-    setter ongatheringstatechange
-    setter onicecandidate
-    setter onselectedcandidatepairchange
-    setter onstatechange
-interface RTCPeerConnection : EventTarget
-    static method generateCertificate
-    attribute @@toStringTag
-    getter canTrickleIceCandidates
-    getter connectionState
-    getter currentLocalDescription
-    getter currentRemoteDescription
-    getter iceConnectionState
-    getter iceGatheringState
-    getter localDescription
-    getter onaddstream
-    getter onconnectionstatechange
-    getter ondatachannel
-    getter onicecandidate
-    getter onicecandidateerror
-    getter oniceconnectionstatechange
-    getter onicegatheringstatechange
-    getter onnegotiationneeded
-    getter onremovestream
-    getter onsignalingstatechange
-    getter ontrack
-    getter pendingLocalDescription
-    getter pendingRemoteDescription
-    getter remoteDescription
-    getter sctp
-    getter signalingState
-    method addIceCandidate
-    method addStream
-    method addTrack
-    method addTransceiver
-    method close
-    method constructor
-    method createAnswer
-    method createDTMFSender
-    method createDataChannel
-    method createOffer
-    method getConfiguration
-    method getLocalStreams
-    method getReceivers
-    method getRemoteStreams
-    method getSenders
-    method getStats
-    method getTransceivers
-    method removeStream
-    method removeTrack
-    method restartIce
-    method setConfiguration
-    method setLocalDescription
-    method setRemoteDescription
-    setter onaddstream
-    setter onconnectionstatechange
-    setter ondatachannel
-    setter onicecandidate
-    setter onicecandidateerror
-    setter oniceconnectionstatechange
-    setter onicegatheringstatechange
-    setter onnegotiationneeded
-    setter onremovestream
-    setter onsignalingstatechange
-    setter ontrack
-interface RTCPeerConnectionIceErrorEvent : Event
-    attribute @@toStringTag
-    getter address
-    getter errorCode
-    getter errorText
-    getter hostCandidate
-    getter port
-    getter url
-    method constructor
-interface RTCPeerConnectionIceEvent : Event
-    attribute @@toStringTag
-    getter candidate
-    method constructor
-interface RTCRtpReceiver
-    static method getCapabilities
-    attribute @@toStringTag
-    getter playoutDelayHint
-    getter rtcpTransport
-    getter track
-    getter transport
-    method constructor
-    method createEncodedAudioStreams
-    method createEncodedStreams
-    method createEncodedVideoStreams
-    method getContributingSources
-    method getParameters
-    method getStats
-    method getSynchronizationSources
-    setter playoutDelayHint
-interface RTCRtpSender
-    static method getCapabilities
-    attribute @@toStringTag
-    getter dtmf
-    getter rtcpTransport
-    getter track
-    getter transport
-    method constructor
-    method createEncodedAudioStreams
-    method createEncodedStreams
-    method createEncodedVideoStreams
-    method getParameters
-    method getStats
-    method replaceTrack
-    method setParameters
-    method setStreams
-interface RTCRtpTransceiver
-    attribute @@toStringTag
-    getter currentDirection
-    getter direction
-    getter headerExtensionsNegotiated
-    getter headerExtensionsToOffer
-    getter mid
-    getter receiver
-    getter sender
-    getter stopped
-    method constructor
-    method setCodecPreferences
-    method setOfferedRtpHeaderExtensions
-    method stop
-    setter direction
-interface RTCSctpTransport : EventTarget
-    attribute @@toStringTag
-    getter maxChannels
-    getter maxMessageSize
-    getter onstatechange
-    getter state
-    getter transport
-    method constructor
-    setter onstatechange
-interface RTCSessionDescription
-    attribute @@toStringTag
-    getter sdp
-    getter type
-    method constructor
-    method toJSON
-    setter sdp
-    setter type
-interface RTCStatsReport
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method has
-    method keys
-    method values
-interface RTCTrackEvent : Event
-    attribute @@toStringTag
-    getter receiver
-    getter streams
-    getter track
-    getter transceiver
-    method constructor
-interface RadioNodeList : NodeList
-    attribute @@toStringTag
-    getter value
-    method @@iterator
-    method constructor
-    setter value
-interface Range : AbstractRange
-    attribute @@toStringTag
-    attribute END_TO_END
-    attribute END_TO_START
-    attribute START_TO_END
-    attribute START_TO_START
-    getter commonAncestorContainer
-    method cloneContents
-    method cloneRange
-    method collapse
-    method compareBoundaryPoints
-    method comparePoint
-    method constructor
-    method createContextualFragment
-    method deleteContents
-    method detach
-    method expand
-    method extractContents
-    method getBoundingClientRect
-    method getClientRects
-    method insertNode
-    method intersectsNode
-    method isPointInRange
-    method selectNode
-    method selectNodeContents
-    method setEnd
-    method setEndAfter
-    method setEndBefore
-    method setStart
-    method setStartAfter
-    method setStartBefore
-    method surroundContents
-    method toString
-interface ReadableByteStreamController
-    attribute @@toStringTag
-    getter byobRequest
-    getter desiredSize
-    method close
-    method constructor
-    method enqueue
-    method error
-interface ReadableStream
-    attribute @@toStringTag
-    getter locked
-    method cancel
-    method constructor
-    method getReader
-    method pipeThrough
-    method pipeTo
-    method tee
-interface ReadableStreamBYOBReader
-    attribute @@toStringTag
-    getter closed
-    method cancel
-    method constructor
-    method read
-    method releaseLock
-interface ReadableStreamBYOBRequest
-    attribute @@toStringTag
-    getter view
-    method constructor
-    method respond
-    method respondWithNewView
-interface ReadableStreamDefaultController
-    attribute @@toStringTag
-    getter desiredSize
-    method close
-    method constructor
-    method enqueue
-    method error
-interface ReadableStreamDefaultReader
-    attribute @@toStringTag
-    getter closed
-    method cancel
-    method constructor
-    method read
-    method releaseLock
-interface ReceiveStream : ReadableStream
-    attribute @@toStringTag
-    getter readable
-    getter readingAborted
-    method abortReading
-    method constructor
-interface RelativeOrientationSensor : OrientationSensor
-    attribute @@toStringTag
-    method constructor
-interface RemotePlayback : EventTarget
-    attribute @@toStringTag
-    getter onconnect
-    getter onconnecting
-    getter ondisconnect
-    getter state
-    method cancelWatchAvailability
-    method constructor
-    method prompt
-    method watchAvailability
-    setter onconnect
-    setter onconnecting
-    setter ondisconnect
-interface ReportingObserver
-    attribute @@toStringTag
-    method constructor
-    method disconnect
-    method observe
-    method takeRecords
-interface Request
-    attribute @@toStringTag
-    getter body
-    getter bodyUsed
-    getter cache
-    getter credentials
-    getter destination
-    getter headers
-    getter integrity
-    getter isHistoryNavigation
-    getter keepalive
-    getter method
-    getter mode
-    getter redirect
-    getter referrer
-    getter referrerPolicy
-    getter signal
-    getter url
-    method arrayBuffer
-    method blob
-    method clone
-    method constructor
-    method formData
-    method json
-    method text
-interface ResizeObserver
-    attribute @@toStringTag
-    method constructor
-    method disconnect
-    method observe
-    method unobserve
-interface ResizeObserverEntry
-    attribute @@toStringTag
-    getter borderBoxSize
-    getter contentBoxSize
-    getter contentRect
-    getter devicePixelContentBoxSize
-    getter target
-    method constructor
-interface ResizeObserverSize
-    attribute @@toStringTag
-    getter blockSize
-    getter inlineSize
-    method constructor
-interface Response
-    static method error
-    static method redirect
-    attribute @@toStringTag
-    getter body
-    getter bodyUsed
-    getter headers
-    getter ok
-    getter redirected
-    getter status
-    getter statusText
-    getter type
-    getter url
-    method arrayBuffer
-    method blob
-    method clone
-    method constructor
-    method formData
-    method json
-    method text
-interface SVGAElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter href
-    getter target
-    method constructor
-interface SVGAngle
-    attribute @@toStringTag
-    attribute SVG_ANGLETYPE_DEG
-    attribute SVG_ANGLETYPE_GRAD
-    attribute SVG_ANGLETYPE_RAD
-    attribute SVG_ANGLETYPE_UNKNOWN
-    attribute SVG_ANGLETYPE_UNSPECIFIED
-    getter unitType
-    getter value
-    getter valueAsString
-    getter valueInSpecifiedUnits
-    method constructor
-    method convertToSpecifiedUnits
-    method newValueSpecifiedUnits
-    setter value
-    setter valueAsString
-    setter valueInSpecifiedUnits
-interface SVGAnimateElement : SVGAnimationElement
-    attribute @@toStringTag
-    method constructor
-interface SVGAnimateMotionElement : SVGAnimationElement
-    attribute @@toStringTag
-    method constructor
-interface SVGAnimateTransformElement : SVGAnimationElement
-    attribute @@toStringTag
-    method constructor
-interface SVGAnimatedAngle
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedBoolean
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-    setter baseVal
-interface SVGAnimatedEnumeration
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-    setter baseVal
-interface SVGAnimatedInteger
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-    setter baseVal
-interface SVGAnimatedLength
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedLengthList
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedNumber
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-    setter baseVal
-interface SVGAnimatedNumberList
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedPreserveAspectRatio
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedRect
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimatedString
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-    setter baseVal
-interface SVGAnimatedTransformList
-    attribute @@toStringTag
-    getter animVal
-    getter baseVal
-    method constructor
-interface SVGAnimationElement : SVGElement
-    attribute @@toStringTag
-    getter onbegin
-    getter onend
-    getter onrepeat
-    getter requiredExtensions
-    getter systemLanguage
-    getter targetElement
-    method beginElement
-    method beginElementAt
-    method constructor
-    method endElement
-    method endElementAt
-    method getCurrentTime
-    method getSimpleDuration
-    method getStartTime
-    setter onbegin
-    setter onend
-    setter onrepeat
-interface SVGCircleElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter cx
-    getter cy
-    getter r
-    method constructor
-interface SVGClipPathElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter clipPathUnits
-    method constructor
-interface SVGComponentTransferFunctionElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_GAMMA
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_LINEAR
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_TABLE
-    attribute SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN
-    getter amplitude
-    getter exponent
-    getter intercept
-    getter offset
-    getter slope
-    getter tableValues
-    getter type
-    method constructor
-interface SVGDefsElement : SVGGraphicsElement
-    attribute @@toStringTag
-    method constructor
-interface SVGDescElement : SVGElement
-    attribute @@toStringTag
-    method constructor
-interface SVGElement : Element
-    attribute @@toStringTag
-    getter autofocus
-    getter className
-    getter dataset
-    getter nonce
-    getter onabort
-    getter onanimationend
-    getter onanimationiteration
-    getter onanimationstart
-    getter onauxclick
-    getter onbeforexrselect
-    getter onblur
-    getter oncancel
-    getter oncanplay
-    getter oncanplaythrough
-    getter onchange
-    getter onclick
-    getter onclose
-    getter oncontextmenu
-    getter oncopy
-    getter oncuechange
-    getter oncut
-    getter ondblclick
-    getter ondrag
-    getter ondragend
-    getter ondragenter
-    getter ondragleave
-    getter ondragover
-    getter ondragstart
-    getter ondrop
-    getter ondurationchange
-    getter onemptied
-    getter onended
-    getter onerror
-    getter onfocus
-    getter onformdata
-    getter ongotpointercapture
-    getter oninput
-    getter oninvalid
-    getter onkeydown
-    getter onkeypress
-    getter onkeyup
-    getter onload
-    getter onloadeddata
-    getter onloadedmetadata
-    getter onloadstart
-    getter onlostpointercapture
-    getter onmousedown
-    getter onmouseenter
-    getter onmouseleave
-    getter onmousemove
-    getter onmouseout
-    getter onmouseover
-    getter onmouseup
-    getter onmousewheel
-    getter onoverscroll
-    getter onpaste
-    getter onpause
-    getter onplay
-    getter onplaying
-    getter onpointercancel
-    getter onpointerdown
-    getter onpointerenter
-    getter onpointerleave
-    getter onpointermove
-    getter onpointerout
-    getter onpointerover
-    getter onpointerrawupdate
-    getter onpointerup
-    getter onprogress
-    getter onratechange
-    getter onreset
-    getter onresize
-    getter onscroll
-    getter onscrollend
-    getter onseeked
-    getter onseeking
-    getter onselect
-    getter onselectionchange
-    getter onselectstart
-    getter onstalled
-    getter onsubmit
-    getter onsuspend
-    getter ontimeupdate
-    getter ontoggle
-    getter ontouchcancel
-    getter ontouchend
-    getter ontouchmove
-    getter ontouchstart
-    getter ontransitioncancel
-    getter ontransitionend
-    getter ontransitionrun
-    getter ontransitionstart
-    getter onvolumechange
-    getter onwaiting
-    getter onwebkitanimationend
-    getter onwebkitanimationiteration
-    getter onwebkitanimationstart
-    getter onwebkittransitionend
-    getter onwheel
-    getter ownerSVGElement
-    getter style
-    getter tabIndex
-    getter viewportElement
-    method blur
-    method constructor
-    method focus
-    setter autofocus
-    setter nonce
-    setter onabort
-    setter onanimationend
-    setter onanimationiteration
-    setter onanimationstart
-    setter onauxclick
-    setter onbeforexrselect
-    setter onblur
-    setter oncancel
-    setter oncanplay
-    setter oncanplaythrough
-    setter onchange
-    setter onclick
-    setter onclose
-    setter oncontextmenu
-    setter oncopy
-    setter oncuechange
-    setter oncut
-    setter ondblclick
-    setter ondrag
-    setter ondragend
-    setter ondragenter
-    setter ondragleave
-    setter ondragover
-    setter ondragstart
-    setter ondrop
-    setter ondurationchange
-    setter onemptied
-    setter onended
-    setter onerror
-    setter onfocus
-    setter onformdata
-    setter ongotpointercapture
-    setter oninput
-    setter oninvalid
-    setter onkeydown
-    setter onkeypress
-    setter onkeyup
-    setter onload
-    setter onloadeddata
-    setter onloadedmetadata
-    setter onloadstart
-    setter onlostpointercapture
-    setter onmousedown
-    setter onmouseenter
-    setter onmouseleave
-    setter onmousemove
-    setter onmouseout
-    setter onmouseover
-    setter onmouseup
-    setter onmousewheel
-    setter onoverscroll
-    setter onpaste
-    setter onpause
-    setter onplay
-    setter onplaying
-    setter onpointercancel
-    setter onpointerdown
-    setter onpointerenter
-    setter onpointerleave
-    setter onpointermove
-    setter onpointerout
-    setter onpointerover
-    setter onpointerrawupdate
-    setter onpointerup
-    setter onprogress
-    setter onratechange
-    setter onreset
-    setter onresize
-    setter onscroll
-    setter onscrollend
-    setter onseeked
-    setter onseeking
-    setter onselect
-    setter onselectionchange
-    setter onselectstart
-    setter onstalled
-    setter onsubmit
-    setter onsuspend
-    setter ontimeupdate
-    setter ontoggle
-    setter ontouchcancel
-    setter ontouchend
-    setter ontouchmove
-    setter ontouchstart
-    setter ontransitioncancel
-    setter ontransitionend
-    setter ontransitionrun
-    setter ontransitionstart
-    setter onvolumechange
-    setter onwaiting
-    setter onwebkitanimationend
-    setter onwebkitanimationiteration
-    setter onwebkitanimationstart
-    setter onwebkittransitionend
-    setter onwheel
-    setter style
-    setter tabIndex
-interface SVGEllipseElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter cx
-    getter cy
-    getter rx
-    getter ry
-    method constructor
-interface SVGFEBlendElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_FEBLEND_MODE_COLOR
-    attribute SVG_FEBLEND_MODE_COLOR_BURN
-    attribute SVG_FEBLEND_MODE_COLOR_DODGE
-    attribute SVG_FEBLEND_MODE_DARKEN
-    attribute SVG_FEBLEND_MODE_DIFFERENCE
-    attribute SVG_FEBLEND_MODE_EXCLUSION
-    attribute SVG_FEBLEND_MODE_HARD_LIGHT
-    attribute SVG_FEBLEND_MODE_HUE
-    attribute SVG_FEBLEND_MODE_LIGHTEN
-    attribute SVG_FEBLEND_MODE_LUMINOSITY
-    attribute SVG_FEBLEND_MODE_MULTIPLY
-    attribute SVG_FEBLEND_MODE_NORMAL
-    attribute SVG_FEBLEND_MODE_OVERLAY
-    attribute SVG_FEBLEND_MODE_SATURATION
-    attribute SVG_FEBLEND_MODE_SCREEN
-    attribute SVG_FEBLEND_MODE_SOFT_LIGHT
-    attribute SVG_FEBLEND_MODE_UNKNOWN
-    getter height
-    getter in1
-    getter in2
-    getter mode
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEColorMatrixElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_FECOLORMATRIX_TYPE_HUEROTATE
-    attribute SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA
-    attribute SVG_FECOLORMATRIX_TYPE_MATRIX
-    attribute SVG_FECOLORMATRIX_TYPE_SATURATE
-    attribute SVG_FECOLORMATRIX_TYPE_UNKNOWN
-    getter height
-    getter in1
-    getter result
-    getter type
-    getter values
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEComponentTransferElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter in1
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFECompositeElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_FECOMPOSITE_OPERATOR_ARITHMETIC
-    attribute SVG_FECOMPOSITE_OPERATOR_ATOP
-    attribute SVG_FECOMPOSITE_OPERATOR_IN
-    attribute SVG_FECOMPOSITE_OPERATOR_OUT
-    attribute SVG_FECOMPOSITE_OPERATOR_OVER
-    attribute SVG_FECOMPOSITE_OPERATOR_UNKNOWN
-    attribute SVG_FECOMPOSITE_OPERATOR_XOR
-    getter height
-    getter in1
-    getter in2
-    getter k1
-    getter k2
-    getter k3
-    getter k4
-    getter operator
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEConvolveMatrixElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_EDGEMODE_DUPLICATE
-    attribute SVG_EDGEMODE_NONE
-    attribute SVG_EDGEMODE_UNKNOWN
-    attribute SVG_EDGEMODE_WRAP
-    getter bias
-    getter divisor
-    getter edgeMode
-    getter height
-    getter in1
-    getter kernelMatrix
-    getter kernelUnitLengthX
-    getter kernelUnitLengthY
-    getter orderX
-    getter orderY
-    getter preserveAlpha
-    getter result
-    getter targetX
-    getter targetY
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEDiffuseLightingElement : SVGElement
-    attribute @@toStringTag
-    getter diffuseConstant
-    getter height
-    getter in1
-    getter kernelUnitLengthX
-    getter kernelUnitLengthY
-    getter result
-    getter surfaceScale
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEDisplacementMapElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_CHANNEL_A
-    attribute SVG_CHANNEL_B
-    attribute SVG_CHANNEL_G
-    attribute SVG_CHANNEL_R
-    attribute SVG_CHANNEL_UNKNOWN
-    getter height
-    getter in1
-    getter in2
-    getter result
-    getter scale
-    getter width
-    getter x
-    getter xChannelSelector
-    getter y
-    getter yChannelSelector
-    method constructor
-interface SVGFEDistantLightElement : SVGElement
-    attribute @@toStringTag
-    getter azimuth
-    getter elevation
-    method constructor
-interface SVGFEDropShadowElement : SVGElement
-    attribute @@toStringTag
-    getter dx
-    getter dy
-    getter height
-    getter in1
-    getter result
-    getter stdDeviationX
-    getter stdDeviationY
-    getter width
-    getter x
-    getter y
-    method constructor
-    method setStdDeviation
-interface SVGFEFloodElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEFuncAElement : SVGComponentTransferFunctionElement
-    attribute @@toStringTag
-    method constructor
-interface SVGFEFuncBElement : SVGComponentTransferFunctionElement
-    attribute @@toStringTag
-    method constructor
-interface SVGFEFuncGElement : SVGComponentTransferFunctionElement
-    attribute @@toStringTag
-    method constructor
-interface SVGFEFuncRElement : SVGComponentTransferFunctionElement
-    attribute @@toStringTag
-    method constructor
-interface SVGFEGaussianBlurElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter in1
-    getter result
-    getter stdDeviationX
-    getter stdDeviationY
-    getter width
-    getter x
-    getter y
-    method constructor
-    method setStdDeviation
-interface SVGFEImageElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter href
-    getter preserveAspectRatio
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEMergeElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEMergeNodeElement : SVGElement
-    attribute @@toStringTag
-    getter in1
-    method constructor
-interface SVGFEMorphologyElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_MORPHOLOGY_OPERATOR_DILATE
-    attribute SVG_MORPHOLOGY_OPERATOR_ERODE
-    attribute SVG_MORPHOLOGY_OPERATOR_UNKNOWN
-    getter height
-    getter in1
-    getter operator
-    getter radiusX
-    getter radiusY
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEOffsetElement : SVGElement
-    attribute @@toStringTag
-    getter dx
-    getter dy
-    getter height
-    getter in1
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFEPointLightElement : SVGElement
-    attribute @@toStringTag
-    getter x
-    getter y
-    getter z
-    method constructor
-interface SVGFESpecularLightingElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter in1
-    getter kernelUnitLengthX
-    getter kernelUnitLengthY
-    getter result
-    getter specularConstant
-    getter specularExponent
-    getter surfaceScale
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFESpotLightElement : SVGElement
-    attribute @@toStringTag
-    getter limitingConeAngle
-    getter pointsAtX
-    getter pointsAtY
-    getter pointsAtZ
-    getter specularExponent
-    getter x
-    getter y
-    getter z
-    method constructor
-interface SVGFETileElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter in1
-    getter result
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFETurbulenceElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_STITCHTYPE_NOSTITCH
-    attribute SVG_STITCHTYPE_STITCH
-    attribute SVG_STITCHTYPE_UNKNOWN
-    attribute SVG_TURBULENCE_TYPE_FRACTALNOISE
-    attribute SVG_TURBULENCE_TYPE_TURBULENCE
-    attribute SVG_TURBULENCE_TYPE_UNKNOWN
-    getter baseFrequencyX
-    getter baseFrequencyY
-    getter height
-    getter numOctaves
-    getter result
-    getter seed
-    getter stitchTiles
-    getter type
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGFilterElement : SVGElement
-    attribute @@toStringTag
-    getter filterUnits
-    getter height
-    getter href
-    getter primitiveUnits
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGForeignObjectElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter height
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGGElement : SVGGraphicsElement
-    attribute @@toStringTag
-    method constructor
-interface SVGGeometryElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter pathLength
-    method constructor
-    method getPointAtLength
-    method getTotalLength
-    method isPointInFill
-    method isPointInStroke
-interface SVGGradientElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_SPREADMETHOD_PAD
-    attribute SVG_SPREADMETHOD_REFLECT
-    attribute SVG_SPREADMETHOD_REPEAT
-    attribute SVG_SPREADMETHOD_UNKNOWN
-    getter gradientTransform
-    getter gradientUnits
-    getter href
-    getter spreadMethod
-    method constructor
-interface SVGGraphicsElement : SVGElement
-    attribute @@toStringTag
-    getter farthestViewportElement
-    getter nearestViewportElement
-    getter requiredExtensions
-    getter systemLanguage
-    getter transform
-    method constructor
-    method getBBox
-    method getCTM
-    method getScreenCTM
-interface SVGImageElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter decoding
-    getter height
-    getter href
-    getter preserveAspectRatio
-    getter width
-    getter x
-    getter y
-    method constructor
-    method decode
-    setter decoding
-interface SVGLength
-    attribute @@toStringTag
-    attribute SVG_LENGTHTYPE_CM
-    attribute SVG_LENGTHTYPE_EMS
-    attribute SVG_LENGTHTYPE_EXS
-    attribute SVG_LENGTHTYPE_IN
-    attribute SVG_LENGTHTYPE_MM
-    attribute SVG_LENGTHTYPE_NUMBER
-    attribute SVG_LENGTHTYPE_PC
-    attribute SVG_LENGTHTYPE_PERCENTAGE
-    attribute SVG_LENGTHTYPE_PT
-    attribute SVG_LENGTHTYPE_PX
-    attribute SVG_LENGTHTYPE_UNKNOWN
-    getter unitType
-    getter value
-    getter valueAsString
-    getter valueInSpecifiedUnits
-    method constructor
-    method convertToSpecifiedUnits
-    method newValueSpecifiedUnits
-    setter value
-    setter valueAsString
-    setter valueInSpecifiedUnits
-interface SVGLengthList
-    attribute @@toStringTag
-    getter length
-    getter numberOfItems
-    method @@iterator
-    method appendItem
-    method clear
-    method constructor
-    method getItem
-    method initialize
-    method insertItemBefore
-    method removeItem
-    method replaceItem
-interface SVGLineElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter x1
-    getter x2
-    getter y1
-    getter y2
-    method constructor
-interface SVGLinearGradientElement : SVGGradientElement
-    attribute @@toStringTag
-    getter x1
-    getter x2
-    getter y1
-    getter y2
-    method constructor
-interface SVGMPathElement : SVGElement
-    attribute @@toStringTag
-    getter href
-    method constructor
-interface SVGMarkerElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_MARKERUNITS_STROKEWIDTH
-    attribute SVG_MARKERUNITS_UNKNOWN
-    attribute SVG_MARKERUNITS_USERSPACEONUSE
-    attribute SVG_MARKER_ORIENT_ANGLE
-    attribute SVG_MARKER_ORIENT_AUTO
-    attribute SVG_MARKER_ORIENT_UNKNOWN
-    getter markerHeight
-    getter markerUnits
-    getter markerWidth
-    getter orientAngle
-    getter orientType
-    getter preserveAspectRatio
-    getter refX
-    getter refY
-    getter viewBox
-    method constructor
-    method setOrientToAngle
-    method setOrientToAuto
-interface SVGMaskElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter maskContentUnits
-    getter maskUnits
-    getter requiredExtensions
-    getter systemLanguage
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGMatrix
-    attribute @@toStringTag
-    getter a
-    getter b
-    getter c
-    getter d
-    getter e
-    getter f
-    method constructor
-    method flipX
-    method flipY
-    method inverse
-    method multiply
-    method rotate
-    method rotateFromVector
-    method scale
-    method scaleNonUniform
-    method skewX
-    method skewY
-    method translate
-    setter a
-    setter b
-    setter c
-    setter d
-    setter e
-    setter f
-interface SVGMetadataElement : SVGElement
-    attribute @@toStringTag
-    method constructor
-interface SVGNumber
-    attribute @@toStringTag
-    getter value
-    method constructor
-    setter value
-interface SVGNumberList
-    attribute @@toStringTag
-    getter length
-    getter numberOfItems
-    method @@iterator
-    method appendItem
-    method clear
-    method constructor
-    method getItem
-    method initialize
-    method insertItemBefore
-    method removeItem
-    method replaceItem
-interface SVGPathElement : SVGGeometryElement
-    attribute @@toStringTag
-    method constructor
-interface SVGPatternElement : SVGElement
-    attribute @@toStringTag
-    getter height
-    getter href
-    getter patternContentUnits
-    getter patternTransform
-    getter patternUnits
-    getter preserveAspectRatio
-    getter requiredExtensions
-    getter systemLanguage
-    getter viewBox
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGPoint
-    attribute @@toStringTag
-    getter x
-    getter y
-    method constructor
-    method matrixTransform
-    setter x
-    setter y
-interface SVGPointList
-    attribute @@toStringTag
-    getter length
-    getter numberOfItems
-    method @@iterator
-    method appendItem
-    method clear
-    method constructor
-    method getItem
-    method initialize
-    method insertItemBefore
-    method removeItem
-    method replaceItem
-interface SVGPolygonElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter animatedPoints
-    getter points
-    method constructor
-interface SVGPolylineElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter animatedPoints
-    getter points
-    method constructor
-interface SVGPreserveAspectRatio
-    attribute @@toStringTag
-    attribute SVG_MEETORSLICE_MEET
-    attribute SVG_MEETORSLICE_SLICE
-    attribute SVG_MEETORSLICE_UNKNOWN
-    attribute SVG_PRESERVEASPECTRATIO_NONE
-    attribute SVG_PRESERVEASPECTRATIO_UNKNOWN
-    attribute SVG_PRESERVEASPECTRATIO_XMAXYMAX
-    attribute SVG_PRESERVEASPECTRATIO_XMAXYMID
-    attribute SVG_PRESERVEASPECTRATIO_XMAXYMIN
-    attribute SVG_PRESERVEASPECTRATIO_XMIDYMAX
-    attribute SVG_PRESERVEASPECTRATIO_XMIDYMID
-    attribute SVG_PRESERVEASPECTRATIO_XMIDYMIN
-    attribute SVG_PRESERVEASPECTRATIO_XMINYMAX
-    attribute SVG_PRESERVEASPECTRATIO_XMINYMID
-    attribute SVG_PRESERVEASPECTRATIO_XMINYMIN
-    getter align
-    getter meetOrSlice
-    method constructor
-    setter align
-    setter meetOrSlice
-interface SVGRadialGradientElement : SVGGradientElement
-    attribute @@toStringTag
-    getter cx
-    getter cy
-    getter fr
-    getter fx
-    getter fy
-    getter r
-    method constructor
-interface SVGRect
-    attribute @@toStringTag
-    getter height
-    getter width
-    getter x
-    getter y
-    method constructor
-    setter height
-    setter width
-    setter x
-    setter y
-interface SVGRectElement : SVGGeometryElement
-    attribute @@toStringTag
-    getter height
-    getter rx
-    getter ry
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGSVGElement : SVGGraphicsElement
-    attribute @@toStringTag
-    attribute SVG_ZOOMANDPAN_DISABLE
-    attribute SVG_ZOOMANDPAN_MAGNIFY
-    attribute SVG_ZOOMANDPAN_UNKNOWN
-    getter currentScale
-    getter currentTranslate
-    getter height
-    getter preserveAspectRatio
-    getter viewBox
-    getter width
-    getter x
-    getter y
-    getter zoomAndPan
-    method animationsPaused
-    method checkEnclosure
-    method checkIntersection
-    method constructor
-    method createSVGAngle
-    method createSVGLength
-    method createSVGMatrix
-    method createSVGNumber
-    method createSVGPoint
-    method createSVGRect
-    method createSVGTransform
-    method createSVGTransformFromMatrix
-    method deselectAll
-    method forceRedraw
-    method getCurrentTime
-    method getElementById
-    method getEnclosureList
-    method getIntersectionList
-    method pauseAnimations
-    method setCurrentTime
-    method suspendRedraw
-    method unpauseAnimations
-    method unsuspendRedraw
-    method unsuspendRedrawAll
-    setter currentScale
-    setter zoomAndPan
-interface SVGScriptElement : SVGElement
-    attribute @@toStringTag
-    getter href
-    getter type
-    method constructor
-    setter type
-interface SVGSetElement : SVGAnimationElement
-    attribute @@toStringTag
-    method constructor
-interface SVGStopElement : SVGElement
-    attribute @@toStringTag
-    getter offset
-    method constructor
-interface SVGStringList
-    attribute @@toStringTag
-    getter length
-    getter numberOfItems
-    method @@iterator
-    method appendItem
-    method clear
-    method constructor
-    method getItem
-    method initialize
-    method insertItemBefore
-    method removeItem
-    method replaceItem
-interface SVGStyleElement : SVGElement
-    attribute @@toStringTag
-    getter disabled
-    getter media
-    getter sheet
-    getter title
-    getter type
-    method constructor
-    setter disabled
-    setter media
-    setter title
-    setter type
-interface SVGSwitchElement : SVGGraphicsElement
-    attribute @@toStringTag
-    method constructor
-interface SVGSymbolElement : SVGElement
-    attribute @@toStringTag
-    getter preserveAspectRatio
-    getter viewBox
-    method constructor
-interface SVGTSpanElement : SVGTextPositioningElement
-    attribute @@toStringTag
-    method constructor
-interface SVGTextContentElement : SVGGraphicsElement
-    attribute @@toStringTag
-    attribute LENGTHADJUST_SPACING
-    attribute LENGTHADJUST_SPACINGANDGLYPHS
-    attribute LENGTHADJUST_UNKNOWN
-    getter lengthAdjust
-    getter textLength
-    method constructor
-    method getCharNumAtPosition
-    method getComputedTextLength
-    method getEndPositionOfChar
-    method getExtentOfChar
-    method getNumberOfChars
-    method getRotationOfChar
-    method getStartPositionOfChar
-    method getSubStringLength
-    method selectSubString
-interface SVGTextElement : SVGTextPositioningElement
-    attribute @@toStringTag
-    method constructor
-interface SVGTextPathElement : SVGTextContentElement
-    attribute @@toStringTag
-    attribute TEXTPATH_METHODTYPE_ALIGN
-    attribute TEXTPATH_METHODTYPE_STRETCH
-    attribute TEXTPATH_METHODTYPE_UNKNOWN
-    attribute TEXTPATH_SPACINGTYPE_AUTO
-    attribute TEXTPATH_SPACINGTYPE_EXACT
-    attribute TEXTPATH_SPACINGTYPE_UNKNOWN
-    getter href
-    getter method
-    getter spacing
-    getter startOffset
-    method constructor
-interface SVGTextPositioningElement : SVGTextContentElement
-    attribute @@toStringTag
-    getter dx
-    getter dy
-    getter rotate
-    getter x
-    getter y
-    method constructor
-interface SVGTitleElement : SVGElement
-    attribute @@toStringTag
-    method constructor
-interface SVGTransform
-    attribute @@toStringTag
-    attribute SVG_TRANSFORM_MATRIX
-    attribute SVG_TRANSFORM_ROTATE
-    attribute SVG_TRANSFORM_SCALE
-    attribute SVG_TRANSFORM_SKEWX
-    attribute SVG_TRANSFORM_SKEWY
-    attribute SVG_TRANSFORM_TRANSLATE
-    attribute SVG_TRANSFORM_UNKNOWN
-    getter angle
-    getter matrix
-    getter type
-    method constructor
-    method setMatrix
-    method setRotate
-    method setScale
-    method setSkewX
-    method setSkewY
-    method setTranslate
-interface SVGTransformList
-    attribute @@toStringTag
-    getter length
-    getter numberOfItems
-    method @@iterator
-    method appendItem
-    method clear
-    method consolidate
-    method constructor
-    method createSVGTransformFromMatrix
-    method getItem
-    method initialize
-    method insertItemBefore
-    method removeItem
-    method replaceItem
-interface SVGUnitTypes
-    attribute @@toStringTag
-    attribute SVG_UNIT_TYPE_OBJECTBOUNDINGBOX
-    attribute SVG_UNIT_TYPE_UNKNOWN
-    attribute SVG_UNIT_TYPE_USERSPACEONUSE
-    method constructor
-interface SVGUseElement : SVGGraphicsElement
-    attribute @@toStringTag
-    getter height
-    getter href
-    getter width
-    getter x
-    getter y
-    method constructor
-interface SVGViewElement : SVGElement
-    attribute @@toStringTag
-    attribute SVG_ZOOMANDPAN_DISABLE
-    attribute SVG_ZOOMANDPAN_MAGNIFY
-    attribute SVG_ZOOMANDPAN_UNKNOWN
-    getter preserveAspectRatio
-    getter viewBox
-    getter zoomAndPan
-    method constructor
-    setter zoomAndPan
-interface Sanitizer
-    static method defaultConfig
-    attribute @@toStringTag
-    method config
-    method constructor
-    method sanitize
-    method sanitizeToString
-interface Scheduler
-    attribute @@toStringTag
-    getter currentTaskSignal
-    method constructor
-    method postTask
-interface Scheduling
-    attribute @@toStringTag
-    method constructor
-    method isFramePending
-    method isInputPending
-interface Screen
-    attribute @@toStringTag
-    getter availHeight
-    getter availLeft
-    getter availTop
-    getter availWidth
-    getter colorDepth
-    getter height
-    getter id
-    getter internal
-    getter isExtended
-    getter left
-    getter onchange
-    getter orientation
-    getter pixelDepth
-    getter primary
-    getter scaleFactor
-    getter top
-    getter touchSupport
-    getter width
-    method addEventListener
-    method constructor
-    method dispatchEvent
-    method removeEventListener
-    setter onchange
-interface ScreenOrientation : EventTarget
-    attribute @@toStringTag
-    getter angle
-    getter onchange
-    getter type
-    method constructor
-    method lock
-    method unlock
-    setter onchange
-interface Screens : EventTarget
-    attribute @@toStringTag
-    getter currentScreen
-    getter oncurrentscreenchange
-    getter onscreenschange
-    getter screens
-    method constructor
-    setter oncurrentscreenchange
-    setter onscreenschange
-interface ScriptProcessorNode : AudioNode
-    attribute @@toStringTag
-    getter bufferSize
-    getter onaudioprocess
-    method constructor
-    setter onaudioprocess
-interface ScrollTimeline : AnimationTimeline
-    attribute @@toStringTag
-    getter orientation
-    getter scrollOffsets
-    getter scrollSource
-    getter timeRange
-    method constructor
-interface SecurityPolicyViolationEvent : Event
-    attribute @@toStringTag
-    getter blockedURI
-    getter columnNumber
-    getter disposition
-    getter documentURI
-    getter effectiveDirective
-    getter lineNumber
-    getter originalPolicy
-    getter referrer
-    getter sample
-    getter sourceFile
-    getter statusCode
-    getter violatedDirective
-    method constructor
-interface Selection
-    attribute @@toStringTag
-    getter anchorNode
-    getter anchorOffset
-    getter baseNode
-    getter baseOffset
-    getter extentNode
-    getter extentOffset
-    getter focusNode
-    getter focusOffset
-    getter isCollapsed
-    getter rangeCount
-    getter type
-    method addRange
-    method collapse
-    method collapseToEnd
-    method collapseToStart
-    method constructor
-    method containsNode
-    method deleteFromDocument
-    method empty
-    method extend
-    method getRangeAt
-    method modify
-    method removeAllRanges
-    method removeRange
-    method selectAllChildren
-    method setBaseAndExtent
-    method setPosition
-    method toString
-interface SendStream : WritableStream
-    attribute @@toStringTag
-    getter writable
-    getter writingAborted
-    method abortWriting
-    method constructor
-interface Sensor : EventTarget
-    attribute @@toStringTag
-    getter activated
-    getter hasReading
-    getter onactivate
-    getter onerror
-    getter onreading
-    getter timestamp
-    method constructor
-    method start
-    method stop
-    setter onactivate
-    setter onerror
-    setter onreading
-interface SensorErrorEvent : Event
-    attribute @@toStringTag
-    getter error
-    method constructor
-interface Serial : EventTarget
-    attribute @@toStringTag
-    getter onconnect
-    getter ondisconnect
-    method constructor
-    method getPorts
-    method requestPort
-    setter onconnect
-    setter ondisconnect
-interface SerialPort : EventTarget
-    attribute @@toStringTag
-    getter onconnect
-    getter ondisconnect
-    getter readable
-    getter writable
-    method close
-    method constructor
-    method getInfo
-    method getSignals
-    method open
-    method setSignals
-    setter onconnect
-    setter ondisconnect
-interface ServiceWorker : EventTarget
-    attribute @@toStringTag
-    getter onerror
-    getter onstatechange
-    getter scriptURL
-    getter state
-    method constructor
-    method postMessage
-    setter onerror
-    setter onstatechange
-interface ServiceWorkerContainer : EventTarget
-    attribute @@toStringTag
-    getter controller
-    getter oncontrollerchange
-    getter onmessage
-    getter onmessageerror
-    getter ready
-    method constructor
-    method getRegistration
-    method getRegistrations
-    method register
-    method startMessages
-    setter oncontrollerchange
-    setter onmessage
-    setter onmessageerror
-interface ServiceWorkerRegistration : EventTarget
-    attribute @@toStringTag
-    getter active
-    getter backgroundFetch
-    getter cookies
-    getter index
-    getter installing
-    getter navigationPreload
-    getter onupdatefound
-    getter paymentManager
-    getter periodicSync
-    getter pushManager
-    getter scope
-    getter sync
-    getter updateViaCache
-    getter waiting
-    method constructor
-    method getNotifications
-    method showNotification
-    method unregister
-    method update
-    setter onupdatefound
-interface ShadowRoot : DocumentFragment
-    attribute @@toStringTag
-    getter activeElement
-    getter adoptedStyleSheets
-    getter delegatesFocus
-    getter fullscreenElement
-    getter host
-    getter innerHTML
-    getter mode
-    getter pictureInPictureElement
-    getter pointerLockElement
-    getter slotAssignment
-    getter styleSheets
-    method constructor
-    method elementFromPoint
-    method elementsFromPoint
-    method getAnimations
-    method getInnerHTML
-    method getSelection
-    setter adoptedStyleSheets
-    setter fullscreenElement
-    setter innerHTML
-interface SharedWorker : EventTarget
-    attribute @@toStringTag
-    getter onerror
-    getter port
-    method constructor
-    setter onerror
-interface SourceBuffer : EventTarget
-    attribute @@toStringTag
-    getter appendWindowEnd
-    getter appendWindowStart
-    getter audioTracks
-    getter buffered
-    getter mode
-    getter onabort
-    getter onerror
-    getter onupdate
-    getter onupdateend
-    getter onupdatestart
-    getter timestampOffset
-    getter trackDefaults
-    getter updating
-    getter videoTracks
-    method abort
-    method appendBuffer
-    method appendEncodedChunks
-    method changeType
-    method constructor
-    method remove
-    setter appendWindowEnd
-    setter appendWindowStart
-    setter mode
-    setter onabort
-    setter onerror
-    setter onupdate
-    setter onupdateend
-    setter onupdatestart
-    setter timestampOffset
-    setter trackDefaults
-interface SourceBufferList : EventTarget
-    attribute @@toStringTag
-    getter length
-    getter onaddsourcebuffer
-    getter onremovesourcebuffer
-    method @@iterator
-    method constructor
-    setter onaddsourcebuffer
-    setter onremovesourcebuffer
-interface SpeechSynthesisErrorEvent : SpeechSynthesisEvent
-    attribute @@toStringTag
-    getter error
-    method constructor
-interface SpeechSynthesisEvent : Event
-    attribute @@toStringTag
-    getter charIndex
-    getter charLength
-    getter elapsedTime
-    getter name
-    getter utterance
-    method constructor
-interface SpeechSynthesisUtterance : EventTarget
-    attribute @@toStringTag
-    getter lang
-    getter onboundary
-    getter onend
-    getter onerror
-    getter onmark
-    getter onpause
-    getter onresume
-    getter onstart
-    getter pitch
-    getter rate
-    getter text
-    getter voice
-    getter volume
-    method constructor
-    setter lang
-    setter onboundary
-    setter onend
-    setter onerror
-    setter onmark
-    setter onpause
-    setter onresume
-    setter onstart
-    setter pitch
-    setter rate
-    setter text
-    setter voice
-    setter volume
-interface StaticRange : AbstractRange
-    attribute @@toStringTag
-    method constructor
-interface StereoPannerNode : AudioNode
-    attribute @@toStringTag
-    getter pan
-    method constructor
-interface Storage
-    attribute @@toStringTag
-    getter length
-    method clear
-    method constructor
-    method getItem
-    method key
-    method removeItem
-    method setItem
-interface StorageBucket
-    attribute @@toStringTag
-    method constructor
-    method durability
-    method estimate
-    method expires
-    method persist
-    method persisted
-    method setExpires
-interface StorageBucketManager
-    attribute @@toStringTag
-    method constructor
-    method delete
-    method keys
-    method open
-interface StorageEvent : Event
-    attribute @@toStringTag
-    getter key
-    getter newValue
-    getter oldValue
-    getter storageArea
-    getter url
-    method constructor
-    method initStorageEvent
-interface StorageManager : EventTarget
-    attribute @@toStringTag
-    getter onquotachange
-    method constructor
-    method estimate
-    method getDirectory
-    method persist
-    method persisted
-    setter onquotachange
-interface StylePropertyMap : StylePropertyMapReadOnly
-    attribute @@toStringTag
-    method append
-    method clear
-    method constructor
-    method delete
-    method set
-interface StylePropertyMapReadOnly
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method getAll
-    method has
-    method keys
-    method values
-interface StyleSheet
-    attribute @@toStringTag
-    getter disabled
-    getter href
-    getter media
-    getter ownerNode
-    getter parentStyleSheet
-    getter title
-    getter type
-    method constructor
-    setter disabled
-    setter media
-interface StyleSheetList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-interface SubmitEvent : Event
-    attribute @@toStringTag
-    getter submitter
-    method constructor
-interface SubtleCrypto
-    attribute @@toStringTag
-    method constructor
-    method decrypt
-    method deriveBits
-    method deriveKey
-    method digest
-    method encrypt
-    method exportKey
-    method generateKey
-    method importKey
-    method sign
-    method unwrapKey
-    method verify
-    method wrapKey
-interface SyncManager
-    attribute @@toStringTag
-    method constructor
-    method getTags
-    method register
-interface TaskAttributionTiming : PerformanceEntry
-    attribute @@toStringTag
-    getter containerId
-    getter containerName
-    getter containerSrc
-    getter containerType
-    method constructor
-    method toJSON
-interface TaskController : AbortController
-    attribute @@toStringTag
-    method constructor
-    method setPriority
-interface TaskPriorityChangeEvent : Event
-    attribute @@toStringTag
-    getter previousPriority
-    method constructor
-interface TaskSignal : AbortSignal
-    attribute @@toStringTag
-    getter onprioritychange
-    getter priority
-    method constructor
-    setter onprioritychange
-interface Text : CharacterData
-    attribute @@toStringTag
-    getter assignedSlot
-    getter wholeText
-    method constructor
-    method splitText
-interface TextDecoder
-    attribute @@toStringTag
-    getter encoding
-    getter fatal
-    getter ignoreBOM
-    method constructor
-    method decode
-interface TextDecoderStream
-    attribute @@toStringTag
-    getter encoding
-    getter fatal
-    getter ignoreBOM
-    getter readable
-    getter writable
-    method constructor
-interface TextDetector
-    attribute @@toStringTag
-    method constructor
-    method detect
-interface TextEncoder
-    attribute @@toStringTag
-    getter encoding
-    method constructor
-    method encode
-    method encodeInto
-interface TextEncoderStream
-    attribute @@toStringTag
-    getter encoding
-    getter readable
-    getter writable
-    method constructor
-interface TextEvent : UIEvent
-    attribute @@toStringTag
-    getter data
-    method constructor
-    method initTextEvent
-interface TextFormatUpdateEvent : Event
-    attribute @@toStringTag
-    getter backgroundColor
-    getter formatRangeEnd
-    getter formatRangeStart
-    getter suggestionHighlightColor
-    getter textColor
-    getter underlineColor
-    getter underlineStyle
-    getter underlineThickness
-    method constructor
-interface TextMetrics
-    attribute @@toStringTag
-    getter actualBoundingBoxAscent
-    getter actualBoundingBoxDescent
-    getter actualBoundingBoxLeft
-    getter actualBoundingBoxRight
-    getter advances
-    getter emHeightAscent
-    getter emHeightDescent
-    getter fontBoundingBoxAscent
-    getter fontBoundingBoxDescent
-    getter width
-    method constructor
-    method getBaselines
-interface TextTrack : EventTarget
-    attribute @@toStringTag
-    getter activeCues
-    getter cues
-    getter id
-    getter kind
-    getter label
-    getter language
-    getter mode
-    getter oncuechange
-    method addCue
-    method constructor
-    method removeCue
-    setter mode
-    setter oncuechange
-interface TextTrackCue : EventTarget
-    attribute @@toStringTag
-    getter endTime
-    getter id
-    getter onenter
-    getter onexit
-    getter pauseOnExit
-    getter startTime
-    getter track
-    method constructor
-    setter endTime
-    setter id
-    setter onenter
-    setter onexit
-    setter pauseOnExit
-    setter startTime
-interface TextTrackCueList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method getCueById
-interface TextTrackList : EventTarget
-    attribute @@toStringTag
-    getter length
-    getter onaddtrack
-    getter onchange
-    getter onremovetrack
-    method @@iterator
-    method constructor
-    method getTrackById
-    setter onaddtrack
-    setter onchange
-    setter onremovetrack
-interface TextUpdateEvent : Event
-    attribute @@toStringTag
-    getter newSelectionEnd
-    getter newSelectionStart
-    getter updateRangeEnd
-    getter updateRangeStart
-    getter updateText
-    method constructor
-interface TimeRanges
-    attribute @@toStringTag
-    getter length
-    method constructor
-    method end
-    method start
-interface TimestampTrigger
-    attribute @@toStringTag
-    getter timestamp
-    method constructor
-interface Touch
-    attribute @@toStringTag
-    getter clientX
-    getter clientY
-    getter force
-    getter identifier
-    getter pageX
-    getter pageY
-    getter radiusX
-    getter radiusY
-    getter region
-    getter rotationAngle
-    getter screenX
-    getter screenY
-    getter target
-    method constructor
-interface TouchEvent : UIEvent
-    attribute @@toStringTag
-    getter altKey
-    getter changedTouches
-    getter ctrlKey
-    getter metaKey
-    getter shiftKey
-    getter targetTouches
-    getter touches
-    method constructor
-interface TouchList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method item
-interface TrackDefault
-    attribute @@toStringTag
-    getter byteStreamTrackID
-    getter kinds
-    getter label
-    getter language
-    getter type
-    method constructor
-interface TrackDefaultList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-interface TrackEvent : Event
-    attribute @@toStringTag
-    getter track
-    method constructor
-interface TransformStream
-    attribute @@toStringTag
-    getter readable
-    getter writable
-    method constructor
-interface TransitionEvent : Event
-    attribute @@toStringTag
-    getter elapsedTime
-    getter propertyName
-    getter pseudoElement
-    method constructor
-interface TreeWalker
-    attribute @@toStringTag
-    getter currentNode
-    getter filter
-    getter root
-    getter whatToShow
-    method constructor
-    method firstChild
-    method lastChild
-    method nextNode
-    method nextSibling
-    method parentNode
-    method previousNode
-    method previousSibling
-    setter currentNode
-interface TrustedHTML
-    attribute @@toStringTag
-    method constructor
-    method toJSON
-    method toString
-interface TrustedScript
-    attribute @@toStringTag
-    method constructor
-    method toJSON
-    method toString
-interface TrustedScriptURL
-    attribute @@toStringTag
-    method constructor
-    method toJSON
-    method toString
-interface TrustedTypePolicy
-    attribute @@toStringTag
-    getter name
-    method constructor
-    method createHTML
-    method createScript
-    method createScriptURL
-interface TrustedTypePolicyFactory : EventTarget
-    attribute @@toStringTag
-    getter defaultPolicy
-    getter emptyHTML
-    getter emptyScript
-    getter onbeforecreatepolicy
-    method constructor
-    method createPolicy
-    method getAttributeType
-    method getPropertyType
-    method getTypeMapping
-    method isHTML
-    method isScript
-    method isScriptURL
-    setter onbeforecreatepolicy
-interface UIEvent : Event
-    attribute @@toStringTag
-    getter detail
-    getter sourceCapabilities
-    getter view
-    getter which
-    method constructor
-    method initUIEvent
-interface URL
-    static method createObjectURL
-    static method revokeObjectURL
-    attribute @@toStringTag
-    getter hash
-    getter host
-    getter hostname
-    getter href
-    getter origin
-    getter password
-    getter pathname
-    getter port
-    getter protocol
-    getter search
-    getter searchParams
-    getter username
-    method constructor
-    method toJSON
-    method toString
-    setter hash
-    setter host
-    setter hostname
-    setter href
-    setter password
-    setter pathname
-    setter port
-    setter protocol
-    setter search
-    setter username
-interface URLPattern
-    attribute @@toStringTag
-    getter hash
-    getter hostname
-    getter password
-    getter pathname
-    getter port
-    getter protocol
-    getter search
-    getter username
-    method constructor
-    method exec
-    method test
-interface URLSearchParams
-    attribute @@toStringTag
-    method @@iterator
-    method append
-    method constructor
-    method delete
-    method entries
-    method forEach
-    method get
-    method getAll
-    method has
-    method keys
-    method set
-    method sort
-    method toString
-    method values
-interface USB : EventTarget
-    attribute @@toStringTag
-    getter onconnect
-    getter ondisconnect
-    method constructor
-    method getDevices
-    method requestDevice
-    setter onconnect
-    setter ondisconnect
-interface USBAlternateInterface
-    attribute @@toStringTag
-    getter alternateSetting
-    getter endpoints
-    getter interfaceClass
-    getter interfaceName
-    getter interfaceProtocol
-    getter interfaceSubclass
-    method constructor
-interface USBConfiguration
-    attribute @@toStringTag
-    getter configurationName
-    getter configurationValue
-    getter interfaces
-    method constructor
-interface USBConnectionEvent : Event
-    attribute @@toStringTag
-    getter device
-    method constructor
-interface USBDevice
-    attribute @@toStringTag
-    getter configuration
-    getter configurations
-    getter deviceClass
-    getter deviceProtocol
-    getter deviceSubclass
-    getter deviceVersionMajor
-    getter deviceVersionMinor
-    getter deviceVersionSubminor
-    getter manufacturerName
-    getter opened
-    getter productId
-    getter productName
-    getter serialNumber
-    getter usbVersionMajor
-    getter usbVersionMinor
-    getter usbVersionSubminor
-    getter vendorId
-    method claimInterface
-    method clearHalt
-    method close
-    method constructor
-    method controlTransferIn
-    method controlTransferOut
-    method isochronousTransferIn
-    method isochronousTransferOut
-    method open
-    method releaseInterface
-    method reset
-    method selectAlternateInterface
-    method selectConfiguration
-    method transferIn
-    method transferOut
-interface USBEndpoint
-    attribute @@toStringTag
-    getter direction
-    getter endpointNumber
-    getter packetSize
-    getter type
-    method constructor
-interface USBInTransferResult
-    attribute @@toStringTag
-    getter data
-    getter status
-    method constructor
-interface USBInterface
-    attribute @@toStringTag
-    getter alternate
-    getter alternates
-    getter claimed
-    getter interfaceNumber
-    method constructor
-interface USBIsochronousInTransferPacket
-    attribute @@toStringTag
-    getter data
-    getter status
-    method constructor
-interface USBIsochronousInTransferResult
-    attribute @@toStringTag
-    getter data
-    getter packets
-    method constructor
-interface USBIsochronousOutTransferPacket
-    attribute @@toStringTag
-    getter bytesWritten
-    getter status
-    method constructor
-interface USBIsochronousOutTransferResult
-    attribute @@toStringTag
-    getter packets
-    method constructor
-interface USBOutTransferResult
-    attribute @@toStringTag
-    getter bytesWritten
-    getter status
-    method constructor
-interface UserActivation
-    attribute @@toStringTag
-    getter hasBeenActive
-    getter isActive
-    method constructor
-interface VTTCue : TextTrackCue
-    attribute @@toStringTag
-    getter align
-    getter line
-    getter position
-    getter region
-    getter size
-    getter snapToLines
-    getter text
-    getter vertical
-    method constructor
-    method getCueAsHTML
-    setter align
-    setter line
-    setter position
-    setter region
-    setter size
-    setter snapToLines
-    setter text
-    setter vertical
-interface VTTRegion
-    attribute @@toStringTag
-    getter id
-    getter lines
-    getter regionAnchorX
-    getter regionAnchorY
-    getter scroll
-    getter viewportAnchorX
-    getter viewportAnchorY
-    getter width
-    method constructor
-    setter id
-    setter lines
-    setter regionAnchorX
-    setter regionAnchorY
-    setter scroll
-    setter viewportAnchorX
-    setter viewportAnchorY
-    setter width
-interface ValidityState
-    attribute @@toStringTag
-    getter badInput
-    getter customError
-    getter patternMismatch
-    getter rangeOverflow
-    getter rangeUnderflow
-    getter stepMismatch
-    getter tooLong
-    getter tooShort
-    getter typeMismatch
-    getter valid
-    getter valueMissing
-    method constructor
-interface VideoDecoder
-    static method isConfigSupported
-    attribute @@toStringTag
-    getter decodeQueueSize
-    getter state
-    method close
-    method configure
-    method constructor
-    method decode
-    method flush
-    method reset
-interface VideoEncoder
-    static method isConfigSupported
-    attribute @@toStringTag
-    getter encodeQueueSize
-    getter state
-    method close
-    method configure
-    method constructor
-    method encode
-    method flush
-    method reset
-interface VideoFrame
-    attribute @@toStringTag
-    getter codedHeight
-    getter codedRect
-    getter codedRegion
-    getter codedWidth
-    getter cropHeight
-    getter cropLeft
-    getter cropTop
-    getter cropWidth
-    getter displayHeight
-    getter displayWidth
-    getter duration
-    getter format
-    getter planes
-    getter timestamp
-    getter visibleRect
-    getter visibleRegion
-    method allocationSize
-    method clone
-    method close
-    method constructor
-    method copyTo
-interface VideoPlaybackQuality
-    attribute @@toStringTag
-    getter corruptedVideoFrames
-    getter creationTime
-    getter droppedVideoFrames
-    getter totalVideoFrames
-    method constructor
-interface VideoTrack
-    attribute @@toStringTag
-    getter id
-    getter kind
-    getter label
-    getter language
-    getter selected
-    getter sourceBuffer
-    method constructor
-    setter selected
-interface VideoTrackList : EventTarget
-    attribute @@toStringTag
-    getter length
-    getter onaddtrack
-    getter onchange
-    getter onremovetrack
-    getter selectedIndex
-    method @@iterator
-    method constructor
-    method getTrackById
-    setter onaddtrack
-    setter onchange
-    setter onremovetrack
-interface VirtualKeyboard : EventTarget
-    attribute @@toStringTag
-    getter boundingRect
-    getter ongeometrychange
-    getter overlaysContent
-    method constructor
-    method hide
-    method show
-    setter ongeometrychange
-    setter overlaysContent
-interface VirtualKeyboardGeometryChangeEvent : Event
-    attribute @@toStringTag
-    method constructor
-interface VisibilityStateEntry : PerformanceEntry
-    attribute @@toStringTag
-    method constructor
-interface VisualViewport : EventTarget
-    attribute @@toStringTag
-    getter height
-    getter offsetLeft
-    getter offsetTop
-    getter onresize
-    getter onscroll
-    getter pageLeft
-    getter pageTop
-    getter scale
-    getter width
-    method constructor
-    setter onresize
-    setter onscroll
-interface WakeLock
-    attribute @@toStringTag
-    method constructor
-    method request
-interface WakeLockSentinel : EventTarget
-    attribute @@toStringTag
-    getter onrelease
-    getter released
-    getter type
-    method constructor
-    method release
-    setter onrelease
-interface WaveShaperNode : AudioNode
-    attribute @@toStringTag
-    getter curve
-    getter oversample
-    method constructor
-    setter curve
-    setter oversample
-interface WebGL2RenderingContext
-    attribute @@toStringTag
-    attribute ACTIVE_ATTRIBUTES
-    attribute ACTIVE_TEXTURE
-    attribute ACTIVE_UNIFORMS
-    attribute ACTIVE_UNIFORM_BLOCKS
-    attribute ALIASED_LINE_WIDTH_RANGE
-    attribute ALIASED_POINT_SIZE_RANGE
-    attribute ALPHA
-    attribute ALPHA_BITS
-    attribute ALREADY_SIGNALED
-    attribute ALWAYS
-    attribute ANY_SAMPLES_PASSED
-    attribute ANY_SAMPLES_PASSED_CONSERVATIVE
-    attribute ARRAY_BUFFER
-    attribute ARRAY_BUFFER_BINDING
-    attribute ATTACHED_SHADERS
-    attribute BACK
-    attribute BLEND
-    attribute BLEND_COLOR
-    attribute BLEND_DST_ALPHA
-    attribute BLEND_DST_RGB
-    attribute BLEND_EQUATION
-    attribute BLEND_EQUATION_ALPHA
-    attribute BLEND_EQUATION_RGB
-    attribute BLEND_SRC_ALPHA
-    attribute BLEND_SRC_RGB
-    attribute BLUE_BITS
-    attribute BOOL
-    attribute BOOL_VEC2
-    attribute BOOL_VEC3
-    attribute BOOL_VEC4
-    attribute BROWSER_DEFAULT_WEBGL
-    attribute BUFFER_SIZE
-    attribute BUFFER_USAGE
-    attribute BYTE
-    attribute CCW
-    attribute CLAMP_TO_EDGE
-    attribute COLOR
-    attribute COLOR_ATTACHMENT0
-    attribute COLOR_ATTACHMENT1
-    attribute COLOR_ATTACHMENT10
-    attribute COLOR_ATTACHMENT11
-    attribute COLOR_ATTACHMENT12
-    attribute COLOR_ATTACHMENT13
-    attribute COLOR_ATTACHMENT14
-    attribute COLOR_ATTACHMENT15
-    attribute COLOR_ATTACHMENT2
-    attribute COLOR_ATTACHMENT3
-    attribute COLOR_ATTACHMENT4
-    attribute COLOR_ATTACHMENT5
-    attribute COLOR_ATTACHMENT6
-    attribute COLOR_ATTACHMENT7
-    attribute COLOR_ATTACHMENT8
-    attribute COLOR_ATTACHMENT9
-    attribute COLOR_BUFFER_BIT
-    attribute COLOR_CLEAR_VALUE
-    attribute COLOR_WRITEMASK
-    attribute COMPARE_REF_TO_TEXTURE
-    attribute COMPILE_STATUS
-    attribute COMPRESSED_TEXTURE_FORMATS
-    attribute CONDITION_SATISFIED
-    attribute CONSTANT_ALPHA
-    attribute CONSTANT_COLOR
-    attribute CONTEXT_LOST_WEBGL
-    attribute COPY_READ_BUFFER
-    attribute COPY_READ_BUFFER_BINDING
-    attribute COPY_WRITE_BUFFER
-    attribute COPY_WRITE_BUFFER_BINDING
-    attribute CULL_FACE
-    attribute CULL_FACE_MODE
-    attribute CURRENT_PROGRAM
-    attribute CURRENT_QUERY
-    attribute CURRENT_VERTEX_ATTRIB
-    attribute CW
-    attribute DECR
-    attribute DECR_WRAP
-    attribute DELETE_STATUS
-    attribute DEPTH
-    attribute DEPTH24_STENCIL8
-    attribute DEPTH32F_STENCIL8
-    attribute DEPTH_ATTACHMENT
-    attribute DEPTH_BITS
-    attribute DEPTH_BUFFER_BIT
-    attribute DEPTH_CLEAR_VALUE
-    attribute DEPTH_COMPONENT
-    attribute DEPTH_COMPONENT16
-    attribute DEPTH_COMPONENT24
-    attribute DEPTH_COMPONENT32F
-    attribute DEPTH_FUNC
-    attribute DEPTH_RANGE
-    attribute DEPTH_STENCIL
-    attribute DEPTH_STENCIL_ATTACHMENT
-    attribute DEPTH_TEST
-    attribute DEPTH_WRITEMASK
-    attribute DITHER
-    attribute DONT_CARE
-    attribute DRAW_BUFFER0
-    attribute DRAW_BUFFER1
-    attribute DRAW_BUFFER10
-    attribute DRAW_BUFFER11
-    attribute DRAW_BUFFER12
-    attribute DRAW_BUFFER13
-    attribute DRAW_BUFFER14
-    attribute DRAW_BUFFER15
-    attribute DRAW_BUFFER2
-    attribute DRAW_BUFFER3
-    attribute DRAW_BUFFER4
-    attribute DRAW_BUFFER5
-    attribute DRAW_BUFFER6
-    attribute DRAW_BUFFER7
-    attribute DRAW_BUFFER8
-    attribute DRAW_BUFFER9
-    attribute DRAW_FRAMEBUFFER
-    attribute DRAW_FRAMEBUFFER_BINDING
-    attribute DST_ALPHA
-    attribute DST_COLOR
-    attribute DYNAMIC_COPY
-    attribute DYNAMIC_DRAW
-    attribute DYNAMIC_READ
-    attribute ELEMENT_ARRAY_BUFFER
-    attribute ELEMENT_ARRAY_BUFFER_BINDING
-    attribute EQUAL
-    attribute FASTEST
-    attribute FLOAT
-    attribute FLOAT_32_UNSIGNED_INT_24_8_REV
-    attribute FLOAT_MAT2
-    attribute FLOAT_MAT2x3
-    attribute FLOAT_MAT2x4
-    attribute FLOAT_MAT3
-    attribute FLOAT_MAT3x2
-    attribute FLOAT_MAT3x4
-    attribute FLOAT_MAT4
-    attribute FLOAT_MAT4x2
-    attribute FLOAT_MAT4x3
-    attribute FLOAT_VEC2
-    attribute FLOAT_VEC3
-    attribute FLOAT_VEC4
-    attribute FRAGMENT_SHADER
-    attribute FRAGMENT_SHADER_DERIVATIVE_HINT
-    attribute FRAMEBUFFER
-    attribute FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_BLUE_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
-    attribute FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE
-    attribute FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_GREEN_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
-    attribute FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
-    attribute FRAMEBUFFER_ATTACHMENT_RED_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE
-    attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
-    attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER
-    attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
-    attribute FRAMEBUFFER_BINDING
-    attribute FRAMEBUFFER_COMPLETE
-    attribute FRAMEBUFFER_DEFAULT
-    attribute FRAMEBUFFER_INCOMPLETE_ATTACHMENT
-    attribute FRAMEBUFFER_INCOMPLETE_DIMENSIONS
-    attribute FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
-    attribute FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
-    attribute FRAMEBUFFER_UNSUPPORTED
-    attribute FRONT
-    attribute FRONT_AND_BACK
-    attribute FRONT_FACE
-    attribute FUNC_ADD
-    attribute FUNC_REVERSE_SUBTRACT
-    attribute FUNC_SUBTRACT
-    attribute GENERATE_MIPMAP_HINT
-    attribute GEQUAL
-    attribute GREATER
-    attribute GREEN_BITS
-    attribute HALF_FLOAT
-    attribute HIGH_FLOAT
-    attribute HIGH_INT
-    attribute IMPLEMENTATION_COLOR_READ_FORMAT
-    attribute IMPLEMENTATION_COLOR_READ_TYPE
-    attribute INCR
-    attribute INCR_WRAP
-    attribute INT
-    attribute INTERLEAVED_ATTRIBS
-    attribute INT_2_10_10_10_REV
-    attribute INT_SAMPLER_2D
-    attribute INT_SAMPLER_2D_ARRAY
-    attribute INT_SAMPLER_3D
-    attribute INT_SAMPLER_CUBE
-    attribute INT_VEC2
-    attribute INT_VEC3
-    attribute INT_VEC4
-    attribute INVALID_ENUM
-    attribute INVALID_FRAMEBUFFER_OPERATION
-    attribute INVALID_INDEX
-    attribute INVALID_OPERATION
-    attribute INVALID_VALUE
-    attribute INVERT
-    attribute KEEP
-    attribute LEQUAL
-    attribute LESS
-    attribute LINEAR
-    attribute LINEAR_MIPMAP_LINEAR
-    attribute LINEAR_MIPMAP_NEAREST
-    attribute LINES
-    attribute LINE_LOOP
-    attribute LINE_STRIP
-    attribute LINE_WIDTH
-    attribute LINK_STATUS
-    attribute LOW_FLOAT
-    attribute LOW_INT
-    attribute LUMINANCE
-    attribute LUMINANCE_ALPHA
-    attribute MAX
-    attribute MAX_3D_TEXTURE_SIZE
-    attribute MAX_ARRAY_TEXTURE_LAYERS
-    attribute MAX_CLIENT_WAIT_TIMEOUT_WEBGL
-    attribute MAX_COLOR_ATTACHMENTS
-    attribute MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS
-    attribute MAX_COMBINED_TEXTURE_IMAGE_UNITS
-    attribute MAX_COMBINED_UNIFORM_BLOCKS
-    attribute MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS
-    attribute MAX_CUBE_MAP_TEXTURE_SIZE
-    attribute MAX_DRAW_BUFFERS
-    attribute MAX_ELEMENTS_INDICES
-    attribute MAX_ELEMENTS_VERTICES
-    attribute MAX_ELEMENT_INDEX
-    attribute MAX_FRAGMENT_INPUT_COMPONENTS
-    attribute MAX_FRAGMENT_UNIFORM_BLOCKS
-    attribute MAX_FRAGMENT_UNIFORM_COMPONENTS
-    attribute MAX_FRAGMENT_UNIFORM_VECTORS
-    attribute MAX_PROGRAM_TEXEL_OFFSET
-    attribute MAX_RENDERBUFFER_SIZE
-    attribute MAX_SAMPLES
-    attribute MAX_SERVER_WAIT_TIMEOUT
-    attribute MAX_TEXTURE_IMAGE_UNITS
-    attribute MAX_TEXTURE_LOD_BIAS
-    attribute MAX_TEXTURE_SIZE
-    attribute MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS
-    attribute MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS
-    attribute MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS
-    attribute MAX_UNIFORM_BLOCK_SIZE
-    attribute MAX_UNIFORM_BUFFER_BINDINGS
-    attribute MAX_VARYING_COMPONENTS
-    attribute MAX_VARYING_VECTORS
-    attribute MAX_VERTEX_ATTRIBS
-    attribute MAX_VERTEX_OUTPUT_COMPONENTS
-    attribute MAX_VERTEX_TEXTURE_IMAGE_UNITS
-    attribute MAX_VERTEX_UNIFORM_BLOCKS
-    attribute MAX_VERTEX_UNIFORM_COMPONENTS
-    attribute MAX_VERTEX_UNIFORM_VECTORS
-    attribute MAX_VIEWPORT_DIMS
-    attribute MEDIUM_FLOAT
-    attribute MEDIUM_INT
-    attribute MIN
-    attribute MIN_PROGRAM_TEXEL_OFFSET
-    attribute MIRRORED_REPEAT
-    attribute NEAREST
-    attribute NEAREST_MIPMAP_LINEAR
-    attribute NEAREST_MIPMAP_NEAREST
-    attribute NEVER
-    attribute NICEST
-    attribute NONE
-    attribute NOTEQUAL
-    attribute NO_ERROR
-    attribute OBJECT_TYPE
-    attribute ONE
-    attribute ONE_MINUS_CONSTANT_ALPHA
-    attribute ONE_MINUS_CONSTANT_COLOR
-    attribute ONE_MINUS_DST_ALPHA
-    attribute ONE_MINUS_DST_COLOR
-    attribute ONE_MINUS_SRC_ALPHA
-    attribute ONE_MINUS_SRC_COLOR
-    attribute OUT_OF_MEMORY
-    attribute PACK_ALIGNMENT
-    attribute PACK_ROW_LENGTH
-    attribute PACK_SKIP_PIXELS
-    attribute PACK_SKIP_ROWS
-    attribute PIXEL_PACK_BUFFER
-    attribute PIXEL_PACK_BUFFER_BINDING
-    attribute PIXEL_UNPACK_BUFFER
-    attribute PIXEL_UNPACK_BUFFER_BINDING
-    attribute POINTS
-    attribute POLYGON_OFFSET_FACTOR
-    attribute POLYGON_OFFSET_FILL
-    attribute POLYGON_OFFSET_UNITS
-    attribute QUERY_RESULT
-    attribute QUERY_RESULT_AVAILABLE
-    attribute R11F_G11F_B10F
-    attribute R16F
-    attribute R16I
-    attribute R16UI
-    attribute R32F
-    attribute R32I
-    attribute R32UI
-    attribute R8
-    attribute R8I
-    attribute R8UI
-    attribute R8_SNORM
-    attribute RASTERIZER_DISCARD
-    attribute READ_BUFFER
-    attribute READ_FRAMEBUFFER
-    attribute READ_FRAMEBUFFER_BINDING
-    attribute RED
-    attribute RED_BITS
-    attribute RED_INTEGER
-    attribute RENDERBUFFER
-    attribute RENDERBUFFER_ALPHA_SIZE
-    attribute RENDERBUFFER_BINDING
-    attribute RENDERBUFFER_BLUE_SIZE
-    attribute RENDERBUFFER_DEPTH_SIZE
-    attribute RENDERBUFFER_GREEN_SIZE
-    attribute RENDERBUFFER_HEIGHT
-    attribute RENDERBUFFER_INTERNAL_FORMAT
-    attribute RENDERBUFFER_RED_SIZE
-    attribute RENDERBUFFER_SAMPLES
-    attribute RENDERBUFFER_STENCIL_SIZE
-    attribute RENDERBUFFER_WIDTH
-    attribute RENDERER
-    attribute REPEAT
-    attribute REPLACE
-    attribute RG
-    attribute RG16F
-    attribute RG16I
-    attribute RG16UI
-    attribute RG32F
-    attribute RG32I
-    attribute RG32UI
-    attribute RG8
-    attribute RG8I
-    attribute RG8UI
-    attribute RG8_SNORM
-    attribute RGB
-    attribute RGB10_A2
-    attribute RGB10_A2UI
-    attribute RGB16F
-    attribute RGB16I
-    attribute RGB16UI
-    attribute RGB32F
-    attribute RGB32I
-    attribute RGB32UI
-    attribute RGB565
-    attribute RGB5_A1
-    attribute RGB8
-    attribute RGB8I
-    attribute RGB8UI
-    attribute RGB8_SNORM
-    attribute RGB9_E5
-    attribute RGBA
-    attribute RGBA16F
-    attribute RGBA16I
-    attribute RGBA16UI
-    attribute RGBA32F
-    attribute RGBA32I
-    attribute RGBA32UI
-    attribute RGBA4
-    attribute RGBA8
-    attribute RGBA8I
-    attribute RGBA8UI
-    attribute RGBA8_SNORM
-    attribute RGBA_INTEGER
-    attribute RGB_INTEGER
-    attribute RG_INTEGER
-    attribute SAMPLER_2D
-    attribute SAMPLER_2D_ARRAY
-    attribute SAMPLER_2D_ARRAY_SHADOW
-    attribute SAMPLER_2D_SHADOW
-    attribute SAMPLER_3D
-    attribute SAMPLER_BINDING
-    attribute SAMPLER_CUBE
-    attribute SAMPLER_CUBE_SHADOW
-    attribute SAMPLES
-    attribute SAMPLE_ALPHA_TO_COVERAGE
-    attribute SAMPLE_BUFFERS
-    attribute SAMPLE_COVERAGE
-    attribute SAMPLE_COVERAGE_INVERT
-    attribute SAMPLE_COVERAGE_VALUE
-    attribute SCISSOR_BOX
-    attribute SCISSOR_TEST
-    attribute SEPARATE_ATTRIBS
-    attribute SHADER_TYPE
-    attribute SHADING_LANGUAGE_VERSION
-    attribute SHORT
-    attribute SIGNALED
-    attribute SIGNED_NORMALIZED
-    attribute SRC_ALPHA
-    attribute SRC_ALPHA_SATURATE
-    attribute SRC_COLOR
-    attribute SRGB
-    attribute SRGB8
-    attribute SRGB8_ALPHA8
-    attribute STATIC_COPY
-    attribute STATIC_DRAW
-    attribute STATIC_READ
-    attribute STENCIL
-    attribute STENCIL_ATTACHMENT
-    attribute STENCIL_BACK_FAIL
-    attribute STENCIL_BACK_FUNC
-    attribute STENCIL_BACK_PASS_DEPTH_FAIL
-    attribute STENCIL_BACK_PASS_DEPTH_PASS
-    attribute STENCIL_BACK_REF
-    attribute STENCIL_BACK_VALUE_MASK
-    attribute STENCIL_BACK_WRITEMASK
-    attribute STENCIL_BITS
-    attribute STENCIL_BUFFER_BIT
-    attribute STENCIL_CLEAR_VALUE
-    attribute STENCIL_FAIL
-    attribute STENCIL_FUNC
-    attribute STENCIL_INDEX8
-    attribute STENCIL_PASS_DEPTH_FAIL
-    attribute STENCIL_PASS_DEPTH_PASS
-    attribute STENCIL_REF
-    attribute STENCIL_TEST
-    attribute STENCIL_VALUE_MASK
-    attribute STENCIL_WRITEMASK
-    attribute STREAM_COPY
-    attribute STREAM_DRAW
-    attribute STREAM_READ
-    attribute SUBPIXEL_BITS
-    attribute SYNC_CONDITION
-    attribute SYNC_FENCE
-    attribute SYNC_FLAGS
-    attribute SYNC_FLUSH_COMMANDS_BIT
-    attribute SYNC_GPU_COMMANDS_COMPLETE
-    attribute SYNC_STATUS
-    attribute TEXTURE
-    attribute TEXTURE0
-    attribute TEXTURE1
-    attribute TEXTURE10
-    attribute TEXTURE11
-    attribute TEXTURE12
-    attribute TEXTURE13
-    attribute TEXTURE14
-    attribute TEXTURE15
-    attribute TEXTURE16
-    attribute TEXTURE17
-    attribute TEXTURE18
-    attribute TEXTURE19
-    attribute TEXTURE2
-    attribute TEXTURE20
-    attribute TEXTURE21
-    attribute TEXTURE22
-    attribute TEXTURE23
-    attribute TEXTURE24
-    attribute TEXTURE25
-    attribute TEXTURE26
-    attribute TEXTURE27
-    attribute TEXTURE28
-    attribute TEXTURE29
-    attribute TEXTURE3
-    attribute TEXTURE30
-    attribute TEXTURE31
-    attribute TEXTURE4
-    attribute TEXTURE5
-    attribute TEXTURE6
-    attribute TEXTURE7
-    attribute TEXTURE8
-    attribute TEXTURE9
-    attribute TEXTURE_2D
-    attribute TEXTURE_2D_ARRAY
-    attribute TEXTURE_3D
-    attribute TEXTURE_BASE_LEVEL
-    attribute TEXTURE_BINDING_2D
-    attribute TEXTURE_BINDING_2D_ARRAY
-    attribute TEXTURE_BINDING_3D
-    attribute TEXTURE_BINDING_CUBE_MAP
-    attribute TEXTURE_COMPARE_FUNC
-    attribute TEXTURE_COMPARE_MODE
-    attribute TEXTURE_CUBE_MAP
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_X
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_Y
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_Z
-    attribute TEXTURE_CUBE_MAP_POSITIVE_X
-    attribute TEXTURE_CUBE_MAP_POSITIVE_Y
-    attribute TEXTURE_CUBE_MAP_POSITIVE_Z
-    attribute TEXTURE_IMMUTABLE_FORMAT
-    attribute TEXTURE_IMMUTABLE_LEVELS
-    attribute TEXTURE_MAG_FILTER
-    attribute TEXTURE_MAX_LEVEL
-    attribute TEXTURE_MAX_LOD
-    attribute TEXTURE_MIN_FILTER
-    attribute TEXTURE_MIN_LOD
-    attribute TEXTURE_WRAP_R
-    attribute TEXTURE_WRAP_S
-    attribute TEXTURE_WRAP_T
-    attribute TIMEOUT_EXPIRED
-    attribute TIMEOUT_IGNORED
-    attribute TRANSFORM_FEEDBACK
-    attribute TRANSFORM_FEEDBACK_ACTIVE
-    attribute TRANSFORM_FEEDBACK_BINDING
-    attribute TRANSFORM_FEEDBACK_BUFFER
-    attribute TRANSFORM_FEEDBACK_BUFFER_BINDING
-    attribute TRANSFORM_FEEDBACK_BUFFER_MODE
-    attribute TRANSFORM_FEEDBACK_BUFFER_SIZE
-    attribute TRANSFORM_FEEDBACK_BUFFER_START
-    attribute TRANSFORM_FEEDBACK_PAUSED
-    attribute TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
-    attribute TRANSFORM_FEEDBACK_VARYINGS
-    attribute TRIANGLES
-    attribute TRIANGLE_FAN
-    attribute TRIANGLE_STRIP
-    attribute UNIFORM_ARRAY_STRIDE
-    attribute UNIFORM_BLOCK_ACTIVE_UNIFORMS
-    attribute UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
-    attribute UNIFORM_BLOCK_BINDING
-    attribute UNIFORM_BLOCK_DATA_SIZE
-    attribute UNIFORM_BLOCK_INDEX
-    attribute UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
-    attribute UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER
-    attribute UNIFORM_BUFFER
-    attribute UNIFORM_BUFFER_BINDING
-    attribute UNIFORM_BUFFER_OFFSET_ALIGNMENT
-    attribute UNIFORM_BUFFER_SIZE
-    attribute UNIFORM_BUFFER_START
-    attribute UNIFORM_IS_ROW_MAJOR
-    attribute UNIFORM_MATRIX_STRIDE
-    attribute UNIFORM_OFFSET
-    attribute UNIFORM_SIZE
-    attribute UNIFORM_TYPE
-    attribute UNPACK_ALIGNMENT
-    attribute UNPACK_COLORSPACE_CONVERSION_WEBGL
-    attribute UNPACK_FLIP_Y_WEBGL
-    attribute UNPACK_IMAGE_HEIGHT
-    attribute UNPACK_PREMULTIPLY_ALPHA_WEBGL
-    attribute UNPACK_ROW_LENGTH
-    attribute UNPACK_SKIP_IMAGES
-    attribute UNPACK_SKIP_PIXELS
-    attribute UNPACK_SKIP_ROWS
-    attribute UNSIGNALED
-    attribute UNSIGNED_BYTE
-    attribute UNSIGNED_INT
-    attribute UNSIGNED_INT_10F_11F_11F_REV
-    attribute UNSIGNED_INT_24_8
-    attribute UNSIGNED_INT_2_10_10_10_REV
-    attribute UNSIGNED_INT_5_9_9_9_REV
-    attribute UNSIGNED_INT_SAMPLER_2D
-    attribute UNSIGNED_INT_SAMPLER_2D_ARRAY
-    attribute UNSIGNED_INT_SAMPLER_3D
-    attribute UNSIGNED_INT_SAMPLER_CUBE
-    attribute UNSIGNED_INT_VEC2
-    attribute UNSIGNED_INT_VEC3
-    attribute UNSIGNED_INT_VEC4
-    attribute UNSIGNED_NORMALIZED
-    attribute UNSIGNED_SHORT
-    attribute UNSIGNED_SHORT_4_4_4_4
-    attribute UNSIGNED_SHORT_5_5_5_1
-    attribute UNSIGNED_SHORT_5_6_5
-    attribute VALIDATE_STATUS
-    attribute VENDOR
-    attribute VERSION
-    attribute VERTEX_ARRAY_BINDING
-    attribute VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
-    attribute VERTEX_ATTRIB_ARRAY_DIVISOR
-    attribute VERTEX_ATTRIB_ARRAY_ENABLED
-    attribute VERTEX_ATTRIB_ARRAY_INTEGER
-    attribute VERTEX_ATTRIB_ARRAY_NORMALIZED
-    attribute VERTEX_ATTRIB_ARRAY_POINTER
-    attribute VERTEX_ATTRIB_ARRAY_SIZE
-    attribute VERTEX_ATTRIB_ARRAY_STRIDE
-    attribute VERTEX_ATTRIB_ARRAY_TYPE
-    attribute VERTEX_SHADER
-    attribute VIEWPORT
-    attribute WAIT_FAILED
-    attribute ZERO
-    getter canvas
-    getter drawingBufferHeight
-    getter drawingBufferWidth
-    method activeTexture
-    method attachShader
-    method beginQuery
-    method beginTransformFeedback
-    method bindAttribLocation
-    method bindBuffer
-    method bindBufferBase
-    method bindBufferRange
-    method bindFramebuffer
-    method bindRenderbuffer
-    method bindSampler
-    method bindTexture
-    method bindTransformFeedback
-    method bindVertexArray
-    method blendColor
-    method blendEquation
-    method blendEquationSeparate
-    method blendFunc
-    method blendFuncSeparate
-    method blitFramebuffer
-    method bufferData
-    method bufferSubData
-    method checkFramebufferStatus
-    method clear
-    method clearBufferfi
-    method clearBufferfv
-    method clearBufferiv
-    method clearBufferuiv
-    method clearColor
-    method clearDepth
-    method clearStencil
-    method clientWaitSync
-    method colorMask
-    method commit
-    method compileShader
-    method compressedTexImage2D
-    method compressedTexImage3D
-    method compressedTexSubImage2D
-    method compressedTexSubImage3D
-    method constructor
-    method copyBufferSubData
-    method copyTexImage2D
-    method copyTexSubImage2D
-    method copyTexSubImage3D
-    method createBuffer
-    method createFramebuffer
-    method createProgram
-    method createQuery
-    method createRenderbuffer
-    method createSampler
-    method createShader
-    method createTexture
-    method createTransformFeedback
-    method createVertexArray
-    method cullFace
-    method deleteBuffer
-    method deleteFramebuffer
-    method deleteProgram
-    method deleteQuery
-    method deleteRenderbuffer
-    method deleteSampler
-    method deleteShader
-    method deleteSync
-    method deleteTexture
-    method deleteTransformFeedback
-    method deleteVertexArray
-    method depthFunc
-    method depthMask
-    method depthRange
-    method detachShader
-    method disable
-    method disableVertexAttribArray
-    method drawArrays
-    method drawArraysInstanced
-    method drawBuffers
-    method drawElements
-    method drawElementsInstanced
-    method drawRangeElements
-    method enable
-    method enableVertexAttribArray
-    method endQuery
-    method endTransformFeedback
-    method fenceSync
-    method finish
-    method flush
-    method framebufferRenderbuffer
-    method framebufferTexture2D
-    method framebufferTextureLayer
-    method frontFace
-    method generateMipmap
-    method getActiveAttrib
-    method getActiveUniform
-    method getActiveUniformBlockName
-    method getActiveUniformBlockParameter
-    method getActiveUniforms
-    method getAttachedShaders
-    method getAttribLocation
-    method getBufferParameter
-    method getBufferSubData
-    method getContextAttributes
-    method getError
-    method getExtension
-    method getFragDataLocation
-    method getFramebufferAttachmentParameter
-    method getIndexedParameter
-    method getInternalformatParameter
-    method getParameter
-    method getProgramInfoLog
-    method getProgramParameter
-    method getQuery
-    method getQueryParameter
-    method getRenderbufferParameter
-    method getSamplerParameter
-    method getShaderInfoLog
-    method getShaderParameter
-    method getShaderPrecisionFormat
-    method getShaderSource
-    method getSupportedExtensions
-    method getSyncParameter
-    method getTexParameter
-    method getTransformFeedbackVarying
-    method getUniform
-    method getUniformBlockIndex
-    method getUniformIndices
-    method getUniformLocation
-    method getVertexAttrib
-    method getVertexAttribOffset
-    method hint
-    method invalidateFramebuffer
-    method invalidateSubFramebuffer
-    method isBuffer
-    method isContextLost
-    method isEnabled
-    method isFramebuffer
-    method isProgram
-    method isQuery
-    method isRenderbuffer
-    method isSampler
-    method isShader
-    method isSync
-    method isTexture
-    method isTransformFeedback
-    method isVertexArray
-    method lineWidth
-    method linkProgram
-    method makeXRCompatible
-    method pauseTransformFeedback
-    method pixelStorei
-    method polygonOffset
-    method readBuffer
-    method readPixels
-    method renderbufferStorage
-    method renderbufferStorageMultisample
-    method resumeTransformFeedback
-    method sampleCoverage
-    method samplerParameterf
-    method samplerParameteri
-    method scissor
-    method shaderSource
-    method stencilFunc
-    method stencilFuncSeparate
-    method stencilMask
-    method stencilMaskSeparate
-    method stencilOp
-    method stencilOpSeparate
-    method texImage2D
-    method texImage3D
-    method texParameterf
-    method texParameteri
-    method texStorage2D
-    method texStorage3D
-    method texSubImage2D
-    method texSubImage3D
-    method transformFeedbackVaryings
-    method uniform1f
-    method uniform1fv
-    method uniform1i
-    method uniform1iv
-    method uniform1ui
-    method uniform1uiv
-    method uniform2f
-    method uniform2fv
-    method uniform2i
-    method uniform2iv
-    method uniform2ui
-    method uniform2uiv
-    method uniform3f
-    method uniform3fv
-    method uniform3i
-    method uniform3iv
-    method uniform3ui
-    method uniform3uiv
-    method uniform4f
-    method uniform4fv
-    method uniform4i
-    method uniform4iv
-    method uniform4ui
-    method uniform4uiv
-    method uniformBlockBinding
-    method uniformMatrix2fv
-    method uniformMatrix2x3fv
-    method uniformMatrix2x4fv
-    method uniformMatrix3fv
-    method uniformMatrix3x2fv
-    method uniformMatrix3x4fv
-    method uniformMatrix4fv
-    method uniformMatrix4x2fv
-    method uniformMatrix4x3fv
-    method useProgram
-    method validateProgram
-    method vertexAttrib1f
-    method vertexAttrib1fv
-    method vertexAttrib2f
-    method vertexAttrib2fv
-    method vertexAttrib3f
-    method vertexAttrib3fv
-    method vertexAttrib4f
-    method vertexAttrib4fv
-    method vertexAttribDivisor
-    method vertexAttribI4i
-    method vertexAttribI4iv
-    method vertexAttribI4ui
-    method vertexAttribI4uiv
-    method vertexAttribIPointer
-    method vertexAttribPointer
-    method viewport
-    method waitSync
-interface WebGLActiveInfo
-    attribute @@toStringTag
-    getter name
-    getter size
-    getter type
-    method constructor
-interface WebGLBuffer
-    attribute @@toStringTag
-    method constructor
-interface WebGLContextEvent : Event
-    attribute @@toStringTag
-    getter statusMessage
-    method constructor
-interface WebGLFramebuffer
-    attribute @@toStringTag
-    method constructor
-interface WebGLProgram
-    attribute @@toStringTag
-    method constructor
-interface WebGLQuery
-    attribute @@toStringTag
-    method constructor
-interface WebGLRenderbuffer
-    attribute @@toStringTag
-    method constructor
-interface WebGLRenderingContext
-    attribute @@toStringTag
-    attribute ACTIVE_ATTRIBUTES
-    attribute ACTIVE_TEXTURE
-    attribute ACTIVE_UNIFORMS
-    attribute ALIASED_LINE_WIDTH_RANGE
-    attribute ALIASED_POINT_SIZE_RANGE
-    attribute ALPHA
-    attribute ALPHA_BITS
-    attribute ALWAYS
-    attribute ARRAY_BUFFER
-    attribute ARRAY_BUFFER_BINDING
-    attribute ATTACHED_SHADERS
-    attribute BACK
-    attribute BLEND
-    attribute BLEND_COLOR
-    attribute BLEND_DST_ALPHA
-    attribute BLEND_DST_RGB
-    attribute BLEND_EQUATION
-    attribute BLEND_EQUATION_ALPHA
-    attribute BLEND_EQUATION_RGB
-    attribute BLEND_SRC_ALPHA
-    attribute BLEND_SRC_RGB
-    attribute BLUE_BITS
-    attribute BOOL
-    attribute BOOL_VEC2
-    attribute BOOL_VEC3
-    attribute BOOL_VEC4
-    attribute BROWSER_DEFAULT_WEBGL
-    attribute BUFFER_SIZE
-    attribute BUFFER_USAGE
-    attribute BYTE
-    attribute CCW
-    attribute CLAMP_TO_EDGE
-    attribute COLOR_ATTACHMENT0
-    attribute COLOR_BUFFER_BIT
-    attribute COLOR_CLEAR_VALUE
-    attribute COLOR_WRITEMASK
-    attribute COMPILE_STATUS
-    attribute COMPRESSED_TEXTURE_FORMATS
-    attribute CONSTANT_ALPHA
-    attribute CONSTANT_COLOR
-    attribute CONTEXT_LOST_WEBGL
-    attribute CULL_FACE
-    attribute CULL_FACE_MODE
-    attribute CURRENT_PROGRAM
-    attribute CURRENT_VERTEX_ATTRIB
-    attribute CW
-    attribute DECR
-    attribute DECR_WRAP
-    attribute DELETE_STATUS
-    attribute DEPTH_ATTACHMENT
-    attribute DEPTH_BITS
-    attribute DEPTH_BUFFER_BIT
-    attribute DEPTH_CLEAR_VALUE
-    attribute DEPTH_COMPONENT
-    attribute DEPTH_COMPONENT16
-    attribute DEPTH_FUNC
-    attribute DEPTH_RANGE
-    attribute DEPTH_STENCIL
-    attribute DEPTH_STENCIL_ATTACHMENT
-    attribute DEPTH_TEST
-    attribute DEPTH_WRITEMASK
-    attribute DITHER
-    attribute DONT_CARE
-    attribute DST_ALPHA
-    attribute DST_COLOR
-    attribute DYNAMIC_DRAW
-    attribute ELEMENT_ARRAY_BUFFER
-    attribute ELEMENT_ARRAY_BUFFER_BINDING
-    attribute EQUAL
-    attribute FASTEST
-    attribute FLOAT
-    attribute FLOAT_MAT2
-    attribute FLOAT_MAT3
-    attribute FLOAT_MAT4
-    attribute FLOAT_VEC2
-    attribute FLOAT_VEC3
-    attribute FLOAT_VEC4
-    attribute FRAGMENT_SHADER
-    attribute FRAMEBUFFER
-    attribute FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
-    attribute FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
-    attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
-    attribute FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
-    attribute FRAMEBUFFER_BINDING
-    attribute FRAMEBUFFER_COMPLETE
-    attribute FRAMEBUFFER_INCOMPLETE_ATTACHMENT
-    attribute FRAMEBUFFER_INCOMPLETE_DIMENSIONS
-    attribute FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
-    attribute FRAMEBUFFER_UNSUPPORTED
-    attribute FRONT
-    attribute FRONT_AND_BACK
-    attribute FRONT_FACE
-    attribute FUNC_ADD
-    attribute FUNC_REVERSE_SUBTRACT
-    attribute FUNC_SUBTRACT
-    attribute GENERATE_MIPMAP_HINT
-    attribute GEQUAL
-    attribute GREATER
-    attribute GREEN_BITS
-    attribute HIGH_FLOAT
-    attribute HIGH_INT
-    attribute IMPLEMENTATION_COLOR_READ_FORMAT
-    attribute IMPLEMENTATION_COLOR_READ_TYPE
-    attribute INCR
-    attribute INCR_WRAP
-    attribute INT
-    attribute INT_VEC2
-    attribute INT_VEC3
-    attribute INT_VEC4
-    attribute INVALID_ENUM
-    attribute INVALID_FRAMEBUFFER_OPERATION
-    attribute INVALID_OPERATION
-    attribute INVALID_VALUE
-    attribute INVERT
-    attribute KEEP
-    attribute LEQUAL
-    attribute LESS
-    attribute LINEAR
-    attribute LINEAR_MIPMAP_LINEAR
-    attribute LINEAR_MIPMAP_NEAREST
-    attribute LINES
-    attribute LINE_LOOP
-    attribute LINE_STRIP
-    attribute LINE_WIDTH
-    attribute LINK_STATUS
-    attribute LOW_FLOAT
-    attribute LOW_INT
-    attribute LUMINANCE
-    attribute LUMINANCE_ALPHA
-    attribute MAX_COMBINED_TEXTURE_IMAGE_UNITS
-    attribute MAX_CUBE_MAP_TEXTURE_SIZE
-    attribute MAX_FRAGMENT_UNIFORM_VECTORS
-    attribute MAX_RENDERBUFFER_SIZE
-    attribute MAX_TEXTURE_IMAGE_UNITS
-    attribute MAX_TEXTURE_SIZE
-    attribute MAX_VARYING_VECTORS
-    attribute MAX_VERTEX_ATTRIBS
-    attribute MAX_VERTEX_TEXTURE_IMAGE_UNITS
-    attribute MAX_VERTEX_UNIFORM_VECTORS
-    attribute MAX_VIEWPORT_DIMS
-    attribute MEDIUM_FLOAT
-    attribute MEDIUM_INT
-    attribute MIRRORED_REPEAT
-    attribute NEAREST
-    attribute NEAREST_MIPMAP_LINEAR
-    attribute NEAREST_MIPMAP_NEAREST
-    attribute NEVER
-    attribute NICEST
-    attribute NONE
-    attribute NOTEQUAL
-    attribute NO_ERROR
-    attribute ONE
-    attribute ONE_MINUS_CONSTANT_ALPHA
-    attribute ONE_MINUS_CONSTANT_COLOR
-    attribute ONE_MINUS_DST_ALPHA
-    attribute ONE_MINUS_DST_COLOR
-    attribute ONE_MINUS_SRC_ALPHA
-    attribute ONE_MINUS_SRC_COLOR
-    attribute OUT_OF_MEMORY
-    attribute PACK_ALIGNMENT
-    attribute POINTS
-    attribute POLYGON_OFFSET_FACTOR
-    attribute POLYGON_OFFSET_FILL
-    attribute POLYGON_OFFSET_UNITS
-    attribute RED_BITS
-    attribute RENDERBUFFER
-    attribute RENDERBUFFER_ALPHA_SIZE
-    attribute RENDERBUFFER_BINDING
-    attribute RENDERBUFFER_BLUE_SIZE
-    attribute RENDERBUFFER_DEPTH_SIZE
-    attribute RENDERBUFFER_GREEN_SIZE
-    attribute RENDERBUFFER_HEIGHT
-    attribute RENDERBUFFER_INTERNAL_FORMAT
-    attribute RENDERBUFFER_RED_SIZE
-    attribute RENDERBUFFER_STENCIL_SIZE
-    attribute RENDERBUFFER_WIDTH
-    attribute RENDERER
-    attribute REPEAT
-    attribute REPLACE
-    attribute RGB
-    attribute RGB565
-    attribute RGB5_A1
-    attribute RGBA
-    attribute RGBA4
-    attribute SAMPLER_2D
-    attribute SAMPLER_CUBE
-    attribute SAMPLES
-    attribute SAMPLE_ALPHA_TO_COVERAGE
-    attribute SAMPLE_BUFFERS
-    attribute SAMPLE_COVERAGE
-    attribute SAMPLE_COVERAGE_INVERT
-    attribute SAMPLE_COVERAGE_VALUE
-    attribute SCISSOR_BOX
-    attribute SCISSOR_TEST
-    attribute SHADER_TYPE
-    attribute SHADING_LANGUAGE_VERSION
-    attribute SHORT
-    attribute SRC_ALPHA
-    attribute SRC_ALPHA_SATURATE
-    attribute SRC_COLOR
-    attribute STATIC_DRAW
-    attribute STENCIL_ATTACHMENT
-    attribute STENCIL_BACK_FAIL
-    attribute STENCIL_BACK_FUNC
-    attribute STENCIL_BACK_PASS_DEPTH_FAIL
-    attribute STENCIL_BACK_PASS_DEPTH_PASS
-    attribute STENCIL_BACK_REF
-    attribute STENCIL_BACK_VALUE_MASK
-    attribute STENCIL_BACK_WRITEMASK
-    attribute STENCIL_BITS
-    attribute STENCIL_BUFFER_BIT
-    attribute STENCIL_CLEAR_VALUE
-    attribute STENCIL_FAIL
-    attribute STENCIL_FUNC
-    attribute STENCIL_INDEX8
-    attribute STENCIL_PASS_DEPTH_FAIL
-    attribute STENCIL_PASS_DEPTH_PASS
-    attribute STENCIL_REF
-    attribute STENCIL_TEST
-    attribute STENCIL_VALUE_MASK
-    attribute STENCIL_WRITEMASK
-    attribute STREAM_DRAW
-    attribute SUBPIXEL_BITS
-    attribute TEXTURE
-    attribute TEXTURE0
-    attribute TEXTURE1
-    attribute TEXTURE10
-    attribute TEXTURE11
-    attribute TEXTURE12
-    attribute TEXTURE13
-    attribute TEXTURE14
-    attribute TEXTURE15
-    attribute TEXTURE16
-    attribute TEXTURE17
-    attribute TEXTURE18
-    attribute TEXTURE19
-    attribute TEXTURE2
-    attribute TEXTURE20
-    attribute TEXTURE21
-    attribute TEXTURE22
-    attribute TEXTURE23
-    attribute TEXTURE24
-    attribute TEXTURE25
-    attribute TEXTURE26
-    attribute TEXTURE27
-    attribute TEXTURE28
-    attribute TEXTURE29
-    attribute TEXTURE3
-    attribute TEXTURE30
-    attribute TEXTURE31
-    attribute TEXTURE4
-    attribute TEXTURE5
-    attribute TEXTURE6
-    attribute TEXTURE7
-    attribute TEXTURE8
-    attribute TEXTURE9
-    attribute TEXTURE_2D
-    attribute TEXTURE_BINDING_2D
-    attribute TEXTURE_BINDING_CUBE_MAP
-    attribute TEXTURE_CUBE_MAP
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_X
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_Y
-    attribute TEXTURE_CUBE_MAP_NEGATIVE_Z
-    attribute TEXTURE_CUBE_MAP_POSITIVE_X
-    attribute TEXTURE_CUBE_MAP_POSITIVE_Y
-    attribute TEXTURE_CUBE_MAP_POSITIVE_Z
-    attribute TEXTURE_MAG_FILTER
-    attribute TEXTURE_MIN_FILTER
-    attribute TEXTURE_WRAP_S
-    attribute TEXTURE_WRAP_T
-    attribute TRIANGLES
-    attribute TRIANGLE_FAN
-    attribute TRIANGLE_STRIP
-    attribute UNPACK_ALIGNMENT
-    attribute UNPACK_COLORSPACE_CONVERSION_WEBGL
-    attribute UNPACK_FLIP_Y_WEBGL
-    attribute UNPACK_PREMULTIPLY_ALPHA_WEBGL
-    attribute UNSIGNED_BYTE
-    attribute UNSIGNED_INT
-    attribute UNSIGNED_SHORT
-    attribute UNSIGNED_SHORT_4_4_4_4
-    attribute UNSIGNED_SHORT_5_5_5_1
-    attribute UNSIGNED_SHORT_5_6_5
-    attribute VALIDATE_STATUS
-    attribute VENDOR
-    attribute VERSION
-    attribute VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
-    attribute VERTEX_ATTRIB_ARRAY_ENABLED
-    attribute VERTEX_ATTRIB_ARRAY_NORMALIZED
-    attribute VERTEX_ATTRIB_ARRAY_POINTER
-    attribute VERTEX_ATTRIB_ARRAY_SIZE
-    attribute VERTEX_ATTRIB_ARRAY_STRIDE
-    attribute VERTEX_ATTRIB_ARRAY_TYPE
-    attribute VERTEX_SHADER
-    attribute VIEWPORT
-    attribute ZERO
-    getter canvas
-    getter drawingBufferHeight
-    getter drawingBufferWidth
-    method activeTexture
-    method attachShader
-    method bindAttribLocation
-    method bindBuffer
-    method bindFramebuffer
-    method bindRenderbuffer
-    method bindTexture
-    method blendColor
-    method blendEquation
-    method blendEquationSeparate
-    method blendFunc
-    method blendFuncSeparate
-    method bufferData
-    method bufferSubData
-    method checkFramebufferStatus
-    method clear
-    method clearColor
-    method clearDepth
-    method clearStencil
-    method colorMask
-    method commit
-    method compileShader
-    method compressedTexImage2D
-    method compressedTexSubImage2D
-    method constructor
-    method copyTexImage2D
-    method copyTexSubImage2D
-    method createBuffer
-    method createFramebuffer
-    method createProgram
-    method createRenderbuffer
-    method createShader
-    method createTexture
-    method cullFace
-    method deleteBuffer
-    method deleteFramebuffer
-    method deleteProgram
-    method deleteRenderbuffer
-    method deleteShader
-    method deleteTexture
-    method depthFunc
-    method depthMask
-    method depthRange
-    method detachShader
-    method disable
-    method disableVertexAttribArray
-    method drawArrays
-    method drawElements
-    method enable
-    method enableVertexAttribArray
-    method finish
-    method flush
-    method framebufferRenderbuffer
-    method framebufferTexture2D
-    method frontFace
-    method generateMipmap
-    method getActiveAttrib
-    method getActiveUniform
-    method getAttachedShaders
-    method getAttribLocation
-    method getBufferParameter
-    method getContextAttributes
-    method getError
-    method getExtension
-    method getFramebufferAttachmentParameter
-    method getParameter
-    method getProgramInfoLog
-    method getProgramParameter
-    method getRenderbufferParameter
-    method getShaderInfoLog
-    method getShaderParameter
-    method getShaderPrecisionFormat
-    method getShaderSource
-    method getSupportedExtensions
-    method getTexParameter
-    method getUniform
-    method getUniformLocation
-    method getVertexAttrib
-    method getVertexAttribOffset
-    method hint
-    method isBuffer
-    method isContextLost
-    method isEnabled
-    method isFramebuffer
-    method isProgram
-    method isRenderbuffer
-    method isShader
-    method isTexture
-    method lineWidth
-    method linkProgram
-    method makeXRCompatible
-    method pixelStorei
-    method polygonOffset
-    method readPixels
-    method renderbufferStorage
-    method sampleCoverage
-    method scissor
-    method shaderSource
-    method stencilFunc
-    method stencilFuncSeparate
-    method stencilMask
-    method stencilMaskSeparate
-    method stencilOp
-    method stencilOpSeparate
-    method texImage2D
-    method texParameterf
-    method texParameteri
-    method texSubImage2D
-    method uniform1f
-    method uniform1fv
-    method uniform1i
-    method uniform1iv
-    method uniform2f
-    method uniform2fv
-    method uniform2i
-    method uniform2iv
-    method uniform3f
-    method uniform3fv
-    method uniform3i
-    method uniform3iv
-    method uniform4f
-    method uniform4fv
-    method uniform4i
-    method uniform4iv
-    method uniformMatrix2fv
-    method uniformMatrix3fv
-    method uniformMatrix4fv
-    method useProgram
-    method validateProgram
-    method vertexAttrib1f
-    method vertexAttrib1fv
-    method vertexAttrib2f
-    method vertexAttrib2fv
-    method vertexAttrib3f
-    method vertexAttrib3fv
-    method vertexAttrib4f
-    method vertexAttrib4fv
-    method vertexAttribPointer
-    method viewport
-interface WebGLSampler
-    attribute @@toStringTag
-    method constructor
-interface WebGLShader
-    attribute @@toStringTag
-    method constructor
-interface WebGLShaderPrecisionFormat
-    attribute @@toStringTag
-    getter precision
-    getter rangeMax
-    getter rangeMin
-    method constructor
-interface WebGLSync
-    attribute @@toStringTag
-    method constructor
-interface WebGLTexture
-    attribute @@toStringTag
-    method constructor
-interface WebGLTransformFeedback
-    attribute @@toStringTag
-    method constructor
-interface WebGLUniformLocation
-    attribute @@toStringTag
-    method constructor
-interface WebGLVertexArrayObject
-    attribute @@toStringTag
-    method constructor
-interface WebKitCSSMatrix : DOMMatrixReadOnly
-    attribute @@toStringTag
-    getter a
-    getter b
-    getter c
-    getter d
-    getter e
-    getter f
-    getter m11
-    getter m12
-    getter m13
-    getter m14
-    getter m21
-    getter m22
-    getter m23
-    getter m24
-    getter m31
-    getter m32
-    getter m33
-    getter m34
-    getter m41
-    getter m42
-    getter m43
-    getter m44
-    method constructor
-    method invertSelf
-    method multiplySelf
-    method preMultiplySelf
-    method rotateAxisAngleSelf
-    method rotateFromVectorSelf
-    method rotateSelf
-    method scale3dSelf
-    method scaleSelf
-    method setMatrixValue
-    method skewXSelf
-    method skewYSelf
-    method translateSelf
-    setter a
-    setter b
-    setter c
-    setter d
-    setter e
-    setter f
-    setter m11
-    setter m12
-    setter m13
-    setter m14
-    setter m21
-    setter m22
-    setter m23
-    setter m24
-    setter m31
-    setter m32
-    setter m33
-    setter m34
-    setter m41
-    setter m42
-    setter m43
-    setter m44
-interface WebKitMutationObserver
-    attribute @@toStringTag
-    method constructor
-    method disconnect
-    method observe
-    method takeRecords
-interface WebSocket : EventTarget
-    attribute @@toStringTag
-    attribute CLOSED
-    attribute CLOSING
-    attribute CONNECTING
-    attribute OPEN
-    getter binaryType
-    getter bufferedAmount
-    getter extensions
-    getter onclose
-    getter onerror
-    getter onmessage
-    getter onopen
-    getter protocol
-    getter readyState
-    getter url
-    method close
-    method constructor
-    method send
-    setter binaryType
-    setter onclose
-    setter onerror
-    setter onmessage
-    setter onopen
-interface WebSocketStream
-    attribute @@toStringTag
-    getter closed
-    getter connection
-    getter url
-    method close
-    method constructor
-interface WebTransport
-    attribute @@toStringTag
-    getter closed
-    getter datagramReadable
-    getter datagramWritable
-    getter datagrams
-    getter incomingBidirectionalStreams
-    getter incomingUnidirectionalStreams
-    getter ready
-    method close
-    method constructor
-    method createBidirectionalStream
-    method createUnidirectionalStream
-    method setDatagramWritableQueueExpirationDuration
-interface WheelEvent : MouseEvent
-    attribute @@toStringTag
-    attribute DOM_DELTA_LINE
-    attribute DOM_DELTA_PAGE
-    attribute DOM_DELTA_PIXEL
-    getter deltaMode
-    getter deltaX
-    getter deltaY
-    getter deltaZ
-    getter wheelDelta
-    getter wheelDeltaX
-    getter wheelDeltaY
-    method constructor
-interface Window : EventTarget
-    attribute @@toStringTag
-    attribute PERSISTENT
-    attribute TEMPORARY
-    method constructor
-interface Worker : EventTarget
-    attribute @@toStringTag
-    getter onerror
-    getter onmessage
-    method constructor
-    method postMessage
-    method terminate
-    setter onerror
-    setter onmessage
-interface Worklet
-    attribute @@toStringTag
-    method addModule
-    method constructor
-interface WorkletAnimation
-    attribute @@toStringTag
-    getter animatorName
-    getter currentTime
-    getter effect
-    getter playState
-    getter playbackRate
-    getter startTime
-    getter timeline
-    method cancel
-    method constructor
-    method pause
-    method play
-    setter playbackRate
-interface WritableStream
-    attribute @@toStringTag
-    getter locked
-    method abort
-    method close
-    method constructor
-    method getWriter
-interface WritableStreamDefaultWriter
-    attribute @@toStringTag
-    getter closed
-    getter desiredSize
-    getter ready
-    method abort
-    method close
-    method constructor
-    method releaseLock
-    method write
-interface XMLDocument : Document
-    attribute @@toStringTag
-    method constructor
-interface XMLHttpRequest : XMLHttpRequestEventTarget
-    attribute @@toStringTag
-    attribute DONE
-    attribute HEADERS_RECEIVED
-    attribute LOADING
-    attribute OPENED
-    attribute UNSENT
-    getter onreadystatechange
-    getter readyState
-    getter response
-    getter responseText
-    getter responseType
-    getter responseURL
-    getter responseXML
-    getter status
-    getter statusText
-    getter timeout
-    getter upload
-    getter withCredentials
-    method abort
-    method constructor
-    method getAllResponseHeaders
-    method getResponseHeader
-    method open
-    method overrideMimeType
-    method send
-    method setRequestHeader
-    setter onreadystatechange
-    setter responseType
-    setter timeout
-    setter withCredentials
-interface XMLHttpRequestEventTarget : EventTarget
-    attribute @@toStringTag
-    getter onabort
-    getter onerror
-    getter onload
-    getter onloadend
-    getter onloadstart
-    getter onprogress
-    getter ontimeout
-    method constructor
-    setter onabort
-    setter onerror
-    setter onload
-    setter onloadend
-    setter onloadstart
-    setter onprogress
-    setter ontimeout
-interface XMLHttpRequestUpload : XMLHttpRequestEventTarget
-    attribute @@toStringTag
-    method constructor
-interface XMLSerializer
-    attribute @@toStringTag
-    method constructor
-    method serializeToString
-interface XPathEvaluator
-    attribute @@toStringTag
-    method constructor
-    method createExpression
-    method createNSResolver
-    method evaluate
-interface XPathExpression
-    attribute @@toStringTag
-    method constructor
-    method evaluate
-interface XPathResult
-    attribute @@toStringTag
-    attribute ANY_TYPE
-    attribute ANY_UNORDERED_NODE_TYPE
-    attribute BOOLEAN_TYPE
-    attribute FIRST_ORDERED_NODE_TYPE
-    attribute NUMBER_TYPE
-    attribute ORDERED_NODE_ITERATOR_TYPE
-    attribute ORDERED_NODE_SNAPSHOT_TYPE
-    attribute STRING_TYPE
-    attribute UNORDERED_NODE_ITERATOR_TYPE
-    attribute UNORDERED_NODE_SNAPSHOT_TYPE
-    getter booleanValue
-    getter invalidIteratorState
-    getter numberValue
-    getter resultType
-    getter singleNodeValue
-    getter snapshotLength
-    getter stringValue
-    method constructor
-    method iterateNext
-    method snapshotItem
-interface XRAnchor
-    attribute @@toStringTag
-    getter anchorSpace
-    method constructor
-    method delete
-interface XRAnchorSet
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method has
-    method keys
-    method values
-interface XRBoundedReferenceSpace : XRReferenceSpace
-    attribute @@toStringTag
-    getter boundsGeometry
-    method constructor
-interface XRCPUDepthInformation : XRDepthInformation
-    attribute @@toStringTag
-    getter data
-    method constructor
-    method getDepthInMeters
-interface XRCamera
-    attribute @@toStringTag
-    getter height
-    getter width
-    method constructor
-interface XRDOMOverlayState
-    attribute @@toStringTag
-    getter type
-    method constructor
-interface XRDepthInformation
-    attribute @@toStringTag
-    getter height
-    getter normDepthBufferFromNormView
-    getter rawValueToMeters
-    getter width
-    method constructor
-interface XRFrame
-    attribute @@toStringTag
-    getter detectedPlanes
-    getter session
-    getter trackedAnchors
-    method constructor
-    method createAnchor
-    method fillJointRadii
-    method fillPoses
-    method getDepthInformation
-    method getHitTestResults
-    method getHitTestResultsForTransientInput
-    method getImageTrackingResults
-    method getJointPose
-    method getLightEstimate
-    method getPose
-    method getViewerPose
-interface XRHand
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method get
-    method keys
-    method values
-interface XRHitTestResult
-    attribute @@toStringTag
-    method constructor
-    method createAnchor
-    method getPose
-interface XRHitTestSource
-    attribute @@toStringTag
-    method cancel
-    method constructor
-interface XRImageTrackingResult
-    attribute @@toStringTag
-    getter imageSpace
-    getter index
-    getter measuredWidthInMeters
-    getter trackingState
-    method constructor
-interface XRInputSource
-    attribute @@toStringTag
-    getter gamepad
-    getter gripSpace
-    getter hand
-    getter handedness
-    getter profiles
-    getter targetRayMode
-    getter targetRaySpace
-    method constructor
-interface XRInputSourceArray
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method keys
-    method values
-interface XRInputSourceEvent : Event
-    attribute @@toStringTag
-    getter frame
-    getter inputSource
-    method constructor
-interface XRInputSourcesChangeEvent : Event
-    attribute @@toStringTag
-    getter added
-    getter removed
-    getter session
-    method constructor
-interface XRJointPose : XRPose
-    attribute @@toStringTag
-    getter radius
-    method constructor
-interface XRJointSpace : XRSpace
-    attribute @@toStringTag
-    getter jointName
-    method constructor
-interface XRLayer : EventTarget
-    attribute @@toStringTag
-    method constructor
-interface XRLightEstimate
-    attribute @@toStringTag
-    getter primaryLightDirection
-    getter primaryLightIntensity
-    getter sphericalHarmonicsCoefficients
-    method constructor
-interface XRLightProbe : EventTarget
-    attribute @@toStringTag
-    getter onreflectionchange
-    getter probeSpace
-    method constructor
-    setter onreflectionchange
-interface XRPlane
-    attribute @@toStringTag
-    getter lastChangedTime
-    getter orientation
-    getter planeSpace
-    getter polygon
-    method constructor
-interface XRPlaneSet
-    attribute @@toStringTag
-    getter size
-    method @@iterator
-    method constructor
-    method entries
-    method forEach
-    method has
-    method keys
-    method values
-interface XRPose
-    attribute @@toStringTag
-    getter emulatedPosition
-    getter transform
-    method constructor
-interface XRRay
-    attribute @@toStringTag
-    getter direction
-    getter matrix
-    getter origin
-    method constructor
-interface XRReferenceSpace : XRSpace
-    attribute @@toStringTag
-    getter onreset
-    method constructor
-    method getOffsetReferenceSpace
-    setter onreset
-interface XRReferenceSpaceEvent : Event
-    attribute @@toStringTag
-    getter referenceSpace
-    getter transform
-    method constructor
-interface XRRenderState
-    attribute @@toStringTag
-    getter baseLayer
-    getter depthFar
-    getter depthNear
-    getter inlineVerticalFieldOfView
-    method constructor
-interface XRRigidTransform
-    attribute @@toStringTag
-    getter inverse
-    getter matrix
-    getter orientation
-    getter position
-    method constructor
-interface XRSession : EventTarget
-    attribute @@toStringTag
-    getter depthDataFormat
-    getter depthUsage
-    getter domOverlayState
-    getter environmentBlendMode
-    getter inputSources
-    getter interactionMode
-    getter onend
-    getter oninputsourceschange
-    getter onselect
-    getter onselectend
-    getter onselectstart
-    getter onsqueeze
-    getter onsqueezeend
-    getter onsqueezestart
-    getter onvisibilitychange
-    getter preferredReflectionFormat
-    getter renderState
-    getter visibilityState
-    method cancelAnimationFrame
-    method constructor
-    method end
-    method getTrackedImageScores
-    method requestAnimationFrame
-    method requestHitTestSource
-    method requestHitTestSourceForTransientInput
-    method requestLightProbe
-    method requestReferenceSpace
-    method updateRenderState
-    setter onend
-    setter oninputsourceschange
-    setter onselect
-    setter onselectend
-    setter onselectstart
-    setter onsqueeze
-    setter onsqueezeend
-    setter onsqueezestart
-    setter onvisibilitychange
-interface XRSessionEvent : Event
-    attribute @@toStringTag
-    getter session
-    method constructor
-interface XRSpace : EventTarget
-    attribute @@toStringTag
-    method constructor
-interface XRSystem : EventTarget
-    attribute @@toStringTag
-    getter ondevicechange
-    method constructor
-    method isSessionSupported
-    method requestSession
-    method supportsSession
-    setter ondevicechange
-interface XRTransientInputHitTestResult
-    attribute @@toStringTag
-    getter inputSource
-    getter results
-    method constructor
-interface XRTransientInputHitTestSource
-    attribute @@toStringTag
-    method cancel
-    method constructor
-interface XRView
-    attribute @@toStringTag
-    getter camera
-    getter eye
-    getter isFirstPersonObserver
-    getter projectionMatrix
-    getter recommendedViewportScale
-    getter transform
-    method constructor
-    method requestViewportScale
-interface XRViewerPose : XRPose
-    attribute @@toStringTag
-    getter views
-    method constructor
-interface XRViewport
-    attribute @@toStringTag
-    getter height
-    getter width
-    getter x
-    getter y
-    method constructor
-interface XRWebGLBinding
-    attribute @@toStringTag
-    method constructor
-    method getCameraImage
-    method getDepthInformation
-    method getReflectionCubeMap
-interface XRWebGLDepthInformation : XRDepthInformation
-    attribute @@toStringTag
-    getter texture
-    method constructor
-interface XRWebGLLayer : XRLayer
-    static method getNativeFramebufferScaleFactor
-    attribute @@toStringTag
-    getter antialias
-    getter framebuffer
-    getter framebufferHeight
-    getter framebufferWidth
-    getter ignoreDepthValues
-    method constructor
-    method getViewport
-interface XSLTProcessor
-    attribute @@toStringTag
-    method clearParameters
-    method constructor
-    method getParameter
-    method importStylesheet
-    method removeParameter
-    method reset
-    method setParameter
-    method transformToDocument
-    method transformToFragment
-interface webkitMediaStream : EventTarget
-    attribute @@toStringTag
-    getter active
-    getter id
-    getter onactive
-    getter onaddtrack
-    getter oninactive
-    getter onremovetrack
-    method addTrack
-    method clone
-    method constructor
-    method getAudioTracks
-    method getTrackById
-    method getTracks
-    method getVideoTracks
-    method removeTrack
-    setter onactive
-    setter onaddtrack
-    setter oninactive
-    setter onremovetrack
-interface webkitRTCPeerConnection : EventTarget
-    static method generateCertificate
-    attribute @@toStringTag
-    getter canTrickleIceCandidates
-    getter connectionState
-    getter currentLocalDescription
-    getter currentRemoteDescription
-    getter iceConnectionState
-    getter iceGatheringState
-    getter localDescription
-    getter onaddstream
-    getter onconnectionstatechange
-    getter ondatachannel
-    getter onicecandidate
-    getter onicecandidateerror
-    getter oniceconnectionstatechange
-    getter onicegatheringstatechange
-    getter onnegotiationneeded
-    getter onremovestream
-    getter onsignalingstatechange
-    getter ontrack
-    getter pendingLocalDescription
-    getter pendingRemoteDescription
-    getter remoteDescription
-    getter sctp
-    getter signalingState
-    method addIceCandidate
-    method addStream
-    method addTrack
-    method addTransceiver
-    method close
-    method constructor
-    method createAnswer
-    method createDTMFSender
-    method createDataChannel
-    method createOffer
-    method getConfiguration
-    method getLocalStreams
-    method getReceivers
-    method getRemoteStreams
-    method getSenders
-    method getStats
-    method getTransceivers
-    method removeStream
-    method removeTrack
-    method restartIce
-    method setConfiguration
-    method setLocalDescription
-    method setRemoteDescription
-    setter onaddstream
-    setter onconnectionstatechange
-    setter ondatachannel
-    setter onicecandidate
-    setter onicecandidateerror
-    setter oniceconnectionstatechange
-    setter onicegatheringstatechange
-    setter onnegotiationneeded
-    setter onremovestream
-    setter onsignalingstatechange
-    setter ontrack
-interface webkitSpeechGrammar
-    attribute @@toStringTag
-    getter src
-    getter weight
-    setter src
-    setter weight
-interface webkitSpeechGrammarList
-    attribute @@toStringTag
-    getter length
-    method @@iterator
-    method addFromString
-    method addFromUri
-    method item
-interface webkitSpeechRecognition : EventTarget
-    attribute @@toStringTag
-    getter continuous
-    getter grammars
-    getter interimResults
-    getter lang
-    getter maxAlternatives
-    getter onaudioend
-    getter onaudiostart
-    getter onend
-    getter onerror
-    getter onnomatch
-    getter onresult
-    getter onsoundend
-    getter onsoundstart
-    getter onspeechend
-    getter onspeechstart
-    getter onstart
-    method abort
-    method start
-    method stop
-    setter continuous
-    setter grammars
-    setter interimResults
-    setter lang
-    setter maxAlternatives
-    setter onaudioend
-    setter onaudiostart
-    setter onend
-    setter onerror
-    setter onnomatch
-    setter onresult
-    setter onsoundend
-    setter onsoundstart
-    setter onspeechend
-    setter onspeechstart
-    setter onstart
-interface webkitSpeechRecognitionError : Event
-    attribute @@toStringTag
-    getter error
-    getter message
-interface webkitSpeechRecognitionEvent : Event
-    attribute @@toStringTag
-    getter resultIndex
-    getter results
-interface webkitURL
-    static method createObjectURL
-    static method revokeObjectURL
-    attribute @@toStringTag
-    getter hash
-    getter host
-    getter hostname
-    getter href
-    getter origin
-    getter password
-    getter pathname
-    getter port
-    getter protocol
-    getter search
-    getter searchParams
-    getter username
-    method constructor
-    method toJSON
-    method toString
-    setter hash
-    setter host
-    setter hostname
-    setter href
-    setter password
-    setter pathname
-    setter port
-    setter protocol
-    setter search
-    setter username
-[NAMESPACES]
-namespace CSS
-    attribute @@toStringTag
-    getter animationWorklet
-    getter highlights
-    getter layoutWorklet
-    getter paintWorklet
-    method Hz
-    method Q
-    method ch
-    method cm
-    method deg
-    method dpcm
-    method dpi
-    method dppx
-    method em
-    method escape
-    method ex
-    method fr
-    method grad
-    method in
-    method kHz
-    method mm
-    method ms
-    method number
-    method pc
-    method percent
-    method pt
-    method px
-    method rad
-    method registerProperty
-    method rem
-    method s
-    method supports
-    method turn
-    method vh
-    method vmax
-    method vmin
-    method vw
-[GLOBAL OBJECT]
-    attribute GCController
-    attribute accessibilityController
-    attribute chrome
-    attribute console
-    attribute eventSender
-    attribute gamepadController
-    attribute globalThis
-    attribute internals
-    attribute propertyNamesInGlobal
-    attribute testRunner
-    attribute textInputController
-    getter appHistory
-    getter attributionReporting
-    getter caches
-    getter clientInformation
-    getter closed
-    getter cookieStore
-    getter crossOriginIsolated
-    getter crypto
-    getter customElements
-    getter defaultStatus
-    getter defaultstatus
-    getter devicePixelRatio
-    getter document
-    getter event
-    getter external
-    getter frameElement
-    getter frames
-    getter history
-    getter indexedDB
-    getter innerHeight
-    getter innerWidth
-    getter isSecureContext
-    getter launchQueue
-    getter length
-    getter localStorage
-    getter location
-    getter locationbar
-    getter menubar
-    getter name
-    getter navigator
-    getter offscreenBuffering
-    getter onabort
-    getter onafterprint
-    getter onanimationend
-    getter onanimationiteration
-    getter onanimationstart
-    getter onappinstalled
-    getter onauxclick
-    getter onbeforeinstallprompt
-    getter onbeforeprint
-    getter onbeforeunload
-    getter onbeforexrselect
-    getter onblur
-    getter oncancel
-    getter oncanplay
-    getter oncanplaythrough
-    getter onchange
-    getter onclick
-    getter onclose
-    getter oncontextmenu
-    getter oncuechange
-    getter ondblclick
-    getter ondevicemotion
-    getter ondeviceorientation
-    getter ondeviceorientationabsolute
-    getter ondrag
-    getter ondragend
-    getter ondragenter
-    getter ondragleave
-    getter ondragover
-    getter ondragstart
-    getter ondrop
-    getter ondurationchange
-    getter onemptied
-    getter onended
-    getter onerror
-    getter onfocus
-    getter onformdata
-    getter ongotpointercapture
-    getter onhashchange
-    getter oninput
-    getter oninvalid
-    getter onkeydown
-    getter onkeypress
-    getter onkeyup
-    getter onlanguagechange
-    getter onload
-    getter onloadeddata
-    getter onloadedmetadata
-    getter onloadstart
-    getter onlostpointercapture
-    getter onmessage
-    getter onmessageerror
-    getter onmousedown
-    getter onmouseenter
-    getter onmouseleave
-    getter onmousemove
-    getter onmouseout
-    getter onmouseover
-    getter onmouseup
-    getter onmousewheel
-    getter onoffline
-    getter ononline
-    getter onoverscroll
-    getter onpagehide
-    getter onpageshow
-    getter onpause
-    getter onplay
-    getter onplaying
-    getter onpointercancel
-    getter onpointerdown
-    getter onpointerenter
-    getter onpointerleave
-    getter onpointermove
-    getter onpointerout
-    getter onpointerover
-    getter onpointerrawupdate
-    getter onpointerup
-    getter onpopstate
-    getter onprogress
-    getter onratechange
-    getter onrejectionhandled
-    getter onreset
-    getter onresize
-    getter onscreenschange
-    getter onscroll
-    getter onscrollend
-    getter onsearch
-    getter onseeked
-    getter onseeking
-    getter onselect
-    getter onselectionchange
-    getter onselectstart
-    getter onstalled
-    getter onstorage
-    getter onsubmit
-    getter onsuspend
-    getter ontimeupdate
-    getter ontimezonechange
-    getter ontoggle
-    getter ontouchcancel
-    getter ontouchend
-    getter ontouchmove
-    getter ontouchstart
-    getter ontransitioncancel
-    getter ontransitionend
-    getter ontransitionrun
-    getter ontransitionstart
-    getter onunhandledrejection
-    getter onunload
-    getter onvolumechange
-    getter onwaiting
-    getter onwebkitanimationend
-    getter onwebkitanimationiteration
-    getter onwebkitanimationstart
-    getter onwebkittransitionend
-    getter onwheel
-    getter opener
-    getter origin
-    getter originAgentCluster
-    getter originPolicyIds
-    getter outerHeight
-    getter outerWidth
-    getter pageXOffset
-    getter pageYOffset
-    getter parent
-    getter performance
-    getter personalbar
-    getter scheduler
-    getter screen
-    getter screenLeft
-    getter screenTop
-    getter screenX
-    getter screenY
-    getter scrollX
-    getter scrollY
-    getter scrollbars
-    getter self
-    getter sessionStorage
-    getter speechSynthesis
-    getter status
-    getter statusbar
-    getter storageFoundation
-    getter styleMedia
-    getter toolbar
-    getter top
-    getter trustedTypes
-    getter visualViewport
-    getter webkitStorageInfo
-    getter window
-    method NodeFilter
-    method alert
-    method atob
-    method blur
-    method btoa
-    method cancelAnimationFrame
-    method cancelIdleCallback
-    method captureEvents
-    method clearInterval
-    method clearTimeout
-    method close
-    method confirm
-    method createImageBitmap
-    method fetch
-    method find
-    method focus
-    method gc
-    method getComputedAccessibleNode
-    method getComputedStyle
-    method getDigitalGoodsService
-    method getLockScreenData
-    method getScreens
-    method getScreensDeprecated
-    method getSelection
-    method getWindowSegments
-    method isMultiScreen
-    method matchMedia
-    method moveBy
-    method moveTo
-    method open
-    method openDatabase
-    method postMessage
-    method print
-    method prompt
-    method queueMicrotask
-    method releaseEvents
-    method requestAnimationFrame
-    method requestIdleCallback
-    method resizeBy
-    method resizeTo
-    method scroll
-    method scrollBy
-    method scrollTo
-    method setInterval
-    method setTimeout
-    method showDirectoryPicker
-    method showOpenFilePicker
-    method showSaveFilePicker
-    method stop
-    method webkitCancelAnimationFrame
-    method webkitRequestAnimationFrame
-    method webkitRequestFileSystem
-    method webkitResolveLocalFileSystemURL
-    setter clientInformation
-    setter defaultStatus
-    setter defaultstatus
-    setter devicePixelRatio
-    setter event
-    setter external
-    setter frames
-    setter innerHeight
-    setter innerWidth
-    setter length
-    setter location
-    setter locationbar
-    setter menubar
-    setter name
-    setter offscreenBuffering
-    setter onabort
-    setter onafterprint
-    setter onanimationend
-    setter onanimationiteration
-    setter onanimationstart
-    setter onappinstalled
-    setter onauxclick
-    setter onbeforeinstallprompt
-    setter onbeforeprint
-    setter onbeforeunload
-    setter onbeforexrselect
-    setter onblur
-    setter oncancel
-    setter oncanplay
-    setter oncanplaythrough
-    setter onchange
-    setter onclick
-    setter onclose
-    setter oncontextmenu
-    setter oncuechange
-    setter ondblclick
-    setter ondevicemotion
-    setter ondeviceorientation
-    setter ondeviceorientationabsolute
-    setter ondrag
-    setter ondragend
-    setter ondragenter
-    setter ondragleave
-    setter ondragover
-    setter ondragstart
-    setter ondrop
-    setter ondurationchange
-    setter onemptied
-    setter onended
-    setter onerror
-    setter onfocus
-    setter onformdata
-    setter ongotpointercapture
-    setter onhashchange
-    setter oninput
-    setter oninvalid
-    setter onkeydown
-    setter onkeypress
-    setter onkeyup
-    setter onlanguagechange
-    setter onload
-    setter onloadeddata
-    setter onloadedmetadata
-    setter onloadstart
-    setter onlostpointercapture
-    setter onmessage
-    setter onmessageerror
-    setter onmousedown
-    setter onmouseenter
-    setter onmouseleave
-    setter onmousemove
-    setter onmouseout
-    setter onmouseover
-    setter onmouseup
-    setter onmousewheel
-    setter onoffline
-    setter ononline
-    setter onoverscroll
-    setter onpagehide
-    setter onpageshow
-    setter onpause
-    setter onplay
-    setter onplaying
-    setter onpointercancel
-    setter onpointerdown
-    setter onpointerenter
-    setter onpointerleave
-    setter onpointermove
-    setter onpointerout
-    setter onpointerover
-    setter onpointerrawupdate
-    setter onpointerup
-    setter onpopstate
-    setter onprogress
-    setter onratechange
-    setter onrejectionhandled
-    setter onreset
-    setter onresize
-    setter onscreenschange
-    setter onscroll
-    setter onscrollend
-    setter onsearch
-    setter onseeked
-    setter onseeking
-    setter onselect
-    setter onselectionchange
-    setter onselectstart
-    setter onstalled
-    setter onstorage
-    setter onsubmit
-    setter onsuspend
-    setter ontimeupdate
-    setter ontimezonechange
-    setter ontoggle
-    setter ontouchcancel
-    setter ontouchend
-    setter ontouchmove
-    setter ontouchstart
-    setter ontransitioncancel
-    setter ontransitionend
-    setter ontransitionrun
-    setter ontransitionstart
-    setter onunhandledrejection
-    setter onunload
-    setter onvolumechange
-    setter onwaiting
-    setter onwebkitanimationend
-    setter onwebkitanimationiteration
-    setter onwebkitanimationstart
-    setter onwebkittransitionend
-    setter onwheel
-    setter opener
-    setter origin
-    setter outerHeight
-    setter outerWidth
-    setter pageXOffset
-    setter pageYOffset
-    setter parent
-    setter performance
-    setter personalbar
-    setter scheduler
-    setter screen
-    setter screenLeft
-    setter screenTop
-    setter screenX
-    setter screenY
-    setter scrollX
-    setter scrollY
-    setter scrollbars
-    setter self
-    setter status
-    setter statusbar
-    setter toolbar
-    setter visualViewport
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/blink/web_tests/virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt b/third_party/blink/web_tests/virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt
new file mode 100644
index 0000000..5736b4f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/composite-relative-keyframes/external/wpt/css/css-transforms/animation/transform-perspective-composition-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (-0.5) should be [perspective(4.12px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0) should be [perspective(5px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.25) should be [perspective(5.45px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.5) should be [perspective(6.15px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (0.75) should be [perspective(7.06px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (1) should be [perspective(8.33px)]
+FAIL Compositing: property <transform> underlying [perspective(10px)] from add [perspective(10px)] to add [perspective(50px)] at (1.5) should be [matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1.1, 0, 0, 0, 1)] assert_equals: expected "matrix3d ( 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , - 1.1 , 0 , 0 , 0 , 1 ) " but got "matrix3d ( 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , - 0.1 , 0 , 0 , 0 , 1 ) "
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (-0.5) should be [perspective(4.12px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0) should be [perspective(5px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.25) should be [perspective(5.45px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.5) should be [perspective(6.15px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (0.75) should be [perspective(7.06px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (1) should be [perspective(8.33px)]
+PASS Compositing: property <transform> underlying [perspective(10px)] from accumulate [perspective(10px)] to accumulate [perspective(50px)] at (1.5) should be [perspective(12.5px)]
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 6d36c7e..3dcb5a80 100644
--- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -2774,6 +2774,10 @@
     method close
     method constructor
     method getWriter
+interface WritableStreamDefaultController
+    attribute @@toStringTag
+    method constructor
+    method error
 interface WritableStreamDefaultWriter
     attribute @@toStringTag
     getter closed
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/OWNERS b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/OWNERS
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/OWNERS
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/OWNERS
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/README.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/README.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/README.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/README.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/css-properties-as-js-properties-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/css-properties-as-js-properties-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/css-property-listing-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/css-property-listing-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/css-property-listing-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/custom-elements-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/custom-elements-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/custom-elements-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/custom-elements-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/element-instance-property-listing-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/element-instance-property-listing-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/feature-policy-features-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/feature-policy-features-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index c2e4dd2..64eb934 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface AbortController
 [Worker]     attribute @@toStringTag
@@ -2792,6 +2792,10 @@
 [Worker]     method close
 [Worker]     method constructor
 [Worker]     method getWriter
+[Worker] interface WritableStreamDefaultController
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method error
 [Worker] interface WritableStreamDefaultWriter
 [Worker]     attribute @@toStringTag
 [Worker]     getter closed
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-expected.txt
index 63d4e96..d569da1 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-expected.txt
@@ -5107,6 +5107,7 @@
     method getEntriesByType
     method mark
     method measure
+    method measureUserAgentSpecificMemory
     method now
     method setResourceTimingBufferSize
     method toJSON
@@ -9202,6 +9203,10 @@
     method close
     method constructor
     method getWriter
+interface WritableStreamDefaultController
+    attribute @@toStringTag
+    method constructor
+    method error
 interface WritableStreamDefaultWriter
     attribute @@toStringTag
     getter closed
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
similarity index 84%
rename from third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index 35dc755..a79f24e 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface Notification : EventTarget
 [Worker]     getter image
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
similarity index 84%
rename from third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index be8425d..1275631 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface Notification : EventTarget
 [Worker]     getter image
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
similarity index 99%
rename from third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
index a96b3d49..8822bd3f 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -2,7 +2,7 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-Starting worker: resources/global-interface-listing-worker.js
+Starting worker: resources/global-interface-listing-worker.js.php
 [Worker] [INTERFACES]
 [Worker] interface AbortController
 [Worker]     attribute @@toStringTag
@@ -2655,6 +2655,10 @@
 [Worker]     method close
 [Worker]     method constructor
 [Worker]     method getWriter
+[Worker] interface WritableStreamDefaultController
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method error
 [Worker] interface WritableStreamDefaultWriter
 [Worker]     attribute @@toStringTag
 [Worker]     getter closed
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/nonstable-css-properties-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/nonstable-css-properties-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/nonstable-css-properties-expected.txt
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/wake-lock-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/webexposed/wake-lock-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/virtual/stable/webexposed/wake-lock-expected.txt
rename to third_party/blink/web_tests/virtual/stable/http/tests/webexposed/wake-lock-expected.txt
diff --git a/third_party/blink/web_tests/webexposed/global-constructors-attributes-worker.html b/third_party/blink/web_tests/webexposed/global-constructors-attributes-worker.html
deleted file mode 100644
index ca2578d..0000000
--- a/third_party/blink/web_tests/webexposed/global-constructors-attributes-worker.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-<script>
-worker = startWorker("resources/global-constructors-attributes-worker.js");
-</script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/webexposed/global-constructors-attributes.html b/third_party/blink/web_tests/webexposed/global-constructors-attributes.html
deleted file mode 100644
index f9072a0..0000000
--- a/third_party/blink/web_tests/webexposed/global-constructors-attributes.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../resources/js-test.js"></script>
-</head>
-<body>
-<script src="resources/global-constructors-attributes.js"></script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker.html b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker.html
deleted file mode 100644
index 6e3fd2bc..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
-<script>
-description("This test documents all interface attributes and methods on DedicatedWorkerGlobalScope.");
-worker = startWorker("resources/global-interface-listing-worker.js");
-worker.postMessage({ platformSpecific: false });
-</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.html b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.html
deleted file mode 100644
index 0f00d03..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
-<script>
-description("This test documents all interface attributes and methods on DedicatedWorkerGlobalScope.");
-worker = startWorker("resources/global-interface-listing-worker.js");
-worker.postMessage({ platformSpecific: true });
-</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker.html b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker.html
deleted file mode 100644
index bfe54a9..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
-<script>
-description("This test documents all interface attributes and methods on SharedWorkerGlobalScope.");
-worker = startWorker("resources/global-interface-listing-worker.js", "shared");
-worker.port.postMessage({ platformSpecific: true });
-</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific.html b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific.html
deleted file mode 100644
index e6c2a88..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<script>
-// Save the list of property names of the global object just after page load.
-var propertyNamesInGlobal = Object.getOwnPropertyNames(this);
-</script>
-<script src="../resources/js-test.js"></script>
-<script src="../resources/global-interface-listing.js"></script>
-<script>
-description("This test documents all interface attributes and methods on the global window object and element instances.");
-globalInterfaceListing(this, propertyNamesInGlobal, true, debug);
-</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker.html b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker.html
deleted file mode 100644
index f72e7b0..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/js-test.js"></script>
-<script>
-description("This test documents all interface attributes and methods on SharedWorkerGlobalScope.");
-worker = startWorker("resources/global-interface-listing-worker.js", "shared");
-worker.port.postMessage({ platformSpecific: false });
-</script>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing.html b/third_party/blink/web_tests/webexposed/global-interface-listing.html
deleted file mode 100644
index 786cc3ab..0000000
--- a/third_party/blink/web_tests/webexposed/global-interface-listing.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<script>
-// Save the list of property names of the global object just after page load.
-var propertyNamesInGlobal = Object.getOwnPropertyNames(this);
-</script>
-<script src="../resources/js-test.js"></script>
-<script src="../resources/global-interface-listing.js"></script>
-<script>
-description("This test documents all interface attributes and methods on the global window object and element instances.");
-globalInterfaceListing(this, propertyNamesInGlobal, false /* platformSpecific */, debug);
-</script>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/prerendered-iframe.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/prerendered-iframe.html
new file mode 100644
index 0000000..3ec8f7af
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/prerendered-iframe.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>Prerendered iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+assert_true(document.prerendering);
+
+const bc = new BroadcastChannel('iframe-channel');
+bc.postMessage('prerender success');
+bc.close();
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-on-iframe.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-on-iframe.html
new file mode 100644
index 0000000..ae72c2c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-on-iframe.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<title>WindowClient.navigate() on a prerendered iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<script src="deferred-promise-utils.js"></script>
+<body>
+<script>
+// The main test page loads the initiator page, then the initiator page will
+// prerender itself with the `prerendering` parameter and add an iframe. Once
+// the prerendered iframe is ready, post a message to a service worker to call
+// WindowClient.navigate().
+
+const IFRAME_URL = 'prerendered-iframe.html';
+
+const params = new URLSearchParams(location.search);
+const prerendering = params.has('prerendering');
+const navigationUrl = params.get('navigationUrl');
+
+function addIframe() {
+  const iframe = document.createElement('iframe');
+  iframe.src = IFRAME_URL;
+  document.body.appendChild(iframe);
+}
+
+// If the navigation is expected to be deferred, wait to navigate to
+// `navigationUrl` until a prerendered iframe is activated by
+// PrerenderEventCollector. The result of the navigation is sent to
+// "navigation-channel" BroadcastChannel and the prerendering states and events
+// is sent to "test-channel" BroadcastChannel by PrerenderEventCollector.
+async function startNavigationToCrossOriginUrl() {
+  assert_not_equals(new URL(navigationUrl).origin, window.location.origin);
+
+  const navigationPromise = new Promise(resolve => {
+    const bc = new BroadcastChannel('navigation-channel');
+    bc.addEventListener('message', e => {
+      assert_equals(e.data, 'navigate() succeeded');
+      resolve()
+      bc.close();
+    });
+    navigator.serviceWorker.controller.postMessage({
+      navigationUrl: navigationUrl,
+      clientUrl: new URL(IFRAME_URL, window.location).toString(),
+      respondTo: 'navigation-channel',
+    });
+  });
+
+  const prerenderEventCollector = new PrerenderEventCollector();
+  prerenderEventCollector.start(navigationPromise, 'navigation on iframe');
+}
+
+// If the navigation is expected to succeed without delay, the navigation result
+// is directly sent to "test-channel" BroadcastChannel.
+function startNavigationToSameOriginUrl() {
+  assert_equals(new URL(navigationUrl).origin, window.location.origin);
+
+  navigator.serviceWorker.controller.postMessage({
+    navigationUrl: navigationUrl,
+    clientUrl: new URL(IFRAME_URL, window.location).toString(),
+    respondTo: 'test-channel',
+  });
+}
+
+if (prerendering) {
+  assert_not_equals(null, navigator.serviceWorker.controller,
+      'should be controlled by a service worker');
+
+  const bc = new BroadcastChannel('iframe-channel');
+  const readyPromise = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  addIframe();
+
+  readyPromise.then(result => {
+    assert_equals(result, 'prerender success');
+
+    if (new URL(navigationUrl).origin === window.location.origin) {
+      startNavigationToSameOriginUrl();
+    } else {
+      startNavigationToCrossOriginUrl();
+    }
+
+    bc.close();
+  });
+} else {
+  loadInitiatorPage();
+}
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-worker.js b/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-worker.js
index 98d6cb2..561415d 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-worker.js
+++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/windowclient-navigate-worker.js
@@ -1,26 +1,33 @@
 self.onmessage = e => {
-  const url = e.data;
+  const navigationUrl = e.data.navigationUrl;
+  const clientUrl = e.data.clientUrl;
+  const respondTo = e.data.respondTo;
 
   e.waitUntil(async function() {
     const source = e.source;
     const clients = await self.clients.matchAll();
-    const client = clients.find(c => c.url.includes('prerendering'));
+    const client = clients.find(c => c.url == clientUrl);
     if (!client) {
-      source.postMessage('Client was not found');
+      const bc = new BroadcastChannel(respondTo);
+      bc.postMessage('Client was not found');
+      bc.close();
       return;
     }
 
+    let result;
     try {
-      await client.navigate(url);
-      source.postMessage('navigate() succeeded');
-      return;
+      await client.navigate(navigationUrl);
+      result = 'navigate() succeeded';
     } catch (e) {
       if (e instanceof TypeError) {
-        source.postMessage('navigate() failed with TypeError');
+        result = 'navigate() failed with TypeError';
       } else {
-        source.postMessage('navigate() failed with unknown error');
+        result = 'navigate() failed with unknown error';
       }
-      return;
+    } finally {
+      const bc = new BroadcastChannel(respondTo);
+      bc.postMessage(result);
+      bc.close();
     }
   }());
 };
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-cross-origin-url-on-iframe.https.html b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-cross-origin-url-on-iframe.https.html
new file mode 100644
index 0000000..c3af0bc
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-cross-origin-url-on-iframe.https.html
@@ -0,0 +1,73 @@
+<!--
+  This file cannot be upstreamed to WPT until:
+  * startPrerendering() usage is replaced with a WebDriver API.
+  * Cross-origin iframe loading is specified. The test expects that cross-origin
+  iframe loading is deferred.
+-->
+<!DOCTYPE html>
+<title>WindowClient.navigate() to cross-origin url in a prerendered iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<body>
+<script>
+const PAGE_URL = 'resources/windowclient-navigate-on-iframe.html';
+const WORKER_URL = 'resources/windowclient-navigate-worker.js';
+const SCOPE = 'resources/';
+const CROSS_ORIGIN_DESTINATION =
+    get_host_info()['HTTPS_REMOTE_ORIGIN'] +
+    base_path() + 'resources/empty.html';
+
+promise_test(async t => {
+  const registration =
+      await service_worker_unregister_and_register(t, WORKER_URL, SCOPE);
+  t.add_cleanup(() => registration.unregister());
+  await wait_for_state(t, registration.installing, 'activated');
+
+  const bc = new BroadcastChannel('test-channel');
+  t.add_cleanup(_ => bc.close());
+
+  const gotMessage = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  // PAGE_URL starts a prerender of a page that makes an iframe, then asks the
+  // service worker to navigate the iframe to `navigationUrl` via
+  // `WindowClient.navigate(url)`. The cross-origin url triggers
+  // PrerenderEventCollector to wait to navigate to `navigationUrl` on an iframe
+  // until the prerendered iframe is activated.
+  window.open(
+      PAGE_URL + '?navigationUrl=' + CROSS_ORIGIN_DESTINATION,
+      '_blank',
+      'noopener');
+
+  const navigationResult = await gotMessage;
+  const expected = [
+    {
+      event: 'started waiting navigation on iframe',
+      prerendering: true
+    },
+    {
+      event: 'prerendering change',
+      prerendering: false
+    },
+    {
+      event: 'finished waiting navigation on iframe',
+      prerendering: false
+    },
+  ];
+  assert_equals(navigationResult.length, expected.length);
+  for (let i = 0; i < navigationResult.length; i++) {
+    assert_equals(navigationResult[i].event, expected[i].event, `event[${i}]`);
+    assert_equals(navigationResult[i].prerendering, expected[i].prerendering,
+        `prerendering[${i}]`);
+  }
+}, 'WindowClient.navigate() to a cross-origin URL on a prerendered iframe ' +
+   'should be deferred');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-same-origin-url-on-iframe.https.html b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-same-origin-url-on-iframe.https.html
new file mode 100644
index 0000000..246e31c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate-to-same-origin-url-on-iframe.https.html
@@ -0,0 +1,50 @@
+<!--
+  This file cannot be upstreamed to WPT until:
+  * startPrerendering() usage is replaced with a WebDriver API.
+-->
+<!DOCTYPE html>
+<title>WindowClient.navigate() to same-origin url in a prerendered iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<body>
+<script>
+const PAGE_URL = 'resources/windowclient-navigate-on-iframe.html';
+const WORKER_URL = 'resources/windowclient-navigate-worker.js';
+const SCOPE = 'resources/';
+const SAME_ORIGIN_DESTINATION =
+    get_host_info()['HTTPS_ORIGIN'] + base_path() + 'resources/empty.html';
+
+promise_test(async t => {
+  const registration =
+      await service_worker_unregister_and_register(t, WORKER_URL, SCOPE);
+  t.add_cleanup(() => registration.unregister());
+  await wait_for_state(t, registration.installing, 'activated');
+
+  const bc = new BroadcastChannel('test-channel');
+  t.add_cleanup(_ => bc.close());
+
+  const gotMessage = new Promise(resolve => {
+    bc.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  // PAGE_URL starts a prerender of a page that makes an iframe, then asks the
+  // service worker to navigate the iframe to `navigationUrl` via
+  // `WindowClient.navigate(url)`.
+  window.open(
+      PAGE_URL + '?navigationUrl=' + SAME_ORIGIN_DESTINATION,
+      '_blank',
+      'noopener');
+
+  const navigationResult = await gotMessage;
+  assert_equals(navigationResult, 'navigate() succeeded',
+      'should succeed to finish navigation test');
+}, 'WindowClient.navigate() to a same-origin URL on a prerendered iframe ' +
+   'should succeed');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate.https.html b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate.https.html
index 899a432..9cfd990b 100644
--- a/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate.https.html
+++ b/third_party/blink/web_tests/wpt_internal/prerender/windowclient-navigate.https.html
@@ -1,19 +1,20 @@
 <!--
   This file cannot be upstreamed to WPT until:
   * startPrerendering() usage is replaced with a WebDriver API.
-  * The specification changes to disallow navigations after the initial
-  prerender navigation.
 -->
 <!DOCTYPE html>
 <title>WindowClient.navigate() for prerendered main page</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="resources/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
 <script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script src="resources/utils.js"></script>
 <body>
 <script>
-const PAGE_URL = 'resources/prerendered-page.html?prerendering';
+const PAGE_URL = 'resources/prerendered-page.html';
 const WORKER_URL = 'resources/windowclient-navigate-worker.js';
+const SAME_ORIGIN_DESTINATION =
+    get_host_info()['HTTPS_ORIGIN'] + base_path() + 'resources/empty.html';
 
 promise_test(async t => {
   const registration =
@@ -21,11 +22,11 @@
   t.add_cleanup(() => registration.unregister());
   await wait_for_state(t, get_newest_worker(registration), 'activated');
 
-  const bc = new BroadcastChannel('prerender-channel');
-  t.add_cleanup(_ => bc.close());
+  const readyChannel = new BroadcastChannel('prerender-channel');
+  t.add_cleanup(_ => readyChannel.close());
 
-  const gotMessage = new Promise(resolve => {
-    bc.addEventListener('message', e => {
+  const readyPromise = new Promise(resolve => {
+    readyChannel.addEventListener('message', e => {
       resolve(e.data);
     }, {
       once: true
@@ -34,17 +35,32 @@
 
   startPrerendering(PAGE_URL);
 
-  const prerenderResult = await gotMessage;
+  const prerenderResult = await readyPromise;
   assert_equals(prerenderResult, 'prerender success',
                 'should succeed to prerender a page');
 
-  const navigationResult = await new Promise(resolve => {
-    navigator.serviceWorker.onmessage = e => { resolve(e.data) };
-    registration.active.postMessage('empty.html');
-  });
-  assert_equals(navigationResult, 'navigate() failed with TypeError',
-                'should fail the navigation with TypeError');
+  const resultChannel = new BroadcastChannel('test-channel');
+  t.add_cleanup(_ => resultChannel.close());
 
+  const navigationPromise = new Promise(resolve => {
+    resultChannel.addEventListener('message', e => {
+      resolve(e.data);
+    }, {
+      once: true
+    });
+  });
+
+  // Asks the service worker to navigate the prerendered page to `navigationUrl`
+  // via `WindowClient.navigate(url)`.
+  registration.active.postMessage({
+    navigationUrl: SAME_ORIGIN_DESTINATION,
+    clientUrl: new URL(PAGE_URL, window.location).toString(),
+    respondTo: 'test-channel',
+  });
+
+  const navigationResult = await navigationPromise;
+  assert_equals(navigationResult, 'navigate() failed with TypeError',
+      'should fail the navigation with TypeError');
 }, 'WindowClient.navigate() for a prerendered main page should throw a' +
    'TypeError');
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html
new file mode 100644
index 0000000..c773745
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/element-set-sanitized-html.https.tentative.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="support/testcases.sub.js"></script>
+</head>
+<body>
+<script>
+  function buildNode(element_name, markup) {
+    const e = document.createElement(element_name);
+    e.innerHTML = markup;
+    return e;
+  }
+
+  function assert_node_equals(node1, node2) {
+    assert_true(node1 instanceof Node && node1.isEqualNode(node2),
+        `Node[${node1.innerHTML}] == Node[${node2.innerHTML}]`);
+  }
+
+  test(t => {
+    const div = document.createElement("div");
+    assert_throws_js(TypeError, _ => div.SetSanitizedHTML());
+    assert_throws_js(TypeError, _ => div.SetSanitizedHTML("abc"));
+    assert_throws_js(TypeError, _ => div.SetSanitizedHTML("abc", null));
+  }, "Sanitizer: Element.SetSanitizedHTML throws with insufficient arguments.");
+
+  for(const context of ["div", "template", "table"]) {
+    const elem1 = document.createElement(context);
+    const elem2 = document.createElement(context);
+    for (const probe of ["<em>Hello</em>", "<td>data</td>"]) {
+      elem1.SetSanitizedHTML(probe, new Sanitizer());
+      elem2.innerHTML = probe;
+      test(t => {
+        assert_node_equals(elem2, elem1);
+      }, `Sanitizer: <${context}>.SetSanitizedHTML("${probe}", ...) obeys parse context.`);
+    }
+  }
+
+  for (const testcase of testcases) {
+    const element = document.createElement("template");
+    test(t => {
+      let s = new Sanitizer(testcase.config_input);
+      element.SetSanitizedHTML(testcase.value, s);
+      assert_node_equals(buildNode(element.localName, testcase.result), element);
+    }, "Sanitizer: Element.SetSanitizedHTML with config: " + testcase.message);
+  }
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt
index b527f4c..5c5063df 100644
--- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt
+++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative-expected.txt
@@ -1,75 +1,70 @@
 This is a testharness.js-based test.
-Found 71 tests; 70 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS SanitizerAPI sanitize function without argument should throw an error.
-PASS SanitizerAPI sanitize function for null.
-PASS SanitizerAPI with config: plaintext, sanitize from string function for plaintext
-PASS SanitizerAPI with config: xmp, sanitize from string function for xmp
-PASS SanitizerAPI with config: Template element, sanitize from string function for Template element
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitize from string function for HTMLAnchorElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitize from string function for HTMLAnchorElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAnchorElement, sanitize from string function for HTMLAnchorElement
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitize from string function for HTMLAreaElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitize from string function for HTMLAreaElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAreaElement, sanitize from string function for HTMLAreaElement
-PASS SanitizerAPI with config: HTMLFormElement with javascript action, sanitize from string function for HTMLFormElement with javascript action
-PASS SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitize from string function for HTMLFormElement with javascript action start with space
-PASS SanitizerAPI with config: HTMLFormElement, sanitize from string function for HTMLFormElement
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitize from string function for HTMLInputElement with javascript formaction
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitize from string function for HTMLInputElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLInputElement, sanitize from string function for HTMLInputElement
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitize from string function for HTMLButtonElement with javascript formaction
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitize from string function for HTMLButtonElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLButtonElement, sanitize from string function for HTMLButtonElement
-PASS SanitizerAPI with config: malformed HTML, sanitize from string function for malformed HTML
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#84., sanitize from string function for Regression test for WICG/sanitizer-api#84.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#85., sanitize from string function for Regression test for WICG/sanitizer-api#85.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#86., sanitize from string function for Regression test for WICG/sanitizer-api#86.
-PASS SanitizerAPI sanitize function shouldn't load the image.
-PASS SanitizerAPI with config: plaintext, sanitize from document function for plaintext
-PASS SanitizerAPI with config: xmp, sanitize from document function for xmp
-PASS SanitizerAPI with config: Template element, sanitize from document function for Template element
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitize from document function for HTMLAnchorElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitize from document function for HTMLAnchorElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAnchorElement, sanitize from document function for HTMLAnchorElement
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitize from document function for HTMLAreaElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitize from document function for HTMLAreaElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAreaElement, sanitize from document function for HTMLAreaElement
-PASS SanitizerAPI with config: HTMLFormElement with javascript action, sanitize from document function for HTMLFormElement with javascript action
-PASS SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitize from document function for HTMLFormElement with javascript action start with space
-PASS SanitizerAPI with config: HTMLFormElement, sanitize from document function for HTMLFormElement
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitize from document function for HTMLInputElement with javascript formaction
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitize from document function for HTMLInputElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLInputElement, sanitize from document function for HTMLInputElement
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitize from document function for HTMLButtonElement with javascript formaction
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitize from document function for HTMLButtonElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLButtonElement, sanitize from document function for HTMLButtonElement
-FAIL SanitizerAPI with config: malformed HTML, sanitize from document function for malformed HTML assert_equals: expected "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" but got "<p>Some text</p><p>Some more text</p>"
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#84., sanitize from document function for Regression test for WICG/sanitizer-api#84.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#85., sanitize from document function for Regression test for WICG/sanitizer-api#85.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#86., sanitize from document function for Regression test for WICG/sanitizer-api#86.
-PASS SanitizerAPI with config: plaintext, sanitize from document fragment function for plaintext
-PASS SanitizerAPI with config: xmp, sanitize from document fragment function for xmp
-PASS SanitizerAPI with config: Template element, sanitize from document fragment function for Template element
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal, sanitize from document fragment function for HTMLAnchorElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAnchorElement with javascript protocal start with space, sanitize from document fragment function for HTMLAnchorElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAnchorElement, sanitize from document fragment function for HTMLAnchorElement
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal, sanitize from document fragment function for HTMLAreaElement with javascript protocal
-PASS SanitizerAPI with config: HTMLAreaElement with javascript protocal start with space, sanitize from document fragment function for HTMLAreaElement with javascript protocal start with space
-PASS SanitizerAPI with config: HTMLAreaElement, sanitize from document fragment function for HTMLAreaElement
-PASS SanitizerAPI with config: HTMLFormElement with javascript action, sanitize from document fragment function for HTMLFormElement with javascript action
-PASS SanitizerAPI with config: HTMLFormElement with javascript action start with space, sanitize from document fragment function for HTMLFormElement with javascript action start with space
-PASS SanitizerAPI with config: HTMLFormElement, sanitize from document fragment function for HTMLFormElement
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction, sanitize from document fragment function for HTMLInputElement with javascript formaction
-PASS SanitizerAPI with config: HTMLInputElement with javascript formaction start with space, sanitize from document fragment function for HTMLInputElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLInputElement, sanitize from document fragment function for HTMLInputElement
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction, sanitize from document fragment function for HTMLButtonElement with javascript formaction
-PASS SanitizerAPI with config: HTMLButtonElement with javascript formaction start with space, sanitize from document fragment function for HTMLButtonElement with javascript formaction start with space
-PASS SanitizerAPI with config: HTMLButtonElement, sanitize from document fragment function for HTMLButtonElement
-PASS SanitizerAPI with config: malformed HTML, sanitize from document fragment function for malformed HTML
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#84., sanitize from document fragment function for Regression test for WICG/sanitizer-api#84.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#85., sanitize from document fragment function for Regression test for WICG/sanitizer-api#85.
-PASS SanitizerAPI with config: Regression test for WICG/sanitizer-api#86., sanitize from document fragment function for Regression test for WICG/sanitizer-api#86.
-PASS SanitizerAPI sanitize from TrustedHTML.
-PASS SanitizerAPI sanitize from string with default policy.
+Found 66 tests; 65 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS SanitizerAPI with config with Document: plaintext
+PASS SanitizerAPI with config with Document: xmp
+PASS SanitizerAPI with config with Document: Template element
+PASS SanitizerAPI with config with Document: HTMLAnchorElement with javascript protocal
+PASS SanitizerAPI with config with Document: HTMLAnchorElement with javascript protocal start with space
+PASS SanitizerAPI with config with Document: HTMLAnchorElement
+PASS SanitizerAPI with config with Document: HTMLAreaElement with javascript protocal
+PASS SanitizerAPI with config with Document: HTMLAreaElement with javascript protocal start with space
+PASS SanitizerAPI with config with Document: HTMLAreaElement
+PASS SanitizerAPI with config with Document: HTMLFormElement with javascript action
+PASS SanitizerAPI with config with Document: HTMLFormElement with javascript action start with space
+PASS SanitizerAPI with config with Document: HTMLFormElement
+PASS SanitizerAPI with config with Document: HTMLInputElement with javascript formaction
+PASS SanitizerAPI with config with Document: HTMLInputElement with javascript formaction start with space
+PASS SanitizerAPI with config with Document: HTMLInputElement
+PASS SanitizerAPI with config with Document: HTMLButtonElement with javascript formaction
+PASS SanitizerAPI with config with Document: HTMLButtonElement with javascript formaction start with space
+PASS SanitizerAPI with config with Document: HTMLButtonElement
+FAIL SanitizerAPI with config with Document: malformed HTML assert_equals: expected "<p>Some text</p><!-- 1 --><!-- 2 --><p>Some more text</p>" but got "<p>Some text</p><p>Some more text</p>"
+PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#84.
+PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#85.
+PASS SanitizerAPI with config with Document: Regression test for WICG/sanitizer-api#86.
+PASS SanitizerAPI with config with DocumentFragment: plaintext
+PASS SanitizerAPI with config with DocumentFragment: xmp
+PASS SanitizerAPI with config with DocumentFragment: Template element
+PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement with javascript protocal
+PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement with javascript protocal start with space
+PASS SanitizerAPI with config with DocumentFragment: HTMLAnchorElement
+PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement with javascript protocal
+PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement with javascript protocal start with space
+PASS SanitizerAPI with config with DocumentFragment: HTMLAreaElement
+PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement with javascript action
+PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement with javascript action start with space
+PASS SanitizerAPI with config with DocumentFragment: HTMLFormElement
+PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement with javascript formaction
+PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement with javascript formaction start with space
+PASS SanitizerAPI with config with DocumentFragment: HTMLInputElement
+PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement with javascript formaction
+PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement with javascript formaction start with space
+PASS SanitizerAPI with config with DocumentFragment: HTMLButtonElement
+PASS SanitizerAPI with config with DocumentFragment: malformed HTML
+PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#84.
+PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#85.
+PASS SanitizerAPI with config with DocumentFragment: Regression test for WICG/sanitizer-api#86.
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: plaintext
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: xmp
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: Template element
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement with javascript protocal
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement with javascript protocal start with space
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAnchorElement
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement with javascript protocal
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement with javascript protocal start with space
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLAreaElement
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement with javascript action
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement with javascript action start with space
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLFormElement
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement with javascript formaction
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement with javascript formaction start with space
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLInputElement
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement with javascript formaction
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement with javascript formaction start with space
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: HTMLButtonElement
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: malformed HTML
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#84.
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#85.
+PASS SanitizerAPI with config with Element.SetSanitizedHTML: Regression test for WICG/sanitizer-api#86.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html
index 20c2075..19f3a9b5 100644
--- a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html
+++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitize.https.tentative.html
@@ -13,34 +13,20 @@
       d.appendChild(fragment);
       return d.innerHTML;
     }
-
-    test(t => {
-      let s = new Sanitizer({});
-      assert_throws_js(TypeError, _ => s.sanitize());
-    }, "SanitizerAPI sanitize function without argument should throw an error.");
-
-    test(t => {
-      let s = new Sanitizer({});
-      fragment = s.sanitize(null);
-      assert_true(fragment instanceof DocumentFragment);
-      assert_equals(getString(fragment), "null");
-    }, "SanitizerAPI sanitize function for null.");
-
-    testcases.forEach(c => test(t => {
-        let s = new Sanitizer(c.config_input);
-        fragment = s.sanitize(c.value);
-        assert_true(fragment instanceof DocumentFragment);
-        assert_equals(getString(fragment), c.result);
-    }, "SanitizerAPI with config: " + c.message + ", sanitize from string function for " + c.message));
-
-    async_test(t => {
-      let s = new Sanitizer();
-      fragment = s.sanitize("<img src='http://bla/'>");
-      t.step_timeout(_ => {
-        assert_equals(performance.getEntriesByName("http://bla/").length, 0);
-        t.done();
-      }, 1000);
-    }, "SanitizerAPI sanitize function shouldn't load the image.");
+    function getFragment(markup) {
+      const d = document.createElement("div");
+      d.innerHTML = markup;
+      let f = document.createDocumentFragment();
+      f.replaceChildren(...d.childNodes);
+      return f;
+    }
+    function getDoc(markup) {
+      return new DOMParser().parseFromString(markup, "text/html");
+    }
+    function assert_node_equals(node1, node2) {
+      assert_true(node1 instanceof Node && node1.isEqualNode(node2),
+                  `Node[${getString(node1)}] == Node[${getString(node2)}]`);
+    }
 
     testcases.forEach(c => test(t => {
         let s = new Sanitizer(c.config_input);
@@ -50,7 +36,7 @@
 
         let result = getString(fragment);
         assert_equals(result, c.result);
-    }, "SanitizerAPI with config: " + c.message + ", sanitize from document function for " + c.message));
+    }, "SanitizerAPI with config with Document: " + c.message));
 
     testcases.forEach(c => test(t => {
         let s = new Sanitizer(c.config_input);
@@ -59,25 +45,17 @@
         fragment = s.sanitize(tpl.content);
         assert_true(fragment instanceof DocumentFragment);
         assert_equals(getString(fragment), c.result);
-    }, "SanitizerAPI with config: " + c.message + ", sanitize from document fragment function for " + c.message));
+    }, "SanitizerAPI with config with DocumentFragment: " + c.message));
 
-    test(t => {
-      let s = new Sanitizer();
-      let policy = trustedTypes.createPolicy("myPolicy", {createHTML: s=>s+1});
-      let html_string = policy.createHTML("testHTML");
-      fragment = s.sanitize(html_string);
-      assert_true(fragment instanceof DocumentFragment);
-      assert_equals(getString(fragment), "testHTML1");
-    }, "SanitizerAPI sanitize from TrustedHTML.");
-
-    test(t => {
-      let s = new Sanitizer();
-      let policy = trustedTypes.createPolicy("default", {createHTML: s=>s+2});
-      let html_string = policy.createHTML("testHTML");
-      fragment = s.sanitize(html_string);
-      assert_true(fragment instanceof DocumentFragment);
-      assert_equals(getString(fragment), "testHTML2");
-    }, "SanitizerAPI sanitize from string with default policy.");
+    // Let's also test .SetSanitizedHTML. The main test suite factors this out
+    // into a seperate file.
+    testcases.forEach(c => test(t => {
+        let result = document.createElement("div");
+        let probe = document.createElement("div");
+        result.innerHTML = c.result;
+        probe.SetSanitizedHTML(c.value, new Sanitizer(c.config_input));
+        assert_equals(result.innerHTML, probe.innerHTML);
+    }, "SanitizerAPI with config with Element.SetSanitizedHTML: " + c.message));
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html
new file mode 100644
index 0000000..98ee9fa
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/sanitizer-api/sanitizer-sanitizeFor.https.tentative.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="support/testcases.sub.js"></script>
+</head>
+
+<body>
+<script>
+    function buildNode(element_name, markup) {
+      const e = document.createElement(element_name);
+      e.innerHTML = markup;
+      return e;
+    }
+
+    function assert_node_equals(node1, node2) {
+      assert_true(node1 instanceof Node && node1.isEqualNode(node2),
+          `Node[${node1.innerHTML}] == Node[${node2.innerHTML}]`);
+    }
+
+    test(t => {
+      let s = new Sanitizer();
+      assert_throws_js(TypeError, _ => s.sanitizeFor());
+      assert_throws_js(TypeError, _ => s.sanitizeFor(null));
+    }, "Sanitizer.sanitizeFor() should throw.");
+
+    test(t => {
+      let s = new Sanitizer();
+      assert_throws_js(TypeError, _ => s.sanitizeFor("xxx"));
+    }, "Sanitizer.sanitizeFor() with one argument should throw.");
+
+    test(t => {
+      const probe = `<a href="about:blank">hello</a><script>con` +
+          `sole.log("world!");<` + `/script>`;
+      const expected = `<a href="about:blank">hello</a>`;
+      for (const element of ["div", "template", "span", "table", "td",
+                             "pumuckl", "custom-element", "linearGradient",
+                             "svg", "svg:img", "svg:linearGradient"]) {
+        assert_node_equals(
+            buildNode(element, expected),
+            new Sanitizer().sanitizeFor(element, probe));
+      }
+    }, `Sanitizer.sanitizeFor(element, ..)`);
+
+    for(const context of ["div", "template", "table"]) {
+      for (const probe of ["<em>Hello</em>", "<td>data</td>"]) {
+        test(t => {
+          assert_node_equals(
+              buildNode(context, probe),
+              new Sanitizer().sanitizeFor(context, probe));
+        }, `Sanitizer.sanitizeFor("${context}", "${probe}") obeys parse context.`);
+      }
+    }
+
+    for (const testcase of testcases) {
+      test(t => {
+        let s = new Sanitizer(testcase.config_input);
+        assert_node_equals(
+            buildNode("template", testcase.result),
+            s.sanitizeFor("template", testcase.value));
+      }, "Sanitizer.sanitizeFor with config: " + testcase.message);
+    }
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/serial/resources/iframe.html b/third_party/blink/web_tests/wpt_internal/serial/resources/iframe.html
new file mode 100644
index 0000000..9f61dfb
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/serial/resources/iframe.html
@@ -0,0 +1,19 @@
+<script type="module">
+  import {SerialService} from '/gen/third_party/blink/public/mojom/serial/serial.mojom.m.js';
+
+  const interceptor =
+      new MojoInterfaceInterceptor(SerialService.$interfaceName);
+  interceptor.oninterfacerequest = (e) => {
+    window.parent.postMessage({
+      type: 'Attach',
+      handle: e.handle
+    }, '*', [e.handle]);
+  };
+  interceptor.start();
+
+  // Wait for a call to getPorts() to complete to ensure that the interface
+  // handle has been bound to the parent context.
+  await navigator.serial.getPorts();
+
+  window.parent.postMessage({ type: 'Ready'}, '*');
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_detachedFrame.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_detachedFrame.https.window.js
new file mode 100644
index 0000000..18cadd7
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_detachedFrame.https.window.js
@@ -0,0 +1,44 @@
+// META: script=/resources/test-only-api.js
+// META: script=/serial/resources/common.js
+// META: script=/serial/resources/automation.js
+
+async function getDetachedSerialPort() {
+  let iframe = document.createElement('iframe');
+  const ready = new Promise((resolve) => {
+    window.addEventListener('message', e => {
+      if (e.data.type == 'Attach') {
+        fakeSerialService.bind(e.data.handle);
+      } else if (e.data.type = 'Ready') {
+        resolve();
+      }
+    })
+  })
+
+  iframe.src = 'resources/iframe.html';
+  document.body.appendChild(iframe);
+  await ready;
+
+  const iframeSerial = iframe.contentWindow.navigator.serial;
+  fakeSerialService.addPort();
+  const ports = await iframeSerial.getPorts();
+  assert_equals(ports.length, 1);
+
+  document.body.removeChild(iframe);
+  // Set iframe to null to ensure that the GC cleans up as much as possible.
+  iframe = null;
+  GCController.collect();
+
+  return ports[0];
+}
+
+serial_test(async (t) => {
+  const port = await getDetachedSerialPort();
+
+  try {
+    await port.open({ baudRate: 9600 });
+  } catch (e) {
+    // Cannot use promise_rejects_dom() because |e| is thrown from a different
+    // global.
+    assert_equals(e.name, 'NotSupportedError');
+  }
+}, 'open() rejects in a detached context');
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serial_detachedFrame.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serial_detachedFrame.https.window.js
new file mode 100644
index 0000000..666d5ce
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/serial/serial_detachedFrame.https.window.js
@@ -0,0 +1,50 @@
+async function getDetachedSerial(t) {
+  let iframe = document.createElement('iframe');
+  const watcher = new EventWatcher(t, iframe, ['load']);
+  iframe.src = '';
+  const loaded = watcher.wait_for(['load']);
+  document.body.appendChild(iframe);
+  await loaded;
+
+  // Save navigator.serial from the iframe and call getPorts() to ensure that
+  // it is initialized.
+  const iframeSerial = iframe.contentWindow.navigator.serial;
+  const ports = await iframeSerial.getPorts();
+  assert_equals(ports.length, 0);
+
+  document.body.removeChild(iframe);
+  // Set iframe to null to ensure that the GC cleans up as much as possible.
+  iframe = null;
+  GCController.collect();
+
+  return iframeSerial;
+}
+
+promise_test(async (t) => {
+  const detachedSerial = await getDetachedSerial(t);
+
+  try {
+    await detachedSerial.getPorts();
+  } catch (e) {
+    // Cannot use promise_rejects_dom() because |e| is thrown from a different
+    // global.
+    assert_equals(e.name, 'NotSupportedError');
+  }
+}, 'getPorts() rejects in a detached context');
+
+promise_test(async (t) => {
+  const detachedSerial = await getDetachedSerial(t);
+
+  try {
+    await detachedSerial.requestPort();
+  } catch (e) {
+    // Cannot use promise_rejects_dom() because |e| is thrown from a different
+    // global.
+    assert_equals(e.name, 'NotSupportedError');
+  }
+}, 'requestPort() rejects in a detached context');
+
+promise_test(async (t) => {
+  const detachedSerial = await getDetachedSerial(t);
+  detachedSerial.addEventListener('connect', () => {});
+}, 'adding an event listener does nothing in a detached context');
diff --git a/third_party/harfbuzz-ng/fuzz/hb_shape_fuzzer.cc b/third_party/harfbuzz-ng/fuzz/hb_shape_fuzzer.cc
index 2f58d9f..0e0e673 100644
--- a/third_party/harfbuzz-ng/fuzz/hb_shape_fuzzer.cc
+++ b/third_party/harfbuzz-ng/fuzz/hb_shape_fuzzer.cc
@@ -11,7 +11,7 @@
 #include <hb-ot.h>
 // clang-format on
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "third_party/harfbuzz-ng/utils/hb_scoped.h"
 
 constexpr size_t kMaxInputLength = 16800;
diff --git a/third_party/harfbuzz-ng/fuzz/hb_subset_fuzzer.cc b/third_party/harfbuzz-ng/fuzz/hb_subset_fuzzer.cc
index c811781..703de5d 100644
--- a/third_party/harfbuzz-ng/fuzz/hb_subset_fuzzer.cc
+++ b/third_party/harfbuzz-ng/fuzz/hb_subset_fuzzer.cc
@@ -12,7 +12,7 @@
 // clang-format on
 
 #include "base/check.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "third_party/harfbuzz-ng/utils/hb_scoped.h"
 
 namespace {
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc
index 5a05afe..a619dc5 100644
--- a/third_party/leveldatabase/env_chromium.cc
+++ b/third_party/leveldatabase/env_chromium.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
 #include "base/macros.h"
@@ -17,7 +18,6 @@
 #include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/process/process_metrics.h"
-#include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
diff --git a/third_party/ocmock/OCMock/OCMArg.m b/third_party/ocmock/OCMock/OCMArg.m
index 3a9aec33..f3eedb8 100644
--- a/third_party/ocmock/OCMock/OCMArg.m
+++ b/third_party/ocmock/OCMock/OCMArg.m
@@ -33,7 +33,7 @@
 
 + (id __autoreleasing *)anyObjectRef
 {
-    return (id *)0x01234567;
+    return (id *)[self anyPointer];
 }
 
 + (SEL)anySelector
@@ -96,9 +96,9 @@
 	if(type[0] == '^')
 	{
 		void *pointer = [value pointerValue];
-		if(pointer == (void *)0x01234567)
+		if(pointer == [self anyPointer])
 			return [OCMArg any];
-		if((pointer != NULL) && (object_getClass((id)pointer) == [OCMPassByRefSetter class]))
+		if((pointer != NULL) && [OCMPassByRefSetter ptrIsPassByRefSetter:pointer])
 			return (id)pointer;
 	}
     else if(type[0] == ':')
diff --git a/third_party/ocmock/OCMock/OCMPassByRefSetter.h b/third_party/ocmock/OCMock/OCMPassByRefSetter.h
index 51d3566..8b168dd 100644
--- a/third_party/ocmock/OCMock/OCMPassByRefSetter.h
+++ b/third_party/ocmock/OCMock/OCMPassByRefSetter.h
@@ -23,6 +23,9 @@
 
 - (id)initWithValue:(id)value;
 
+// Returns YES if ptr is actually a OCMPassByRefSetter
++ (BOOL)ptrIsPassByRefSetter:(void*)ptr;
+
 - (id)value;
 
 @end
diff --git a/third_party/ocmock/OCMock/OCMPassByRefSetter.m b/third_party/ocmock/OCMock/OCMPassByRefSetter.m
index 7d9f7557..0e4cd52 100644
--- a/third_party/ocmock/OCMock/OCMPassByRefSetter.m
+++ b/third_party/ocmock/OCMock/OCMPassByRefSetter.m
@@ -16,14 +16,25 @@
 
 #import "OCMPassByRefSetter.h"
 
+static NSHashTable *gPointerTable = nil;
 
 @implementation OCMPassByRefSetter
 
++ (void)initialize {
+    if (self == [OCMPassByRefSetter class])
+    {
+        gPointerTable = [[NSHashTable hashTableWithOptions:NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality] retain];
+    }
+}
+
 - (id)initWithValue:(id)aValue
 {
     if ((self = [super init]))
     {
         value = [aValue retain];
+        @synchronized(gPointerTable) {
+            NSHashInsertKnownAbsent(gPointerTable, self);
+        }
     }
 	
 	return self;
@@ -32,6 +43,10 @@
 - (void)dealloc
 {
 	[value release];
+	@synchronized(gPointerTable) {
+		NSAssert(NSHashGet(gPointerTable, self) != NULL, @"self should be in the hash table");
+		NSHashRemove(gPointerTable, self);
+	}
 	[super dealloc];
 }
 
@@ -40,4 +55,10 @@
 	return value;
 }
 
++ (BOOL)ptrIsPassByRefSetter:(void*)ptr {
+    @synchronized(gPointerTable) {
+        return NSHashGet(gPointerTable, ptr) != NULL;
+    }
+}
+
 @end
diff --git a/third_party/ocmock/README.chromium b/third_party/ocmock/README.chromium
index cfe2a0e..93be8ae 100644
--- a/third_party/ocmock/README.chromium
+++ b/third_party/ocmock/README.chromium
@@ -37,3 +37,6 @@
 
 Chromium patches in https://github.com/erikdoe/ocmock/pull/343 to fix the
 comparison of structure representation as strings (again).
+
+Chromium patches in a fix for iOS15 ptrath failures in OCMArg to cache all
+OCMPassByRefSetters rather than checking with object_getClass.
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn
index 6fcf75d2..105fbdb 100644
--- a/third_party/protobuf/BUILD.gn
+++ b/third_party/protobuf/BUILD.gn
@@ -259,6 +259,12 @@
     # The root store tool is not part of Chrome itself, and needs to parse
     # human-readable protobufs.
     "//net/tools/root_store_tool:root_store_proto_full",
+
+    # The spirv-fuzz fuzzer tool needs protobuf_full and is not included in
+    # Chrome.
+    "//third_party/vulkan-deps/spirv-tools/src:spirv-fuzz",
+    "//third_party/vulkan-deps/spirv-tools/src:spvtools_fuzz",
+    "//third_party/vulkan-deps/spirv-tools/src:spvtools_fuzz_proto",
   ]
 
   sources = protobuf_lite_sources + [
diff --git a/third_party/qcms/qcms_color_space_fuzzer.cc b/third_party/qcms/qcms_color_space_fuzzer.cc
index 17b1f8fa..814f8f0 100644
--- a/third_party/qcms/qcms_color_space_fuzzer.cc
+++ b/third_party/qcms/qcms_color_space_fuzzer.cc
@@ -6,7 +6,7 @@
 #include <cstdint>
 #include <random>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/libfuzzer/fuzzers/color_space_data.h"
 #include "third_party/qcms/src/qcms.h"
 
diff --git a/third_party/r8/3pp/3pp.pb b/third_party/r8/3pp/3pp.pb
index ef9c4ba..54909960 100644
--- a/third_party/r8/3pp/3pp.pb
+++ b/third_party/r8/3pp/3pp.pb
@@ -5,6 +5,7 @@
       tag_pattern: "%s-dev"
     }
     patch_dir: "patches"
+    patch_version: "alpha"
   }
 
   build {
diff --git a/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch b/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch
index 32ed2a600..0b9e8792 100644
--- a/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch
+++ b/third_party/r8/3pp/patches/0001-Statefull-lambdas-regress-dex-size.patch
@@ -1,7 +1,7 @@
-From 60780034d9ef3d627b16725c197403a5fe1b6a27 Mon Sep 17 00:00:00 2001
+From 35ed636e46ee1be966b5e4ac3557403d4f8b3fae Mon Sep 17 00:00:00 2001
 From: Andrew Grieve <agrieve@chromium.org>
 Date: Mon, 1 Feb 2021 15:09:52 -0500
-Subject: [PATCH 1/4] Statefull lambdas regress dex size.
+Subject: [PATCH 1/5] Statefull lambdas regress dex size.
 
 Bug: b/129997269
 ---
@@ -23,5 +23,5 @@
  
    // Synthesize virtual methods.
 -- 
-2.32.0.288.g62a8d224e6-goog
+2.32.0.93.g670b81a890-goog
 
diff --git a/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch b/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch
index 0dd13d5..0d3af40 100644
--- a/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch
+++ b/third_party/r8/3pp/patches/0002-Allow-access-modification-everywhere.patch
@@ -1,7 +1,7 @@
-From 4ab201427d83f47fda9dba7b6ef79b9cef6d7c2c Mon Sep 17 00:00:00 2001
+From ad3675346cba5227c6f4b4d334340601cfe42853 Mon Sep 17 00:00:00 2001
 From: Andrew Grieve <agrieve@chromium.org>
 Date: Wed, 21 Oct 2020 10:59:42 -0400
-Subject: [PATCH 2/4] Allow access modification everywhere
+Subject: [PATCH 2/5] Allow access modification everywhere
 
 Chrome does not need need -keep to maintain original visibility.
 Loosening this constraint allows for better optimization, and is easier
@@ -11,7 +11,7 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
-index 2ff90085c..0e0acd581 100644
+index 68b7e13b1..886f630a1 100644
 --- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
 +++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
 @@ -953,7 +953,7 @@ public class AppInfoWithLiveness extends AppInfoWithClassHierarchy
@@ -24,5 +24,5 @@
  
    public boolean isRepackagingAllowed(DexProgramClass clazz) {
 -- 
-2.32.0.288.g62a8d224e6-goog
+2.32.0.93.g670b81a890-goog
 
diff --git a/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch b/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch
index aec0a9e0..14ec68f 100644
--- a/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch
+++ b/third_party/r8/3pp/patches/0003-Add-disassemble-command-to-keeps.patch
@@ -1,7 +1,7 @@
-From bc79e6d9c90e8586d841ddf9cdfaaf591c33996d Mon Sep 17 00:00:00 2001
+From 78629559e44a09acd689452cad3634a70933301e Mon Sep 17 00:00:00 2001
 From: Mohamed Heikal <mheikal@google.com>
 Date: Wed, 26 May 2021 19:03:39 -0400
-Subject: [PATCH 3/4] Add disassemble command to keeps
+Subject: [PATCH 3/5] Add disassemble command to keeps
 
 ---
  src/main/keep.txt | 1 +
@@ -20,5 +20,5 @@
  -keep public class com.android.tools.r8.dexsplitter.DexSplitter { public static void main(java.lang.String[]); }
  
 -- 
-2.32.0.288.g62a8d224e6-goog
+2.32.0.93.g670b81a890-goog
 
diff --git a/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch b/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch
index 0781a3e..28649aa 100644
--- a/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch
+++ b/third_party/r8/3pp/patches/0004-Disable-useDexPcAsDebugInformation.patch
@@ -1,7 +1,7 @@
-From ca66a211ce82c330257d9ca94dcca4c644cb4674 Mon Sep 17 00:00:00 2001
+From 1a7ca4f116f86104a772705433a12f91a7d6a08f Mon Sep 17 00:00:00 2001
 From: Andrew Grieve <agrieve@chromium.org>
 Date: Wed, 23 Jun 2021 21:53:35 -0400
-Subject: [PATCH 4/4] Disable useDexPcAsDebugInformation
+Subject: [PATCH 4/5] Disable useDexPcAsDebugInformation
 
 useDexPcAsDebugInformation breaks deobfuscation, but would be great to turn on.
 
@@ -11,10 +11,10 @@
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
-index e82e04d90..03bab9255 100644
+index c17a6ac6e..f20be9f49 100644
 --- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
 +++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
-@@ -1704,7 +1704,7 @@ public class InternalOptions implements GlobalKeepInfoConfiguration {
+@@ -1718,7 +1718,7 @@ public class InternalOptions implements GlobalKeepInfoConfiguration {
    }
  
    public boolean canUseDexPcAsDebugInformation() {
@@ -24,5 +24,5 @@
  
    public boolean isInterfaceMethodDesugaringEnabled() {
 -- 
-2.32.0.288.g62a8d224e6-goog
+2.32.0.93.g670b81a890-goog
 
diff --git a/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch b/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch
new file mode 100644
index 0000000..17c0928e
--- /dev/null
+++ b/third_party/r8/3pp/patches/0005-Change-PushableEnqueuerWorkList-backing-to-Concurren.patch
@@ -0,0 +1,38 @@
+From ffba24c4288a3f7c8ee1d2d43c92c82c29e077fb Mon Sep 17 00:00:00 2001
+From: Morten Krogh-Jespersen <mkroghj@google.com>
+Date: Wed, 7 Jul 2021 16:37:56 +0200
+Subject: [PATCH 5/5] Change PushableEnqueuerWorkList backing to
+ ConcurrentLinkedQueue
+
+Bug: 193003098
+Change-Id: If667bb01502dad0efec7a16aea1b1aa93bfbaffb
+---
+ .../java/com/android/tools/r8/shaking/EnqueuerWorklist.java   | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+index 47684370e..2fcac5531 100644
+--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
++++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+@@ -18,8 +18,8 @@ import com.android.tools.r8.shaking.GraphReporter.KeepReasonWitness;
+ import com.android.tools.r8.utils.Action;
+ import com.android.tools.r8.utils.InternalOptions;
+ import com.android.tools.r8.utils.collections.ProgramMethodSet;
+-import java.util.ArrayDeque;
+ import java.util.Queue;
++import java.util.concurrent.ConcurrentLinkedQueue;
+ 
+ public abstract class EnqueuerWorklist {
+ 
+@@ -369,7 +369,7 @@ public abstract class EnqueuerWorklist {
+   static class PushableEnqueuerWorkList extends EnqueuerWorklist {
+ 
+     PushableEnqueuerWorkList(Enqueuer enqueuer) {
+-      super(enqueuer, new ArrayDeque<>());
++      super(enqueuer, new ConcurrentLinkedQueue<>());
+     }
+ 
+     @Override
+-- 
+2.32.0.93.g670b81a890-goog
+
diff --git a/third_party/sudden_motion_sensor/sudden_motion_sensor_mac.cc b/third_party/sudden_motion_sensor/sudden_motion_sensor_mac.cc
index 6ac3321..8ea1f3b 100644
--- a/third_party/sudden_motion_sensor/sudden_motion_sensor_mac.cc
+++ b/third_party/sudden_motion_sensor/sudden_motion_sensor_mac.cc
@@ -55,9 +55,9 @@
 
 #include <memory>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 
 struct SuddenMotionSensor::GenericMacbookSensor {
   // Name of device to be read.
diff --git a/third_party/widevine/cdm/BUILD.gn b/third_party/widevine/cdm/BUILD.gn
index d389a4df..30c3025 100644
--- a/third_party/widevine/cdm/BUILD.gn
+++ b/third_party/widevine/cdm/BUILD.gn
@@ -30,17 +30,12 @@
 # TODO(xhwang): widevine_cdm_version.h is only used in few places. Clean this up
 # so we don't need to copy it in most cases.
 if (bundle_widevine_cdm) {
-  widevine_os = target_os
-  if (is_chromeos_lacros) {
-    widevine_os = "linux"  # Bundle Linux CDM for Lacros builds.
-  }
-
   widevine_arch = target_cpu
   if (widevine_arch == "x86") {
     widevine_arch = "ia32"
   }
 
-  widevine_cdm_root = "${widevine_root}/${widevine_os}/${widevine_arch}"
+  widevine_cdm_root = "${widevine_root}/${target_os}/${widevine_arch}"
   cdm_file_name = "${shlib_prefix}widevinecdm${shlib_extension}"
 
   widevine_cdm_version_h_file = "${widevine_cdm_root}/widevine_cdm_version.h"
diff --git a/third_party/wuffs/README.chromium b/third_party/wuffs/README.chromium
index e4326d9b..50ea575d 100644
--- a/third_party/wuffs/README.chromium
+++ b/third_party/wuffs/README.chromium
@@ -1,8 +1,8 @@
 Name: Wuffs (Wrangling Untrusted File Formats Safely)
 Short name: Wuffs
 URL: https://github.com/google/wuffs
-Version: 0.3.0-beta.3
-Revision: b2b8961126502d2ab00daa20d19a976964c012a3
+Version: 0.3.0-beta.6
+Revision: d0451190ca0a4d0566d142261548cc264819f6c4
 Security critical: yes
 License: Apache 2.0
 
diff --git a/third_party/zlib/google/compression_utils_unittest.cc b/third_party/zlib/google/compression_utils_unittest.cc
index 31c3226f..415b9ab 100644
--- a/third_party/zlib/google/compression_utils_unittest.cc
+++ b/third_party/zlib/google/compression_utils_unittest.cc
@@ -9,7 +9,7 @@
 
 #include <string>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace compression {
diff --git a/third_party/zlib/google/zip_reader_unittest.cc b/third_party/zlib/google/zip_reader_unittest.cc
index 44134f88..b203cb57 100644
--- a/third_party/zlib/google/zip_reader_unittest.cc
+++ b/third_party/zlib/google/zip_reader_unittest.cc
@@ -13,13 +13,13 @@
 
 #include "base/bind.h"
 #include "base/check.h"
+#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/hash/md5.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/tools/aggregation_service/BUILD.gn b/tools/aggregation_service/BUILD.gn
new file mode 100644
index 0000000..7343739b
--- /dev/null
+++ b/tools/aggregation_service/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+executable("aggregation_service_tool") {
+  testonly = true
+
+  sources = [ "aggregation_service_tool_main.cc" ]
+
+  deps = [
+    "//base",
+    "//content/test:test_support",
+    "//url",
+  ]
+}
diff --git a/tools/aggregation_service/DEPS b/tools/aggregation_service/DEPS
new file mode 100644
index 0000000..b944551
--- /dev/null
+++ b/tools/aggregation_service/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+content/public/test"
+]
diff --git a/tools/aggregation_service/DIR_METADATA b/tools/aggregation_service/DIR_METADATA
new file mode 100644
index 0000000..4f8aa58
--- /dev/null
+++ b/tools/aggregation_service/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+  component: "Internals>ConversionMeasurement"
+}
+team_email: "privacy-sandbox-dev@chromium.org"
diff --git a/tools/aggregation_service/OWNERS b/tools/aggregation_service/OWNERS
new file mode 100644
index 0000000..76fa9199
--- /dev/null
+++ b/tools/aggregation_service/OWNERS
@@ -0,0 +1 @@
+file://content/browser/aggregation_service/OWNERS
diff --git a/tools/aggregation_service/aggregation_service_tool_main.cc b/tools/aggregation_service/aggregation_service_tool_main.cc
new file mode 100644
index 0000000..1e8db95
--- /dev/null
+++ b/tools/aggregation_service/aggregation_service_tool_main.cc
@@ -0,0 +1,147 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/run_loop.h"
+#include "base/strings/string_split.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/single_thread_task_executor.h"
+#include "base/task/thread_pool/thread_pool_instance.h"
+#include "build/build_config.h"
+#include "content/public/test/test_aggregation_service.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace {
+
+// If you change any of the switch strings, update the kHelpMsg accordingly.
+const char kSwitchContents[] = "contents";
+const char kSwitchHelperKeys[] = "helper-keys";
+const char kSwitchOutput[] = "output";
+
+const char kHelpMsg[] = R"(
+  aggregation_service_tool --contents=<report_contents>
+  --helper-keys=<helper_server_keys> --output=<output_file_path>
+
+  Example:
+  aggregation_service_tool --contents="count-value,1234,5"
+  --helper-keys="a.com:keys1.json,b.com:keys2.json" --output="output.json"
+
+  aggregation_service_tool is a command-line tool that accepts report contents
+  `contents` and mapping of origins to public key json files
+  `helper_server_keys` as input and output an encrypted report in
+  `output_file_path`.
+)";
+
+void PrintHelp() {
+  LOG(INFO) << kHelpMsg;
+}
+
+void SetPublicKeysFromFile(const url::Origin& origin,
+                           const std::string& json_file_path,
+                           content::TestAggregationService* agg_service,
+                           base::OnceCallback<void(bool)> callback) {
+#if defined(OS_WIN)
+  base::FilePath json_file(base::UTF8ToWide(json_file_path));
+#else
+  base::FilePath json_file(json_file_path);
+#endif
+
+  if (!base::PathExists(json_file)) {
+    LOG(ERROR) << "aggregation_service_tool failed to open file: "
+               << json_file.value() << ".";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  std::string json_string;
+  if (!base::ReadFileToString(json_file, &json_string)) {
+    LOG(ERROR) << "aggregation_service_tool failed to read file: "
+               << json_file.value() << ".";
+    std::move(callback).Run(false);
+    return;
+  }
+
+  agg_service->SetPublicKeys(origin, json_string, std::move(callback));
+}
+
+}  // namespace
+
+int main(int argc, char* argv[]) {
+  base::SingleThreadTaskExecutor executor;
+  base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
+      "aggregation_service_tool");
+
+  base::CommandLine::Init(argc, argv);
+  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
+
+  base::CommandLine::StringVector args = command_line.GetArgs();
+
+  if (args.size() != 0U) {
+    LOG(ERROR)
+        << "aggregation_service_tool does not expect any additional arguments.";
+    PrintHelp();
+    return 1;
+  }
+
+  if (!command_line.HasSwitch(kSwitchContents) ||
+      !command_line.HasSwitch(kSwitchHelperKeys) ||
+      !command_line.HasSwitch(kSwitchOutput)) {
+    LOG(ERROR) << "aggregation_service_tool expects contents, helper keys and "
+                  "output to be specified.";
+    PrintHelp();
+    return 1;
+  }
+
+  std::string contents = command_line.GetSwitchValueASCII(kSwitchContents);
+  std::string helper_keys = command_line.GetSwitchValueASCII(kSwitchHelperKeys);
+  base::FilePath output = command_line.GetSwitchValuePath(kSwitchOutput);
+
+  std::unique_ptr<content::TestAggregationService> agg_service =
+      content::TestAggregationService::Create();
+
+  // `helper_keys` is formatted like "a.com:keys1.json,b.com:keys2.json".
+  base::StringPairs kv_pairs;
+  base::SplitStringIntoKeyValuePairs(helper_keys, /*key_value_delimiter=*/':',
+                                     /*key_value_pair_delimiter=*/',',
+                                     &kv_pairs);
+
+  // Send each origin's specified public keys to the tool's storage.
+  for (const auto& kv : kv_pairs) {
+    url::Origin origin = url::Origin::Create(GURL("https://" + kv.first));
+    bool succeeded = false;
+    base::RunLoop run_loop;
+    SetPublicKeysFromFile(
+        origin, kv.second, agg_service.get(),
+        base::BindOnce(
+            [](base::OnceClosure quit, bool& succeeded_out, bool succeeded_in) {
+              succeeded_out = succeeded_in;
+              std::move(quit).Run();
+            },
+            run_loop.QuitClosure(), std::ref(succeeded)));
+    run_loop.Run();
+    if (!succeeded) {
+      LOG(ERROR)
+          << "aggregation_service_tool failed to set public keys for origin: "
+          << origin << ".";
+      return 1;
+    }
+  }
+
+  // TODO(crbug.com/1217824): Interact with the assembler to create an encrypted
+  // report.
+
+  // TODO(crbug.com/1218124): Returning that report (e.g. by saving to disk).
+
+  return 0;
+}
diff --git a/tools/android/common/adb_connection.cc b/tools/android/common/adb_connection.cc
index 8b0c549c..4295172 100644
--- a/tools/android/common/adb_connection.cc
+++ b/tools/android/common/adb_connection.cc
@@ -14,9 +14,9 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
-#include "base/stl_util.h"
 #include "tools/android/common/net.h"
 
 namespace tools {
diff --git a/tools/android/forwarder2/forwarders_manager.cc b/tools/android/forwarder2/forwarders_manager.cc
index 4d99f1bc..dc25b14 100644
--- a/tools/android/forwarder2/forwarders_manager.cc
+++ b/tools/android/forwarder2/forwarders_manager.cc
@@ -12,11 +12,11 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/posix/eintr_wrapper.h"
-#include "base/stl_util.h"
 #include "tools/android/forwarder2/forwarder.h"
 #include "tools/android/forwarder2/socket.h"
 
diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py
index 7ffbf46d..4e6a244 100755
--- a/tools/binary_size/diagnose_bloat.py
+++ b/tools/binary_size/diagnose_bloat.py
@@ -135,12 +135,18 @@
 
   @property
   def summary_stat(self):
+    items = []
     for section_name, results in self._diff.items():
       for subsection_name, value, units in results:
         if 'normalized' in subsection_name:
-          full_name = '{} {}'.format(section_name, subsection_name)
-          return _DiffResult(full_name, value, units)
-    raise Exception('Could not find "normalized" in: ' + repr(self._diff))
+          items.append([section_name, subsection_name, value, units])
+    if len(items) > 1:  # Handle Trichrome.
+      items = [item for item in items if 'Combined_normalized' in item[1]]
+    if len(items) == 1:
+      [section_name, subsection_name, value, units] = items[0]
+      full_name = '{} {}'.format(section_name, subsection_name)
+      return _DiffResult(full_name, value, units)
+    raise Exception('Could not find canonical "normalized" in: %r' % self._diff)
 
   def CombinedSizeChangeForSection(self, section):
     for subsection_name, value, _ in self._diff[section]:
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py
index 94f00c64e..db62c31a 100644
--- a/tools/binary_size/libsupersize/archive.py
+++ b/tools/binary_size/libsupersize/archive.py
@@ -40,6 +40,7 @@
 import obj_analyzer
 import parallel
 import path_util
+import readelf
 import string_extract
 import zip_util
 
@@ -833,13 +834,13 @@
 
   if args.elf_file:
     metadata[models.METADATA_ELF_FILENAME] = shorten_path(args.elf_file)
-    architecture = _ArchFromElf(args.elf_file, args.tool_prefix)
+    architecture = readelf.ArchFromElf(args.elf_file, args.tool_prefix)
     metadata[models.METADATA_ELF_ARCHITECTURE] = architecture
     timestamp_obj = datetime.datetime.utcfromtimestamp(
         os.path.getmtime(args.elf_file))
     timestamp = calendar.timegm(timestamp_obj.timetuple())
     metadata[models.METADATA_ELF_MTIME] = timestamp
-    build_id = BuildIdFromElf(args.elf_file, args.tool_prefix)
+    build_id = readelf.BuildIdFromElf(args.elf_file, args.tool_prefix)
     metadata[models.METADATA_ELF_BUILD_ID] = build_id
     relocations_count = _CountRelocationsFromElf(args.elf_file,
                                                  args.tool_prefix)
@@ -939,7 +940,12 @@
 def _ParseElfInfo(map_path, elf_path, tool_prefix, track_string_literals,
                   outdir_context=None, linker_name=None):
   """Adds ELF section ranges and symbols."""
+  assert map_path or elf_path, 'Need a linker map or an ELF file.'
+  assert map_path or not track_string_literals, (
+      'track_string_literals not yet implemented without map file')
   if elf_path:
+    elf_section_ranges = readelf.SectionInfoFromElf(elf_path, tool_prefix)
+
     # Run nm on the elf file to retrieve the list of symbol names per-address.
     # This list is required because the .map file contains only a single name
     # for each address, yet multiple symbols are often coalesced when they are
@@ -961,17 +967,21 @@
           track_string_literals=track_string_literals)
       bulk_analyzer.AnalyzePaths(outdir_context.elf_object_paths)
 
-  logging.info('Parsing Linker Map')
-  with _OpenMaybeGzAsText(map_path) as map_file:
-    map_section_ranges, raw_symbols, linker_map_extras = (
-        linker_map_parser.MapFileParser().Parse(linker_name, map_file))
+  if map_path:
+    logging.info('Parsing Linker Map')
+    with _OpenMaybeGzAsText(map_path) as f:
+      map_section_ranges, raw_symbols, linker_map_extras = (
+          linker_map_parser.MapFileParser().Parse(linker_name, f))
 
-    if outdir_context and outdir_context.thin_archives:
-      _ResolveThinArchivePaths(raw_symbols, outdir_context.thin_archives)
+      if outdir_context and outdir_context.thin_archives:
+        _ResolveThinArchivePaths(raw_symbols, outdir_context.thin_archives)
+  else:
+    logging.info('Collecting symbols from nm')
+    raw_symbols = nm.CreateUniqueSymbols(elf_path, tool_prefix,
+                                         elf_section_ranges)
 
-  if elf_path:
+  if map_path and elf_path:
     logging.debug('Validating section sizes')
-    elf_section_ranges = _SectionInfoFromElf(elf_path, tool_prefix)
     differing_elf_section_sizes = {}
     differing_map_section_sizes = {}
     for k, (_, elf_size) in elf_section_ranges.items():
@@ -994,7 +1004,7 @@
         missed_object_paths, outdir_context.output_directory)[0]
     bulk_analyzer.AnalyzePaths(missed_object_paths)
     bulk_analyzer.SortPaths()
-    if track_string_literals:
+    if track_string_literals and map_path:
       merge_string_syms = [s for s in raw_symbols if
                            s.full_name == '** merge strings' or
                            s.full_name == '** lld merge strings']
@@ -1048,9 +1058,11 @@
             # is fast enough since len(merge_string_syms) < 10.
             raw_symbols[idx:idx + 1] = literal_syms
 
-  linker_map_parser.DeduceObjectPathsFromThinMap(raw_symbols, linker_map_extras)
+  if map_path:
+    linker_map_parser.DeduceObjectPathsFromThinMap(raw_symbols,
+                                                   linker_map_extras)
 
-  if elf_path:
+  if elf_path and track_string_literals:
     _NameStringLiterals(raw_symbols, elf_path, tool_prefix)
 
   # If we have an ELF file, use its ranges as the source of truth, since some
@@ -1422,13 +1434,7 @@
     symbol.size = 0
     symbol.padding = 0
 
-  relocs_cmd = [path_util.GetReadElfPath(tool_prefix), '--relocs', elf_path]
-  relro_addresses = subprocess.check_output(relocs_cmd).decode('ascii').split(
-      '\n')
-  # Grab first column from (sample output) '02de6d5c  00000017 R_ARM_RELATIVE'
-  relro_addresses = [
-      int(l.split()[0], 16) for l in relro_addresses if 'R_ARM_RELATIVE' in l
-  ]
+  relro_addresses = readelf.CollectRelocationAddresses(elf_path, tool_prefix)
   # More likely for there to be a bug in supersize than an ELF to have any
   # relative relocations.
   assert relro_addresses
@@ -1499,6 +1505,29 @@
   return ret, other_elf_symbols
 
 
+def _ParseNinjaFiles(output_directory, elf_path=None):
+  linker_elf_path = elf_path
+  if elf_path:
+    # For partitioned libraries, the actual link command outputs __combined.so.
+    partitioned_elf_path = elf_path.replace('.so', '__combined.so')
+    if os.path.exists(partitioned_elf_path):
+      linker_elf_path = partitioned_elf_path
+
+  logging.info('Parsing ninja files, looking for %s.',
+               (linker_elf_path or 'source mapping only (elf_path=None)'))
+
+  source_mapper, ninja_elf_object_paths = ninja_parser.Parse(
+      output_directory, linker_elf_path)
+
+  logging.debug('Parsed %d .ninja files.', source_mapper.parsed_file_count)
+  if elf_path:
+    assert ninja_elf_object_paths, (
+        'Failed to find link command in ninja files for ' +
+        os.path.relpath(linker_elf_path, output_directory))
+
+  return source_mapper, ninja_elf_object_paths
+
+
 def CreateContainerAndSymbols(knobs=None,
                               opts=None,
                               container_name=None,
@@ -1563,21 +1592,12 @@
   section_ranges = {}
   raw_symbols = []
   if opts.analyze_native and output_directory:
-    # Start by finding the elf_object_paths, so that nm can run on them while
-    # the linker .map is being parsed.
-    target_elf_path = elf_path
-    if map_path and '__combined.so.map' in map_path:
-      target_elf_path = elf_path.replace('.so', '__combined.so')
-    logging.info('Parsing ninja files, looking for %s.', target_elf_path)
+    # Finds all objects passed to the linker and creates a map of .o -> .cc.
+    source_mapper, ninja_elf_object_paths = _ParseNinjaFiles(
+        output_directory, elf_path)
 
-    source_mapper, ninja_elf_object_paths = ninja_parser.Parse(
-        output_directory, target_elf_path)
-
-    logging.debug('Parsed %d .ninja files.', source_mapper.parsed_file_count)
-    assert not elf_path or ninja_elf_object_paths, (
-        'Failed to find link command in ninja files for ' +
-        os.path.relpath(elf_path, output_directory))
-
+    # Start by finding elf_object_paths so that nm can run on them while the
+    # linker .map is being parsed.
     if ninja_elf_object_paths:
       elf_object_paths, thin_archives = ar.ExpandThinArchives(
           ninja_elf_object_paths, output_directory)
@@ -1618,7 +1638,7 @@
     with tempfile.NamedTemporaryFile(suffix=os.path.basename(elf_path)) as f:
       strip_path = path_util.GetStripPath(tool_prefix)
       subprocess.run([strip_path, '-o', f.name, elf_path], check=True)
-      section_ranges = _SectionInfoFromElf(f.name, tool_prefix)
+      section_ranges = readelf.SectionInfoFromElf(f.name, tool_prefix)
       elf_overhead_size = _CalculateElfOverhead(section_ranges, f.name)
 
   if elf_path:
@@ -1762,45 +1782,11 @@
     return None
 
 
-def BuildIdFromElf(elf_path, tool_prefix):
-  args = [path_util.GetReadElfPath(tool_prefix), '-n', elf_path]
-  stdout = subprocess.check_output(args).decode('ascii')
-  match = re.search(r'Build ID: (\w+)', stdout)
-  assert match, 'Build ID not found from running: ' + ' '.join(args)
-  return match.group(1)
-
-
-def _SectionInfoFromElf(elf_path, tool_prefix):
-  args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide', elf_path]
-  stdout = subprocess.check_output(args).decode('ascii')
-  section_ranges = {}
-  # Matches  [ 2] .hash HASH 00000000006681f0 0001f0 003154 04   A  3   0  8
-  for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE):
-    items = match.group(1).split()
-    section_ranges[items[0]] = (int(items[2], 16), int(items[4], 16))
-  return section_ranges
-
-
 def _ElfIsMainPartition(elf_path, tool_prefix):
-  section_ranges = _SectionInfoFromElf(elf_path, tool_prefix)
+  section_ranges = readelf.SectionInfoFromElf(elf_path, tool_prefix)
   return models.SECTION_PART_END in section_ranges.keys()
 
 
-def _ArchFromElf(elf_path, tool_prefix):
-  args = [path_util.GetReadElfPath(tool_prefix), '-h', elf_path]
-  stdout = subprocess.check_output(args).decode('ascii')
-  machine = re.search('Machine:\s*(.+)', stdout).group(1)
-  if machine == 'Intel 80386':
-    return 'x86'
-  if machine == 'Advanced Micro Devices X86-64':
-    return 'x64'
-  elif machine == 'ARM':
-    return 'arm'
-  elif machine == 'AArch64':
-    return 'arm64'
-  return machine
-
-
 def _CountRelocationsFromElf(elf_path, tool_prefix):
   args = [path_util.GetObjDumpPath(tool_prefix), '--private-headers', elf_path]
   stdout = subprocess.check_output(args).decode('ascii')
@@ -1823,15 +1809,15 @@
 
 
 def _DetectLinkerName(map_path):
-  with _OpenMaybeGzAsText(map_path) as map_file:
-    return linker_map_parser.DetectLinkerNameFromMapFile(map_file)
+  with _OpenMaybeGzAsText(map_path) as f:
+    return linker_map_parser.DetectLinkerNameFromMapFile(f)
 
 
 def _ElfInfoFromApk(apk_path, apk_so_path, tool_prefix):
   """Returns a tuple of (build_id, section_ranges, elf_overhead_size)."""
   with zip_util.UnzipToTemp(apk_path, apk_so_path) as temp:
-    build_id = BuildIdFromElf(temp, tool_prefix)
-    section_ranges = _SectionInfoFromElf(temp, tool_prefix)
+    build_id = readelf.BuildIdFromElf(temp, tool_prefix)
+    section_ranges = readelf.SectionInfoFromElf(temp, tool_prefix)
     elf_overhead_size = _CalculateElfOverhead(section_ranges, temp)
     return build_id, section_ranges, elf_overhead_size
 
@@ -1878,10 +1864,15 @@
                       default=True, action='store_false',
                       help='Disable breaking down "** merge strings" into more '
                            'granular symbols.')
+  parser.add_argument('--no-map-file',
+                      dest='ignore_linker_map',
+                      action='store_true',
+                      help='Use debug information to capture symbol sizes '
+                      'instead of linker map file.')
   parser.add_argument(
       '--relocations',
       action='store_true',
-      help='Instead of counting binary size, count number of relative'
+      help='Instead of counting binary size, count number of relative '
       'relocation instructions in ELF code.')
   parser.add_argument(
       '--java-only', action='store_true', help='Run on only Java symbols')
@@ -2008,7 +1999,7 @@
 
 
 def _DeduceNativeInfo(tentative_output_dir, apk_path, elf_path, map_path,
-                      on_config_error):
+                      ignore_linker_map, on_config_error):
   apk_so_path = None
   if apk_path:
     with zipfile.ZipFile(apk_path) as z:
@@ -2038,20 +2029,21 @@
     if is_partition:
       on_config_error('Found unexpected _partition.so: ' + elf_path)
 
-    if _ElfIsMainPartition(elf_path, ''):
-      map_path = elf_path.replace('.so', '__combined.so') + '.map'
-    else:
-      map_path = elf_path + '.map'
-    if not os.path.exists(map_path):
-      map_path += '.gz'
+    if not ignore_linker_map:
+      if _ElfIsMainPartition(elf_path, ''):
+        map_path = elf_path.replace('.so', '__combined.so') + '.map'
+      else:
+        map_path = elf_path + '.map'
+      if not os.path.exists(map_path):
+        map_path += '.gz'
 
-  if not os.path.exists(map_path):
+  if not ignore_linker_map and not os.path.exists(map_path):
     # Consider a missing linker map fatal only for the base module. For .so
     # files in feature modules, allow skipping breakdowns.
     on_config_error(
         'Could not find .map(.gz)? file. Ensure you have built with '
         'is_official_build=true and generate_linker_map=true, or use '
-        '--map-file to point me a linker map file.')
+        '--map-file to point me a linker map file, or use --no-map-file.')
 
   return elf_path, map_path, apk_so_path
 
@@ -2085,7 +2077,7 @@
   for sub_args in ret:
     for k, v in sub_args.__dict__.items():
       # Translate file arguments to be relative to |sub_dir|.
-      if (k.endswith('_file') or k == 'f') and v is not None:
+      if (k.endswith('_file') or k == 'f') and isinstance(v, str):
         sub_args.__dict__[k] = os.path.join(base_dir, v)
   return ret
 
@@ -2123,19 +2115,31 @@
       opts.analyze_native = False
     else:
       sub_args.elf_file, sub_args.map_file, apk_so_path = _DeduceNativeInfo(
-          top_args.output_directory, sub_args.apk_file, sub_args.elf_file
-          or sub_args.aux_elf_file, sub_args.map_file, on_config_error)
+          tentative_output_dir=top_args.output_directory,
+          apk_path=sub_args.apk_file,
+          elf_path=sub_args.elf_file or sub_args.aux_elf_file,
+          map_path=sub_args.map_file,
+          ignore_linker_map=sub_args.ignore_linker_map,
+          on_config_error=on_config_error)
+
+    if sub_args.ignore_linker_map:
+      sub_args.map_file = None
 
   if opts.analyze_native:
     if sub_args.map_file:
       linker_name = _DetectLinkerName(sub_args.map_file)
       logging.info('Linker name: %s', linker_name)
+    else:
+      # TODO(crbug.com/1193507): Remove when we implement string literal
+      #     tracking without map files.
+      #     nm emits some string literal symbols, but most exist in symbol gaps.
+      opts.track_string_literals = False
 
-      tool_prefix_finder = path_util.ToolPrefixFinder(
-          value=sub_args.tool_prefix,
-          output_directory=top_args.output_directory,
-          linker_name=linker_name)
-      sub_args.tool_prefix = tool_prefix_finder.Finalized()
+    tool_prefix_finder = path_util.ToolPrefixFinder(
+        value=sub_args.tool_prefix,
+        output_directory=top_args.output_directory,
+        linker_name=linker_name)
+    sub_args.tool_prefix = tool_prefix_finder.Finalized()
   else:
     # Trust that these values will not be used, and set to None.
     sub_args.elf_file = None
diff --git a/tools/binary_size/libsupersize/console.py b/tools/binary_size/libsupersize/console.py
index 3bdbb9af..52ebcac 100644
--- a/tools/binary_size/libsupersize/console.py
+++ b/tools/binary_size/libsupersize/console.py
@@ -25,6 +25,7 @@
 import match_util
 import models
 import path_util
+import readelf
 import string_extract
 
 
@@ -283,7 +284,7 @@
 
   def _ElfPathForSymbol(self, size_info, container, tool_prefix, elf_path):
     def build_id_matches(elf_path):
-      found_build_id = archive.BuildIdFromElf(elf_path, tool_prefix)
+      found_build_id = readelf.BuildIdFromElf(elf_path, tool_prefix)
       expected_build_id = container.metadata.get(models.METADATA_ELF_BUILD_ID)
       return found_build_id == expected_build_id
 
diff --git a/tools/binary_size/libsupersize/integration_test.py b/tools/binary_size/libsupersize/integration_test.py
index 88f24b98..6fab8e8d 100755
--- a/tools/binary_size/libsupersize/integration_test.py
+++ b/tools/binary_size/libsupersize/integration_test.py
@@ -197,11 +197,12 @@
                      use_apk=False,
                      use_minimal_apks=False,
                      use_pak=False,
-                     use_aux_elf=False):
+                     use_aux_elf=False,
+                     ignore_linker_map=False):
     assert not use_elf or use_output_directory
     assert not (use_apk and use_pak)
     cache_key = (use_output_directory, use_elf, use_apk, use_minimal_apks,
-                 use_pak, use_aux_elf)
+                 use_pak, use_aux_elf, ignore_linker_map)
     if cache_key not in IntegrationTest.cached_size_info:
       knobs = archive.SectionSizeKnobs()
       # Override for testing. Lower the bar for compacting symbols, to allow
@@ -209,8 +210,14 @@
       knobs.max_same_name_alias_count = 3
 
       args = self._CreateTestArgs()
+      if ignore_linker_map:
+        args.ignore_linker_map = ignore_linker_map
+        # TODO(crbug.com/1193507): Remove when we implement string literal
+        #     tracking without map files.
+        args.track_string_literals = False
+      else:
+        args.map_file = _TEST_MAP_PATH
       args.elf_file = _TEST_ELF_PATH if use_elf or use_aux_elf else None
-      args.map_file = _TEST_MAP_PATH
       args.output_directory = _TEST_OUTPUT_DIR if use_output_directory else None
       args.source_directory = _TEST_SOURCE_DIR
       args.tool_prefix = _TEST_TOOL_PREFIX
@@ -238,7 +245,7 @@
       if use_pak:
         pak_files = [_TEST_APK_LOCALE_PAK_PATH, _TEST_APK_PAK_PATH]
         pak_info_file = _TEST_PAK_INFO_PATH
-      linker_name = 'gold'
+      linker_name = None if ignore_linker_map else 'gold'
 
       # For simplicity, using |args| for both params. This is okay since
       # |args.ssargs_file| is unassigned.
@@ -314,16 +321,20 @@
                  use_minimal_apks=False,
                  use_pak=False,
                  use_aux_elf=None,
+                 ignore_linker_map=False,
                  debug_measures=False,
                  include_padding=False):
     args = [
         archive_path,
         '--source-directory',
         _TEST_SOURCE_DIR,
-        #  --map-file ignored for use_ssargs.
-        '--map-file',
-        _TEST_MAP_PATH,
     ]
+    if ignore_linker_map:
+      args += ['--no-map-file']
+      args += ['--tool-prefix', _TEST_TOOL_PREFIX]
+    elif not use_ssargs:
+      # --map-file ignored for use_ssargs.
+      args += ['--map-file', _TEST_MAP_PATH]
 
     if use_output_directory:
       # Let autodetection find output_directory when --elf-file is used.
@@ -356,6 +367,7 @@
                      use_minimal_apks=False,
                      use_pak=False,
                      use_aux_elf=False,
+                     ignore_linker_map=False,
                      debug_measures=False,
                      include_padding=False):
     with tempfile.NamedTemporaryFile(suffix='.size') as temp_file:
@@ -366,6 +378,7 @@
                       use_minimal_apks=use_minimal_apks,
                       use_pak=use_pak,
                       use_aux_elf=use_aux_elf,
+                      ignore_linker_map=ignore_linker_map,
                       debug_measures=debug_measures,
                       include_padding=include_padding)
       size_info = archive.LoadAndPostProcessSizeInfo(temp_file.name)
@@ -376,7 +389,8 @@
         use_apk=use_apk,
         use_minimal_apks=use_minimal_apks,
         use_pak=use_pak,
-        use_aux_elf=use_aux_elf)
+        use_aux_elf=use_aux_elf,
+        ignore_linker_map=ignore_linker_map)
     self.assertEqual(_AllMetadata(expected_size_info), _AllMetadata(size_info))
     # Don't cluster.
     expected_size_info.symbols = expected_size_info.raw_symbols
@@ -409,6 +423,10 @@
     return self._DoArchiveTest(use_elf=True)
 
   @_CompareWithGolden()
+  def test_Archive_Elf_No_Map(self):
+    return self._DoArchiveTest(use_elf=True, ignore_linker_map=True)
+
+  @_CompareWithGolden()
   def test_Archive_Apk(self):
     return self._DoArchiveTest(use_apk=True, use_aux_elf=True)
 
diff --git a/tools/binary_size/libsupersize/nm.py b/tools/binary_size/libsupersize/nm.py
old mode 100644
new mode 100755
index 15ff93cd..693bdf76
--- a/tools/binary_size/libsupersize/nm.py
+++ b/tools/binary_size/libsupersize/nm.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
 # Copyright 2017 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
@@ -15,14 +16,22 @@
   BulkForkAndCall() target: Runs nm on a .a file or a list of .o files, parses
   the output, extracts symbol information, and (if available) extracts string
   offset information.
+
+CreateUniqueSymbols():
+  Creates Symbol objects from nm output.
 """
 
+import argparse
 import collections
+import logging
+import os
 import subprocess
 
 import demangle
+import models
 import parallel
 import path_util
+import readelf
 import sys
 
 
@@ -95,8 +104,10 @@
   args = [path_util.GetNmPath(tool_prefix), '--no-sort', '--defined-only',
           elf_path]
   # pylint: disable=unexpected-keyword-arg
-  proc = subprocess.Popen(
-      args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')
+  proc = subprocess.Popen(args,
+                          stdout=subprocess.PIPE,
+                          stderr=subprocess.DEVNULL,
+                          encoding='utf-8')
   # llvm-nm may write to stderr. Discard to denoise.
   stdout, _ = proc.communicate()
   assert proc.returncode == 0
@@ -139,6 +150,147 @@
   }
 
 
+def CreateUniqueSymbols(elf_path, tool_prefix, section_ranges):
+  """Creates symbols from nm --print-size output.
+
+  Creates only one symbol for each address (does not create symbol aliases).
+  """
+  # Filter to sections we care about and sort by (address, size).
+  section_ranges = [
+      x for x in section_ranges.items() if x[0] in models.NATIVE_SECTIONS
+  ]
+  section_ranges.sort(key=lambda x: x[1])
+  min_address = section_ranges[0][1][0]
+  max_address = sum(section_ranges[-1][1])
+
+  args = [
+      path_util.GetNmPath(tool_prefix), '--no-sort', '--defined-only',
+      '--print-size', elf_path
+  ]
+  # pylint: disable=unexpected-keyword-arg
+  stdout = subprocess.check_output(args,
+                                   stderr=subprocess.DEVNULL,
+                                   encoding='utf-8')
+  lines = stdout.splitlines()
+  logging.debug('Parsing %d lines of output', len(lines))
+  symbols_by_address = {}
+  # Example 32-bit output:
+  # 00857f94 00000004 t __on_dlclose_late
+  # 000001ec r ndk_build_number
+  for line in lines:
+    tokens = line.split(' ', 3)
+    num_tokens = len(tokens)
+    if num_tokens < 3:
+      # Address with no size and no name.
+      continue
+    address_str = tokens[0]
+    # Check if size is omitted (can happen with binutils but not llvm).
+    if num_tokens == 3:
+      size_str = '0'
+      section = tokens[1]
+      mangled_name = tokens[2]
+    else:
+      size_str = tokens[1]
+      section = tokens[2]
+      mangled_name = tokens[3]
+
+    if section not in 'BbDdTtRrWw' or not _IsRelevantNmName(mangled_name):
+      continue
+
+    address = int(address_str, 16)
+
+    # Ignore symbols outside of sections that we care about.
+    # Symbols can still exist in sections that we do not care about if those
+    # sections are interleaved. We discard such symbols in the next loop.
+    if not min_address <= address < max_address:
+      continue
+
+    # Pick the alias that defines a size.
+    existing_alias = symbols_by_address.get(address)
+    if existing_alias and existing_alias.size > 0:
+      continue
+
+    size = int(size_str, 16)
+
+    # E.g.: .str.2.llvm.12282370934750212
+    if mangled_name.startswith('.str.'):
+      mangled_name = models.STRING_LITERAL_NAME
+    elif mangled_name.startswith('__ARMV7PILongThunk_'):
+      # Convert thunks from prefix to suffix so that name is demangleable.
+      mangled_name = mangled_name[len('__ARMV7PILongThunk_'):] + '.LongThunk'
+    elif mangled_name.startswith('__ThumbV7PILongThunk_'):
+      mangled_name = mangled_name[len('__ThumbV7PILongThunk_'):] + '.LongThunk'
+
+    # Use address (next loop) to determine between .data and .data.rel.ro.
+    section_name = None
+    if section in 'Tt':
+      section_name = models.SECTION_TEXT
+    elif section in 'Rr':
+      section_name = models.SECTION_RODATA
+    elif section in 'Bb':
+      section_name = models.SECTION_BSS
+
+    # No need to demangle names since they will be demangled by
+    # DemangleRemainingSymbols().
+    symbols_by_address[address] = models.Symbol(section_name,
+                                                size,
+                                                address=address,
+                                                full_name=mangled_name)
+
+  logging.debug('Sorting %d NM symbols', len(symbols_by_address))
+  # Sort symbols by address.
+  sorted_symbols = sorted(symbols_by_address.values(), key=lambda s: s.address)
+
+  # Assign section to symbols based on address, and size where unspecified.
+  # Use address rather than nm's section character to distinguish between
+  # .data.rel.ro and .data.
+  logging.debug('Assigning section_name and filling in missing sizes')
+  section_range_iter = iter(section_ranges)
+  section_end = -1
+  raw_symbols = []
+  active_assembly_sym = None
+  for i, sym in enumerate(sorted_symbols):
+    # Move to next section if applicable.
+    while sym.address >= section_end:
+      section_range = next(section_range_iter)
+      section_name, (section_start, section_size) = section_range
+      section_end = section_start + section_size
+
+    # Skip symbols that don't fall into a section that we care about
+    # (e.g. GCC_except_table533 from .eh_frame).
+    if sym.address < section_start:
+      continue
+
+    if sym.section_name and sym.section_name != section_name:
+      logging.warning('Re-assigning section for %r to %s', sym, section_name)
+    sym.section_name = section_name
+
+    if i + 1 < len(sorted_symbols):
+      next_addr = sorted_symbols[i + 1].address
+    else:
+      next_addr = section_end
+
+    # Heuristic: Discard subsequent assembly symbols (no size) that are ALL_CAPS
+    # or .-prefixed, since they are likely labels within a function.
+    if (active_assembly_sym and sym.size == 0
+        and sym.section_name == models.SECTION_TEXT):
+      if sym.full_name.startswith('.') or sym.full_name.isupper():
+        active_assembly_sym.size += next_addr - sym.address
+        # Triggers ~30 times for all of libchrome.so.
+        logging.debug('Discarding assembly label: %s', sym.full_name)
+        continue
+
+    active_assembly_sym = sym if sym.size == 0 else None
+
+    # For assembly symbols:
+    # Add in a size when absent and guard against size overlapping next symbol.
+    if active_assembly_sym or sym.end_address > next_addr:
+      sym.size = next_addr - sym.address
+
+    raw_symbols.append(sym)
+
+  return raw_symbols
+
 
 def _CollectAliasesByAddressAsyncHelper(elf_path, tool_prefix):
   result = CollectAliasesByAddress(elf_path, tool_prefix)
@@ -236,3 +388,25 @@
   #     down on marshalling overhead.
   return (parallel.EncodeDictOfLists(symbol_names_by_path),
           parallel.EncodeDictOfLists(string_addresses_by_path), num_no_symbols)
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('--tool-prefix', required=True)
+  parser.add_argument('--output-directory', required=True)
+  parser.add_argument('elf_path', type=os.path.realpath)
+
+  args = parser.parse_args()
+  logging.basicConfig(level=logging.DEBUG,
+                      format='%(levelname).1s %(relativeCreated)6d %(message)s')
+
+  # Other functions in this file have test entrypoints in object_analyzer.py.
+  section_ranges = readelf.SectionInfoFromElf(args.elf_path, args.tool_prefix)
+  symbols = CreateUniqueSymbols(args.elf_path, args.tool_prefix, section_ranges)
+  for s in symbols:
+    print(s)
+  logging.warning('Printed %d symbols', len(symbols))
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/binary_size/libsupersize/readelf.py b/tools/binary_size/libsupersize/readelf.py
new file mode 100644
index 0000000..15fd02cd
--- /dev/null
+++ b/tools/binary_size/libsupersize/readelf.py
@@ -0,0 +1,58 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Helpers that interact with the "readelf" tool."""
+
+import re
+import subprocess
+
+import path_util
+
+
+def BuildIdFromElf(elf_path, tool_prefix):
+  """Returns the Build ID for the given binary."""
+  args = [path_util.GetReadElfPath(tool_prefix), '-n', elf_path]
+  stdout = subprocess.check_output(args, encoding='ascii')
+  match = re.search(r'Build ID: (\w+)', stdout)
+  assert match, 'Build ID not found from running: ' + ' '.join(args)
+  return match.group(1)
+
+
+def ArchFromElf(elf_path, tool_prefix):
+  """Returns the GN architecture for the given binary."""
+  args = [path_util.GetReadElfPath(tool_prefix), '-h', elf_path]
+  stdout = subprocess.check_output(args, encoding='ascii')
+  machine = re.search('Machine:\s*(.+)', stdout).group(1)
+  if machine == 'Intel 80386':
+    return 'x86'
+  if machine == 'Advanced Micro Devices X86-64':
+    return 'x64'
+  elif machine == 'ARM':
+    return 'arm'
+  elif machine == 'AArch64':
+    return 'arm64'
+  return machine
+
+
+def SectionInfoFromElf(elf_path, tool_prefix):
+  """Finds the address and size of all ELF sections
+
+  Returns:
+    A dict of section_name->(start_address, size).
+  """
+  args = [path_util.GetReadElfPath(tool_prefix), '-S', '--wide', elf_path]
+  stdout = subprocess.check_output(args, encoding='ascii')
+  section_ranges = {}
+  # Matches  [ 2] .hash HASH 00000000006681f0 0001f0 003154 04   A  3   0  8
+  for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE):
+    items = match.group(1).split()
+    section_ranges[items[0]] = (int(items[2], 16), int(items[4], 16))
+  return section_ranges
+
+
+def CollectRelocationAddresses(elf_path, tool_prefix):
+  """Returns the list of addresses that are targets for relative relocations."""
+  cmd = [path_util.GetReadElfPath(tool_prefix), '--relocs', elf_path]
+  ret = subprocess.check_output(cmd, encoding='ascii').splitlines()
+  # Grab first column from (sample output) '02de6d5c  00000017 R_ARM_RELATIVE'
+  return [int(l.split(maxsplit=1)[0], 16) for l in ret if 'R_ARM_RELATIVE' in l]
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Elf_No_Map.golden b/tools/binary_size/libsupersize/testdata/Archive_Elf_No_Map.golden
new file mode 100644
index 0000000..a6d84f4
--- /dev/null
+++ b/tools/binary_size/libsupersize/testdata/Archive_Elf_No_Map.golden
@@ -0,0 +1,103 @@
+elf_arch=arm
+elf_build_id=WhatAnAmazingBuildId
+elf_file_name=elf
+elf_mtime={redacted}
+elf_relocations_count=394087
+git_revision=abc123
+gn_args=var1=true var2="foo"
+tool_prefix=tools/binary_size/libsupersize/testdata/mock_toolchain/
+Section .text: has 100.0% of 35982248 bytes accounted for from 11 symbols. 0 bytes are unaccounted for.
+* Padding accounts for 83704 bytes (0.2%)
+* 3 have source paths. Accounts for 8472 bytes (0.0%).
+* 3 have a component assigned. Accounts for 8472 bytes (0.0%).
+* 1 placeholders exist (symbols that start with **). Accounts for 35897728 bytes (99.8%).
+* 5 aliases exist, mapped to 2 unique addresses (32 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are clones. Accounts for 8 bytes (0.0%).
+Large padding of 75512 between:
+  A) .text@28d900(size_without_padding=8,padding=0,full_name=startup._GLOBAL__sub_I_page_allocator.cc,object_path=,source_path=,flags={},num_aliases=1,component=)
+  B) .text@2a0000(size_without_padding=16,padding=75512,full_name=BazAlias(bool),object_path=,source_path=,flags={},num_aliases=2,component=)
+Large padding of 8168 between:
+  A) .text@2a0010(size_without_padding=8,padding=0,full_name=blink::ContiguousContainerBase::shrinkToFit(),object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={clone},num_aliases=3,component=Internal>Android)
+  B) .text@2a2000(size_without_padding=8,padding=8168,full_name=OUTLINED_FUNCTION_0,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
+Section .rodata: has 0.0% of 0 bytes accounted for from 0 symbols. 5927652 bytes are unaccounted for.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 string literals exist. Accounts for 0 bytes (0.0%) padding is 0 bytes.
+* 0 symbols have shared ownership.
+Section .data.rel.ro: has 0.0% of 0 bytes accounted for from 0 symbols. 1065224 bytes are unaccounted for.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.0% of 0 bytes accounted for from 0 symbols. 101768 bytes are unaccounted for.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .bss: has 0.0% of 0 bytes accounted for from 0 symbols. 1300456 bytes are unaccounted for.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.translations: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.nontranslated: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .other: has 100.0% of 90351129 bytes accounted for from 23 symbols. 0 bytes are unaccounted for.
+* Padding accounts for 33902635 bytes (37.5%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 have a component assigned. Accounts for 0 bytes (0.0%).
+* 22 placeholders exist (symbols that start with **). Accounts for 56448494 bytes (62.5%).
+* 0 symbols have shared ownership.
+.text@28d900(size_without_padding=8,padding=0,full_name=startup._GLOBAL__sub_I_page_allocator.cc,object_path=,source_path=,flags={},num_aliases=1,component=)
+.text@2a0000(size_without_padding=16,padding=75512,full_name=BazAlias(bool),object_path=,source_path=,flags={},num_aliases=2,component=)
+.text@2a0000(size_without_padding=16,padding=75512,full_name=blink::ContiguousContainerBase::shrinkToFit(),object_path=,source_path=,flags={},num_aliases=2,component=)
+.text@2a0010(size_without_padding=8,padding=0,full_name=BarAlias(),object_path=,source_path=,flags={},num_aliases=3,component=)
+.text@2a0010(size_without_padding=8,padding=0,full_name=FooAlias(),object_path=,source_path=,flags={},num_aliases=3,component=)
+.text@2a0010(size_without_padding=8,padding=0,full_name=blink::ContiguousContainerBase::shrinkToFit(),object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={clone},num_aliases=3,component=Internal>Android)
+.text@2a2000(size_without_padding=8,padding=8168,full_name=OUTLINED_FUNCTION_0,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
+.text@2a2020(size_without_padding=264,padding=24,full_name=OUTLINED_FUNCTION_1,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
+.text@2a2128(size_without_padding=248,padding=0,full_name=AssemblySymbol,object_path=,source_path=,flags={},num_aliases=1,component=)
+.text@2a2220(size_without_padding=264,padding=0,full_name=aliasedWithOutlinedFunction(),object_path=,source_path=,flags={},num_aliases=1,component=)
+.text@2a2328(size_without_padding=35897728,padding=0,full_name=** .text (unattributed),object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=60,padding=0,full_name=** ELF Section: .ARM.attributes,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=1536456,padding=0,full_name=** ELF Section: .ARM.exidx,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=183632,padding=0,full_name=** ELF Section: .ARM.extab,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=304,padding=0,full_name=** ELF Section: .dynamic,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=4025,padding=0,full_name=** ELF Section: .dynstr,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=6496,padding=0,full_name=** ELF Section: .dynsym,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=8,padding=0,full_name=** ELF Section: .fini_array,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=812,padding=0,full_name=** ELF Section: .gnu.version,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=28,padding=0,full_name=** ELF Section: .gnu.version_d,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=96,padding=0,full_name=** ELF Section: .gnu.version_r,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=42956,padding=0,full_name=** ELF Section: .got,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=2684,padding=0,full_name=** ELF Section: .hash,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=8,padding=0,full_name=** ELF Section: .init_array,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=19,padding=0,full_name=** ELF Section: .interp,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=36,padding=0,full_name=** ELF Section: .note.gnu.build-id,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=28,padding=0,full_name=** ELF Section: .note.gnu.gold-version,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=4244,padding=0,full_name=** ELF Section: .plt,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=2655384,padding=0,full_name=** ELF Section: .rel.dyn,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=2816,padding=0,full_name=** ELF Section: .rel.plt,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=436,padding=0,full_name=** ELF Section: .shstrtab,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=34841854,padding=0,full_name=** ELF Section: .strtab,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=17166112,padding=0,full_name=** ELF Section: .symtab,object_path=,source_path=,flags={},num_aliases=1,component=)
+.other@0(size_without_padding=0,padding=33902635,full_name=Overhead: ELF file,object_path=,source_path=,flags={},num_aliases=1,component=)
diff --git a/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_nm.py b/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_nm.py
index 51ee9c7..5276d90 100644
--- a/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_nm.py
+++ b/tools/binary_size/libsupersize/testdata/mock_toolchain/mock_nm.py
@@ -25,6 +25,24 @@
 002b6bb8 t $t.22
 """.format(_SHRINK_TO_FIT_CLONE)
 
+_ELF_OUTPUT_WITH_SIZE = """002b6e20 t $t
+00000010 N
+002b6bb8 00000008 t $t
+002a0010 00000008 t {}
+0028d900 00000008 T startup._GLOBAL__sub_I_page_allocator.cc
+002a0010 00000008 t FooAlias()
+002b6bb8 00000000 t $t.23
+002a0010 00000008 t BarAlias()
+002a0000 00000018 t blink::ContiguousContainerBase::shrinkToFit()
+002a0000 00000018 t BazAlias(bool)
+002a2000 00000008 t OUTLINED_FUNCTION_0
+002a2020 00000108 t OUTLINED_FUNCTION_1
+002a2020 00000108 t OUTLINED_FUNCTION_2
+002a2128 t AssemblySymbol
+002a2138 t .assembly_label
+002a2220 00000108 t aliasedWithOutlinedFunction()
+002b6bb8 00000000 t $t.22
+""".format(_SHRINK_TO_FIT_CLONE)
 _SHRINK_TO_FIT = ('blink::ContiguousContainerBase::shrinkToFit() '
                   '[clone .part.1234] [clone .isra.2]')
 # Generated by: nm --no-sort --defined-only <any .o file with pak resources> -C
@@ -112,7 +130,10 @@
 
 def _PrintOutput(path):
   if path.endswith(os.path.join('out', 'Release', 'elf')):
-    sys.stdout.write(_ELF_OUTPUT)
+    if '--print-size' in sys.argv:
+      sys.stdout.write(_ELF_OUTPUT_WITH_SIZE)
+    else:
+      sys.stdout.write(_ELF_OUTPUT)
   else:
     lines = _OBJECT_OUTPUTS.get(os.path.normpath(path))
     assert lines, 'No mock_nm.py entry for: ' + path
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 1aefef9..e02dd5ce 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -17,6 +17,7 @@
 import subprocess
 import sys
 import tarfile
+import time
 
 from update import RELEASE_VERSION, STAMP_FILE
 
@@ -572,7 +573,10 @@
     binaries = [f for f in want if f.endswith('.exe') or f.endswith('.dll')]
     assert 'bin/clang-cl.exe' in binaries
     assert 'bin/lld-link.exe' in binaries
+    start = time.time()
     UploadPDBsToSymbolServer(binaries)
+    end = time.time()
+    print('symbol upload took', end - start, 'seconds')
 
   # FIXME: Warn if the file already exists on the server.
 
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 1e8d94e..a2cf0fe0 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -39,7 +39,7 @@
 # https://chromium.googlesource.com/chromium/src/+/main/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
-CLANG_REVISION = 'llvmorg-13-init-14634-gf814cd74'
+CLANG_REVISION = 'llvmorg-13-init-14732-g8a7b5ebf'
 CLANG_SUB_REVISION = 1
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/tools/cros/OWNERS b/tools/cros/OWNERS
index 448d9be..5456cdad 100644
--- a/tools/cros/OWNERS
+++ b/tools/cros/OWNERS
@@ -2,5 +2,4 @@
 # http://dev.chromium.org/developers/telemetry/telemetry-feature-guidelines
 
 achuith@chromium.org
-tbarzic@chromium.org
-tengs@chromium.org
+tbarzic@chromium.org
\ No newline at end of file
diff --git a/tools/imagediff/image_diff.cc b/tools/imagediff/image_diff.cc
index 9c0a9ae..44de463 100644
--- a/tools/imagediff/image_diff.cc
+++ b/tools/imagediff/image_diff.cc
@@ -70,6 +70,7 @@
   }
 
   Image(const Image& image) = default;
+  Image& operator=(const Image& image) = default;
 
   bool has_image() const {
     return w_ > 0 && h_ > 0;
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
index 7446988..7b0242a 100644
--- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc
+++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -11,8 +11,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
+#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/unguessable_token.h"
 #include "base/util/type_safety/id_type.h"
diff --git a/tools/json_schema_compiler/test/arrays_unittest.cc b/tools/json_schema_compiler/test/arrays_unittest.cc
index 3b1ae0b..b2907f41 100644
--- a/tools/json_schema_compiler/test/arrays_unittest.cc
+++ b/tools/json_schema_compiler/test/arrays_unittest.cc
@@ -9,7 +9,7 @@
 #include <memory>
 #include <utility>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "tools/json_schema_compiler/test/enums.h"
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 0bfcec8..75ab0faf 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -262,6 +262,10 @@
     'chromium.fyi': {
       'Afl Upload Linux ASan': 'afl_asan_shared_release_bot',
       'ASAN Debug (reclient)': 'asan_lsan_debug_bot_reclient',
+      'Comparison Linux': {
+        'goma': 'gpu_tests_release_bot',
+        'reclient': 'gpu_tests_release_bot_reclient',
+      },
       'Libfuzzer Upload Chrome OS ASan': 'libfuzzer_chromeos_asan_release_bot',
       'Libfuzzer Upload Linux ASan': 'libfuzzer_asan_release_bot',
       'Libfuzzer Upload Linux ASan (reclient)': 'libfuzzer_asan_release_bot_reclient',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index cd1adb7..62ea177f3 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -24,6 +24,22 @@
       "use_goma": true
     }
   },
+  "Comparison Linux": {
+    "goma": {
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "use_goma": true
+    },
+    "reclient": {
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "use_rbe": true
+    }
+  },
   "Libfuzzer Upload Chrome OS ASan": {
     "gn_args": {
       "archive_seed_corpus": false,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 4c945fab..b299cc43 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -4995,6 +4995,30 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Commerce.TabGridSwitched.HasPriceDrop">
+  <owner>davidjm@chromium.org</owner>
+  <owner>ayman@chromium.org</owner>
+  <owner>dtrainor@chromium.org</owner>
+  <description>
+    Price drops are displayed on the Tab Grid Card in the Tab Grid Switcher for
+    commerce related websites where a decrease in price, relative to the
+    previously known price is identified. This metric records when the user
+    clicks the Tab Grid Card which contains a price drop.
+  </description>
+</action>
+
+<action name="Commerce.TabGridSwitched.NoPriceDrop">
+  <owner>davidjm@chromium.org</owner>
+  <owner>ayman@chromium.org</owner>
+  <owner>dtrainor@chromium.org</owner>
+  <description>
+    Price drops are displayed on the Tab Grid Card in the Tab Grid Switcher for
+    commerce related websites where a decrease in price, relative to the
+    previously known price is identified. This metric records when the user
+    clicks the Tab Grid Card which does not contain a price drop.
+  </description>
+</action>
+
 <action name="ConfirmNotToOrderSpringCharger">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -16950,6 +16974,25 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="NewTabPage.Carts.AcceptDiscountConsent">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <description>
+    The 'get discounts' is clicked in the discount consent to agree to receive
+    discounts.
+  </description>
+</action>
+
+<action name="NewTabPage.Carts.DisableDiscount">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <description>
+    User disables the discount feature in the new tab page customize menu.
+  </description>
+</action>
+
 <action name="NewTabPage.Carts.DismissLastCartHidesModule">
   <owner>wychen@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
@@ -16960,6 +17003,15 @@
   </description>
 </action>
 
+<action name="NewTabPage.Carts.EnableDiscount">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <description>
+    User enables the discount feature in the new tab page customize menu.
+  </description>
+</action>
+
 <action name="NewTabPage.Carts.HideModule">
   <owner>wychen@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
@@ -16980,6 +17032,16 @@
   </description>
 </action>
 
+<action name="NewTabPage.Carts.RejectDiscountConsent">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <description>
+    The 'No thanks' is clicked in the discount consent to opt out of receiving
+    discounts.
+  </description>
+</action>
+
 <action name="NewTabPage.Carts.RemoveModule">
   <owner>wychen@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index a8663433..03c305c 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -3383,6 +3383,7 @@
   <int value="10" label="App Management main view (Plugin VM)"/>
   <int value="11" label="DBus Service (Plugin VM)"/>
   <int value="12" label="Notification (Plugin VM)"/>
+  <int value="13" label="App Management main view (Borealis)"/>
 </enum>
 
 <enum name="AppManagementUserAction">
@@ -7736,6 +7737,12 @@
   <int value="2" label="BLOCK_STATUS_ALL_DOMAINS_BLOCKED"/>
 </enum>
 
+<enum name="BlockZeroSerialNumberType">
+  <int value="0" label="Normal serial number"/>
+  <int value="1" label="Repeating pattern in serial number"/>
+  <int value="2" label="Missing serial number"/>
+</enum>
+
 <enum name="BluetoothAdapterConnectToServiceInsecurelyResult">
   <int value="0" label="Success"/>
   <int value="1" label="Error: Invalid arguments"/>
@@ -8892,6 +8899,11 @@
   <int value="1" label="Has CRC"/>
 </enum>
 
+<enum name="BooleanHasDiscount">
+  <int value="0" label="No discount"/>
+  <int value="1" label="has discount"/>
+</enum>
+
 <enum name="BooleanHasDistilledData">
   <int value="0" label="No distilled data"/>
   <int value="1" label="Has distilled data"/>
@@ -9541,6 +9553,11 @@
   <int value="1" label="Set"/>
 </enum>
 
+<enum name="BooleanShared">
+  <int value="0" label="Not shared"/>
+  <int value="1" label="Shared"/>
+</enum>
+
 <enum name="BooleanShareGroup">
   <int value="0" label="No share group"/>
   <int value="1" label="Using share group"/>
@@ -10488,6 +10505,12 @@
   <int value="7" label="Failed to open low latency stream"/>
 </enum>
 
+<enum name="CartDiscountDataType">
+  <summary>Discount related data associated with the cart module.</summary>
+  <int value="0" label="cart_discount_info"/>
+  <int value="1" label="cart_discount_link"/>
+</enum>
+
 <enum name="CastCertificateStatus">
   <int value="0" label="OK"/>
   <int value="1" label="InvalidCrl"/>
@@ -33874,6 +33897,8 @@
   <int value="3946" label="DifferentPerspectiveCBOrParent"/>
   <int value="3947" label="WebkitImageSet"/>
   <int value="3948" label="RTCPeerConnectionWithBlockingCsp"/>
+  <int value="3949" label="SanitizerAPISanitizeFor"/>
+  <int value="3950" label="SanitizerAPIElementSetSanitized"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
@@ -40411,6 +40436,15 @@
   <int value="6" label="DEFAULT_NTP"/>
 </enum>
 
+<enum name="HostPermissionsAccess">
+  <int value="0" label="CANNOT_AFFECT"/>
+  <int value="1" label="NOT_REQUESTED"/>
+  <int value="2" label="ON_CLICK"/>
+  <int value="3" label="ON_SPECIFIC_SITES"/>
+  <int value="4" label="ON_ALL_REQUESTED_SITES"/>
+  <int value="5" label="ON_ACTIVE_TAB_ONLY"/>
+</enum>
+
 <enum name="HostSafetyStatus">
   <int value="0" label="OK"/>
   <int value="1" label="Top level domain is numeric"/>
@@ -46793,6 +46827,7 @@
       label="SupervisedUserCommittedInterstitials:disabled"/>
   <int value="-1504305449" label="NTPPhysicalWebPageSuggestions:enabled"/>
   <int value="-1503851906" label="EnableSettingsShortcutSearch:enabled"/>
+  <int value="-1500811568" label="MuteNotificationSnoozeAction:disabled"/>
   <int value="-1498681588" label="AndroidWebContentsDarkMode:enabled"/>
   <int value="-1498334893" label="ExperimentalVRFeatures:enabled"/>
   <int value="-1497450774" label="TreatUnsafeDownloadsAsActive:disabled"/>
@@ -47219,6 +47254,7 @@
   <int value="-1191671217" label="TabGroupsNewBadgePromo:disabled"/>
   <int value="-1191258368" label="PageInfoPerformanceHints:disabled"/>
   <int value="-1190174011" label="enable-hdr"/>
+  <int value="-1187546444" label="MuteNotificationSnoozeAction:enabled"/>
   <int value="-1187251500" label="OmniboxPedalsBatch2NonEnglish:disabled"/>
   <int value="-1186760297" label="ForceSpectreVariant2Mitigation:disabled"/>
   <int value="-1185477291" label="ImeDecoderWithSandbox:enabled"/>
@@ -48253,6 +48289,7 @@
   <int value="-304777110" label="PreconnectToSearch:disabled"/>
   <int value="-303992327" label="SwipeToMoveCursor:disabled"/>
   <int value="-302407285" label="WipeDataOnChildAccountSignin:disabled"/>
+  <int value="-301689561" label="PermissionQuietChip:disabled"/>
   <int value="-301228557" label="PageInfoDiscoverability:disabled"/>
   <int value="-300018686" label="disable-cloud-import"/>
   <int value="-299841473" label="top-document-isolation:enabled"/>
@@ -48326,6 +48363,7 @@
   <int value="-239616243" label="HighDynamicRange:enabled"/>
   <int value="-239176328" label="BluetoothAggressiveAppearanceFilter:enabled"/>
   <int value="-237367320" label="AssistantAudioEraser:disabled"/>
+  <int value="-236433493" label="ArcKeyboardShortcutHelperIntegration:enabled"/>
   <int value="-234966279" label="PointerEvent:disabled"/>
   <int value="-234687894"
       label="NonValidatingReloadOnRefreshContentV2:disabled"/>
@@ -48391,6 +48429,7 @@
       label="VmCameraMicIndicatorsAndNotifications:disabled"/>
   <int value="-175696105" label="MessagesForAndroidUpdatePassword:enabled"/>
   <int value="-175666252" label="Portals:disabled"/>
+  <int value="-175574799" label="finch-seed-no-charging-requirement"/>
   <int value="-174829803" label="TabOutlinesInLowContrastThemes:enabled"/>
   <int value="-174706795"
       label="WebPaymentsPerMethodCanMakePaymentQuota:enabled"/>
@@ -49570,6 +49609,7 @@
   <int value="802463708" label="WebViewSurfaceControl:enabled"/>
   <int value="803282885" label="PreferHtmlOverPlugins:disabled"/>
   <int value="803982925" label="CellularForbidAttachApn:disabled"/>
+  <int value="804551127" label="ArcKeyboardShortcutHelperIntegration:disabled"/>
   <int value="804958673" label="LensCameraAssistedSearch:enabled"/>
   <int value="805882800" label="SafetyCheckChromeCleanerChild:disabled"/>
   <int value="806035639" label="EnableNeuralPalmDetectionFilter:disabled"/>
@@ -50572,6 +50612,7 @@
   <int value="1639728471" label="ThemeRefactorAndroid:disabled"/>
   <int value="1640386037" label="ContextualSuggestionsSlimPeekUI:disabled"/>
   <int value="1643626730" label="PrinterStatus:disabled"/>
+  <int value="1643700095" label="PermissionQuietChip:enabled"/>
   <int value="1643712769" label="PrintWithReducedRasterization:enabled"/>
   <int value="1645447927" label="MixedContentSiteSetting:disabled"/>
   <int value="1645479440" label="HistoryManipulationIntervention:disabled"/>
@@ -58350,6 +58391,12 @@
   <int value="7" label="Main resource redirect, no-store"/>
 </enum>
 
+<enum name="NoteCreationFunnel">
+  <int value="0" label="Create Card Button Clicked"/>
+  <int value="1" label="Template Selected"/>
+  <int value="2" label="NoteShared"/>
+</enum>
+
 <enum name="NoteTakingAppLaunchResult">
   <int value="0" label="Chrome app launched successfully"/>
   <int value="1" label="Chrome app missing"/>
@@ -61947,6 +61994,17 @@
   <int value="6" label="Too short EDID data: chromaticity coordinates"/>
   <int value="7" label="Invalid EDID: human unreadable char in name"/>
   <int value="8" label="Too short EDID data: extensions"/>
+  <int value="9" label="Too short EDID data: block zero serial number"/>
+  <int value="10" label="Too short EDID data: week of manufacture"/>
+  <int value="11" label="Too short EDID data: physical display size"/>
+</enum>
+
+<enum name="ParseEdidOptionals">
+  <int value="0" label="All optional fields are available"/>
+  <int value="1" label="Missing: block zero serial number"/>
+  <int value="2" label="Missing: descriptor block serial number"/>
+  <int value="3" label="Missing: week of manufacture"/>
+  <int value="4" label="Missing: physical display size"/>
 </enum>
 
 <enum name="PartnerBookmark.FaviconFetchResult">
@@ -65562,6 +65620,7 @@
   <int value="18" label="kNavigationBadHttpStatus"/>
   <int value="19" label="kClientCertRequested"/>
   <int value="20" label="kNavigationRequestNetworkFailure"/>
+  <int value="21" label="kMaxNumOfRunningPrerendersExceeded"/>
 </enum>
 
 <enum name="PrerenderHoverEvent">
diff --git a/tools/metrics/histograms/histograms_xml/apps/histograms.xml b/tools/metrics/histograms/histograms_xml/apps/histograms.xml
index ca8a5c78..5fcc164 100644
--- a/tools/metrics/histograms/histograms_xml/apps/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/apps/histograms.xml
@@ -1044,6 +1044,16 @@
   </summary>
 </histogram>
 
+<histogram name="Apps.AppListBubbleCreationTime" units="ms"
+    expires_after="2021-12-31">
+  <owner>wcwang@chromium.org</owner>
+  <owner>chromeos-launcher@google.com</owner>
+  <summary>
+    The amount of time it takes to build the app list bubble UI. This is logged
+    each time the app list bubble gets shown.
+  </summary>
+</histogram>
+
 <histogram name="Apps.AppListBubbleShowSource" enum="AppListShowSource"
     expires_after="2022-06-15">
   <owner>newcomer@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
index bc7f8b126..83ac72c 100644
--- a/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/autofill/histograms.xml
@@ -1522,6 +1522,26 @@
   </summary>
 </histogram>
 
+<histogram name="Autofill.PerfectFilling.{FormType}" enum="Boolean"
+    expires_after="M96">
+  <owner>koerber@google.com</owner>
+  <owner>chrome-autofill-alerts@google.com</owner>
+  <summary>
+    For a form of type {FormType}, log at submission time if the filling
+    experience was perfect. In a perfect filling experience, all non-empty
+    fields have been autofilled without subsequent corrections. Note that the
+    {FormType} is not mutually exclusive. If a single form contains both address
+    and credit card information, the metric is recorded for each {FormType}. In
+    such a combined form, both the address and the credit card information needs
+    to be filled perfectly, in order to record perfect filling.
+  </summary>
+  <token key="FormType">
+    <variant name="Addresses" summary="Form contains address information."/>
+    <variant name="CreditCards"
+        summary="Forms contains credit card information."/>
+  </token>
+</histogram>
+
 <histogram name="Autofill.ProfileActionOnFormSubmitted"
     enum="AutofillProfileAction" expires_after="M95">
   <owner>battre@chromium.org</owner>
@@ -2435,6 +2455,32 @@
   </summary>
 </histogram>
 
+<histogram name="Autofill.WebOTP.OneTimeCode.FillDuration.FromInteraction"
+    units="ms" expires_after="2021-11-07">
+  <owner>yigu@chromium.org</owner>
+  <owner>battre@chromium.org</owner>
+  <owner>web-identity@google.com</owner>
+  <summary>
+    Time elapsed between the user's first interaction with a form and the form's
+    submission, for form with autocomplete=&quot;one-time-code&quot;. An
+    interaction requires changing a form control's value manually or via
+    autofill. The interaction can happen on a different form than the one which
+    is submitted. This is recorded once per form submission.
+  </summary>
+</histogram>
+
+<histogram name="Autofill.WebOTP.OneTimeCode.FillDuration.FromLoad" units="ms"
+    expires_after="2021-11-07">
+  <owner>yigu@chromium.org</owner>
+  <owner>battre@chromium.org</owner>
+  <owner>web-identity@google.com</owner>
+  <summary>
+    Time elapsed between form load and form submission, for forms with
+    autocomplete=&quot;one-time-code&quot;. This is recorded once per form
+    submission.
+  </summary>
+</histogram>
+
 <histogram name="Autofill.WebOTP.OneTimeCode.FromAutocomplete" units="Boolean"
     expires_after="2021-11-07">
   <owner>yigu@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
index 4ff94abf..0199554 100644
--- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml
@@ -3273,7 +3273,8 @@
     <variant name="PartitionAlloc"/>
   </token>
   <token key="Context">
-    <variant name="2D"/>
+    <variant name="2D.Accelerated"/>
+    <variant name="2D.Unaccelerated"/>
     <variant name="ImageBitmap"/>
     <variant name="WebGL"/>
     <variant name="WebGL2"/>
diff --git a/tools/metrics/histograms/histograms_xml/compositing/histograms.xml b/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
index fb9618ef3..527673f 100644
--- a/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/compositing/histograms.xml
@@ -170,7 +170,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.ExtraDamage" units="%"
-    expires_after="2021-08-09">
+    expires_after="2022-02-01">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
@@ -185,7 +185,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.FrameBufferDamage"
-    units="%" expires_after="2021-08-15">
+    units="%" expires_after="2022-02-01">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
@@ -199,7 +199,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.RootDamage" units="%"
-    expires_after="2021-08-09">
+    expires_after="2022-02-01">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
@@ -211,7 +211,7 @@
 </histogram>
 
 <histogram name="Compositing.DirectRenderer.PartialSwap.TotalDamage" units="%"
-    expires_after="2021-08-09">
+    expires_after="2022-02-01">
   <owner>vasilyt@chromium.org</owner>
   <owner>backer@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
index c5c6b36..a15d2e3 100644
--- a/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/extensions/histograms.xml
@@ -2201,6 +2201,19 @@
   </summary>
 </histogram>
 
+<histogram name="Extensions.HostPermissions.GrantedAccess"
+    enum="HostPermissionsAccess" expires_after="never">
+<!-- expires-never: Monitors core extension usage. -->
+
+  <owner>emiliapaz@chromium.org</owner>
+  <owner>extensions-core@chromium.org</owner>
+  <summary>
+    Records the host permissions access for a enabled extension as a result of
+    the RuntimeHostPermissions feature. Recorded once per extension at profile
+    initialization.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.IncognitoAllowed" units="units"
     expires_after="never">
 <!-- expires-never: Monitoring extension usage. -->
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 56d7c5e..7c827021 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -14381,6 +14381,9 @@
   <suffix name="LocationBarLeftChip"
       label="A chip on the left-hand side of the location bar that shows a
              bubble when clicked"/>
+  <suffix name="LocationBarLeftQuietChip"
+      label="A less prominent version of a chip on the left-hand side of the
+             location bar that shows a bubble when clicked"/>
   <suffix name="LocationBarRightAnimatedIcon"
       label="An animated indicator on the right-hand side of the location bar"/>
   <suffix name="LocationBarRightStaticIcon"
@@ -20029,8 +20032,8 @@
   <affected-histogram name="V8.WasmDecodeFunctionMicroSeconds"/>
   <affected-histogram name="V8.WasmDecodeModuleMicroSeconds"/>
   <affected-histogram name="V8.WasmDecodeModulePeakMemoryBytes"/>
-  <affected-histogram name="V8.WasmFunctionSizeBytes"/>
   <affected-histogram name="V8.WasmFunctionsPerModule"/>
+  <affected-histogram name="V8.WasmHugeFunctionSizeBytes"/>
   <affected-histogram name="V8.WasmInstantiateModuleMicroSeconds"/>
   <affected-histogram name="V8.WasmMaxMemPagesCount"/>
   <affected-histogram name="V8.WasmMinMemPagesCount"/>
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index e90a3b3..61db2b0 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -5117,15 +5117,15 @@
 </histogram>
 
 <histogram name="MediaRouter.CastStreaming.Session.Length.File" units="ms"
-    expires_after="2021-07-01">
-  <owner>rwkeane@google.com</owner>
+    expires_after="2022-07-01">
+  <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Total length of a Cast Streaming File mirror session.</summary>
 </histogram>
 
 <histogram name="MediaRouter.CastStreaming.Session.Length.OffscreenTab"
-    units="ms" expires_after="2021-07-01">
-  <owner>rwkeane@google.com</owner>
+    units="ms" expires_after="2022-07-01">
+  <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
     Total length of a Cast Streaming Offscreen Tab mirror session.
@@ -5133,15 +5133,15 @@
 </histogram>
 
 <histogram name="MediaRouter.CastStreaming.Session.Length.Screen" units="ms"
-    expires_after="2021-07-01">
-  <owner>rwkeane@google.com</owner>
+    expires_after="2022-07-01">
+  <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>Total length of a Cast Streaming Screen mirror session.</summary>
 </histogram>
 
 <histogram name="MediaRouter.CastStreaming.Session.Length.Tab" units="ms"
-    expires_after="2021-07-01">
-  <owner>rwkeane@google.com</owner>
+    expires_after="2022-07-01">
+  <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
     Total length of a Cast Streaming mirror session of type Tab and NOT of types
@@ -5183,7 +5183,7 @@
 
 <histogram name="MediaRouter.CastWebSenderExtensionLoaded"
     enum="BooleanEnabled" expires_after="2022-04-04">
-  <owner>rwkeane@chromium.org</owner>
+  <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
     Whenever a resource is loaded from the Media Router Component Extension,
diff --git a/tools/metrics/histograms/histograms_xml/nearby/histograms.xml b/tools/metrics/histograms/histograms_xml/nearby/histograms.xml
index e12b8419..00e0820c 100644
--- a/tools/metrics/histograms/histograms_xml/nearby/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/nearby/histograms.xml
@@ -22,7 +22,7 @@
 <histograms>
 
 <histogram name="Nearby.Connections.Bluetooth.Adapter.SetName.Result"
-    enum="BooleanSuccess" expires_after="2021-12-16">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -32,7 +32,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.Adapter.SetScanMode.Result"
-    enum="BooleanSuccess" expires_after="2021-12-16">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -43,7 +43,7 @@
 
 <histogram
     name="Nearby.Connections.Bluetooth.ClassicMedium.ConnectToService.Duration"
-    units="ms" expires_after="2021-12-15">
+    units="ms" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -53,7 +53,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.ClassicMedium.{Operation}.Result"
-    enum="BooleanSuccess" expires_after="2021-12-10">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>Records the result of {Operation}.</summary>
@@ -66,7 +66,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.LEMedium.StartAdvertising.Result"
-    enum="BooleanSuccess" expires_after="2021-12-10">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -75,7 +75,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.LEMedium.StartScanning.Result"
-    enum="BooleanSuccess" expires_after="2021-12-10">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -84,7 +84,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.LEMedium.StopAdvertising.Result"
-    enum="BooleanSuccess" expires_after="2021-12-10">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -93,14 +93,14 @@
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.LEMedium.StopScanning.Result"
-    enum="BooleanSuccess" expires_after="2021-12-10">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>Records whether BLE scanning has been stopped successfully.</summary>
 </histogram>
 
 <histogram name="Nearby.Connections.Bluetooth.Socket.{Operation}.Result"
-    enum="BooleanSuccess" expires_after="2021-12-14">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>Records whether {Operation} has succeeded.</summary>
@@ -112,7 +112,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.ReceiveExpress.NumParsingAttempts"
-    units="attempts" expires_after="2021-08-19">
+    units="attempts" expires_after="2022-02-23">
   <owner>julietlevesque@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -125,7 +125,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.TachyonIceConfigFetcher.CacheHit"
-    enum="BooleanCacheHit" expires_after="2021-10-25">
+    enum="BooleanCacheHit" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -136,7 +136,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.TachyonIceConfigFetcher.FailureReason"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2021-10-25">
+    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -147,7 +147,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.TachyonIceConfigFetcher.OAuthTokenFetchResult"
-    enum="BooleanSuccess" expires_after="2021-10-25">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -158,7 +158,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.TachyonIceConfigFetcher.Result"
-    enum="BooleanSuccess" expires_after="2021-10-25">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -169,7 +169,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.{Direction}Express.OAuthTokenFetchResult"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -185,7 +185,7 @@
 </histogram>
 
 <histogram name="Nearby.Connections.InstantMessaging.{Direction}Express.Result"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -200,7 +200,7 @@
 
 <histogram
     name="Nearby.Connections.InstantMessaging.{Direction}Express.Result.FailureReason"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2021-08-19">
+    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -216,7 +216,7 @@
 
 <histogram name="Nearby.Connections.UtilityProcessShutdownReason"
     enum="NearbyConnectionsUtilityProcessShutdownReason"
-    expires_after="2022-01-26">
+    expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -229,7 +229,7 @@
 <histogram
     name="Nearby.Connections.UtilityProcessShutdownReason.DisconnectedMojoDependency"
     enum="NearbyConnectionsUtilityProcessMojoDependencyName"
-    expires_after="2022-01-26">
+    expires_after="2022-02-23">
   <owner>hansberry@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -243,7 +243,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.BluetoothMacAddressPresentForPrivateCertificateCreation"
-    enum="BooleanPresent" expires_after="2021-08-19">
+    enum="BooleanPresent" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -277,7 +277,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesCount"
-    units="certificates" expires_after="2021-08-19">
+    units="certificates" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -289,7 +289,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesFailuePageCount"
-    units="pages" expires_after="2021-08-19">
+    units="pages" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -301,7 +301,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesHttpResult"
-    enum="NearbyShareHttpResult" expires_after="2021-12-26">
+    enum="NearbyShareHttpResult" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -314,7 +314,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesSuccessPageCount"
-    units="pages" expires_after="2021-08-19">
+    units="pages" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -325,7 +325,7 @@
 
 <histogram
     name="Nearby.Share.Certificates.Manager.DownloadPublicCertificatesSuccessRate"
-    enum="BooleanSuccess" expires_after="2021-10-25">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -337,7 +337,7 @@
 <histogram
     name="Nearby.Share.Certificates.Manager.GetDecryptedPublicCertificateResult"
     enum="NearbyShareCertificateManagerGetDecryptedPublicCertificateResult"
-    expires_after="2021-12-26">
+    expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -347,7 +347,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Certificates.Storage.InitializeAttemptCount"
-    units="attempts" expires_after="2021-08-19">
+    units="attempts" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -358,7 +358,7 @@
 
 <histogram name="Nearby.Share.Certificates.Storage.InitializeAttemptResult"
     enum="NearbyShareCertificateStorageInitializationResult"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -369,7 +369,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Certificates.Storage.InitializeSuccessDuration"
-    units="ms" expires_after="2021-10-25">
+    units="ms" expires_after="2022-02-23">
   <owner>cvandermerwe@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -380,7 +380,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Certificates.Storage.{Operation}SuccessRate"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -400,7 +400,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Connection.EstablishOutgoingConnection.Success"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -414,7 +414,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Connection.EstablishOutgoingConnectionStatus"
-    enum="NearbyShareFinalStatus" expires_after="2021-12-26">
+    enum="NearbyShareFinalStatus" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -427,7 +427,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Connection.TimeToEstablishOutgoingConnection"
-    units="ms" expires_after="2021-12-26">
+    units="ms" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -441,7 +441,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.CanGetProfileUserName"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -456,7 +456,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.DownloadPageCount.{Result}"
-    units="pages" expires_after="2021-08-19">
+    units="pages" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -476,7 +476,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.DownloadResult" enum="BooleanSuccess"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -490,7 +490,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.HttpResult" enum="NearbyShareHttpResult"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -504,7 +504,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.NumContacts.{Type}" units="contacts"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -527,7 +527,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.Percent{Type}" units="%"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -550,7 +550,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Contacts.TimeToDownload.{Result}" units="ms"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -568,7 +568,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.DeviceType{Direction}"
-    enum="NearbyShareDeviceType" expires_after="2021-08-19">
+    enum="NearbyShareDeviceType" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -584,7 +584,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Discovery.Delay.FromStartDiscoveryTo{EndState}"
-    units="ms" expires_after="2021-08-19">
+    units="ms" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -599,7 +599,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Discovery.FurthestDiscoveryProgress"
-    enum="NearbyShareDiscoveryProgress" expires_after="2021-12-26">
+    enum="NearbyShareDiscoveryProgress" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -609,7 +609,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Discovery.LookUpSelectedShareTarget"
-    enum="BooleanFound" expires_after="2021-08-19">
+    enum="BooleanFound" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -621,7 +621,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Discovery.NumShareTargets.{Variation}"
-    units="share targets" expires_after="2021-08-19">
+    units="share targets" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -636,7 +636,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Discovery.{Operation}"
-    enum="NearbyShareServiceStatusCode" expires_after="2021-08-19">
+    enum="NearbyShareServiceStatusCode" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -655,7 +655,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Enabled" enum="NearbyShareEnabledState"
-    expires_after="2021-12-26">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -668,7 +668,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.EnabledStateChanged" enum="BooleanEnabled"
-    expires_after="2021-10-25">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -680,7 +680,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.IsKnownContact" enum="BooleanKnown"
-    expires_after="2021-12-26">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -691,7 +691,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.LocalDeviceData.DeviceDataUpdater.HttpResult"
-    enum="NearbyShareHttpResult" expires_after="2021-12-26">
+    enum="NearbyShareHttpResult" expires_after="2022-02-23">
   <owner>cclem@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -702,7 +702,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Medium.ChangedToMedium"
-    enum="NearbyConnectionsMedium" expires_after="2021-12-26">
+    enum="NearbyConnectionsMedium" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -733,7 +733,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Medium.InitiateBandwidthUpgradeResult"
-    enum="BooleanSuccess" expires_after="2021-12-26">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -747,7 +747,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Medium.RequestedBandwidthUpgradeResult"
-    enum="BooleanUpgraded" expires_after="2021-12-26">
+    enum="BooleanUpgraded" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -758,7 +758,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Onboarding.Duration" units="ms"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>cvandermerwe@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -768,7 +768,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Onboarding.EntryPoint"
-    enum="NearbyShareOnboardingEntryPoint" expires_after="2021-08-19">
+    enum="NearbyShareOnboardingEntryPoint" expires_after="2022-02-23">
   <owner>cvandermerwe@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -780,7 +780,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Onboarding.Result"
-    enum="NearbyShareOnboardingFinalState" expires_after="2021-08-19">
+    enum="NearbyShareOnboardingFinalState" expires_after="2022-02-23">
   <owner>cvandermerwe@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -793,7 +793,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.AttachmentType{Variation}"
-    enum="NearbyShareAttachmentType" expires_after="2021-08-19">
+    enum="NearbyShareAttachmentType" expires_after="2022-02-23">
   <owner>cvandermerwe@google.com</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -813,7 +813,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.FinalStatus{UpgradedMedium}"
-    enum="NearbyShareFinalStatus" expires_after="2021-08-19">
+    enum="NearbyShareFinalStatus" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -831,7 +831,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.Medium" enum="NearbyShareUpgradedMedium"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -843,7 +843,7 @@
 
 <histogram
     name="Nearby.Share.Payload.Medium.Over5MbTransferred{ShareTargetType}"
-    enum="NearbyShareUpgradedMedium" expires_after="2021-08-19">
+    enum="NearbyShareUpgradedMedium" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -862,7 +862,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.NumAttachments{Type}" units="attachments"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -877,7 +877,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.TotalSize{Variation}" units="KB"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -908,7 +908,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Payload.TransferRate{Variation}" units="KB/s"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -939,7 +939,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.StartAdvertising.Result.FailureReason{Mode}"
-    enum="NearbyShareStartAdvertisingFailureReason" expires_after="2021-08-19">
+    enum="NearbyShareStartAdvertisingFailureReason" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -953,7 +953,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.StartAdvertising.Result{Mode}"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -967,7 +967,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.TimeFromInitiateSendToRemoteDeviceNotification"
-    units="ms" expires_after="2021-08-19">
+    units="ms" expires_after="2022-02-23">
   <owner>cvandermerwe@google.com</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -982,7 +982,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.TimeFromLocalAcceptToTransferStart" units="ms"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>cvandermerwe@google.com</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -1092,7 +1092,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Transfer.FinalStatus{Variation}"
-    enum="NearbyShareTransferFinalStatus" expires_after="2021-08-19">
+    enum="NearbyShareTransferFinalStatus" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -1175,7 +1175,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.Transfer.Success" enum="BooleanSuccess"
-    expires_after="2021-08-19">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -1187,7 +1187,7 @@
 
 <histogram
     name="Nearby.Share.Transfer.Success.{Direction}.{ShareTargetType}.{ContactStatus}"
-    enum="BooleanSuccess" expires_after="2021-08-19">
+    enum="BooleanSuccess" expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
@@ -1253,7 +1253,7 @@
 </histogram>
 
 <histogram name="Nearby.Share.VisibilityChoice" enum="NearbyShareVisibility"
-    expires_after="2021-12-26">
+    expires_after="2022-02-23">
   <owner>nohle@chromium.org</owner>
   <owner>nearby-share-chromeos-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
index 0f43045..87dfb90f 100644
--- a/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/new_tab_page/histograms.xml
@@ -89,8 +89,22 @@
   </summary>
 </histogram>
 
+<histogram name="NewTabPage.Carts.AppliedDiscount" units="count"
+    expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Logged when discount is encoded successfully into the navigation url. This
+    histogram always logs a 1 and this value has no meaning other than this
+    occurence happended. Only logged on the 1P NTP. Note that even if the user
+    has Google as their default search engine, Incognito and Guest mode NTPs are
+    not considered 1P and don't log this histogram.
+  </summary>
+</histogram>
+
 <histogram name="NewTabPage.Carts.CartCount" units="count"
-    expires_after="2021-12-05">
+    expires_after="2021-12-30">
   <owner>wychen@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -101,7 +115,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Carts.ClickCart" units="index"
-    expires_after="2021-08-01">
+    expires_after="2021-12-30">
   <owner>wychen@chromium.org</owner>
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -111,6 +125,76 @@
   </summary>
 </histogram>
 
+<histogram name="NewTabPage.Carts.ClickCart.HasDiscount"
+    enum="BooleanHasDiscount" expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Logged when a user clicks on a cart in the cart module. It records whether
+    the clicked cart has a discount or not. Only logged on the 1P NTP. Note that
+    even if the user has Google as their default search engine, Incognito and
+    Guest mode NTPs are not considered 1P and don't log this histogram.
+  </summary>
+</histogram>
+
+<histogram name="NewTabPage.Carts.DataRequest" enum="CartDiscountDataType"
+    expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Records the discount data associated with the cart module. Logged when the
+    chrome cart module makes a data request to a Chrome-external backend. Only
+    logged on the 1P NTP. Note that even if the user has Google as their default
+    search engine, Incognito and Guest mode NTPs are not considered 1P and don't
+    log this histogram.
+  </summary>
+</histogram>
+
+<histogram name="NewTabPage.Carts.DiscountAt" units="index"
+    expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Logged when the cart module is created and if there is at least one
+    abandoned cart. It records the index of the discounted cart within the cart
+    module. Only logged on the 1P NTP. Note that even if the user has Google as
+    their default search engine, Incognito and Guest mode NTPs are not
+    considered 1P and don't log this histogram.
+  </summary>
+</histogram>
+
+<histogram name="NewTabPage.Carts.DiscountConsentShow" units="count"
+    expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Logged every time the consent for Rule-based Discount shows in the cart
+    module. We only show the consent when there are abandoned carts from partner
+    merchants. This histogram always logs a 1 and this value has no meaning
+    other than that an occurrence happended. Only logged on the 1P NTP. Note
+    that even if the user has Google as their default search engine, Incognito
+    and Guest mode NTPs are not considered 1P and don't log this histogram.
+  </summary>
+</histogram>
+
+<histogram name="NewTabPage.Carts.DiscountCountAtLoad" units="count"
+    expires_after="2021-12-30">
+  <owner>meiliang@chromium.org</owner>
+  <owner>yuezhanggg@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Logged when the cart module is created and if there is at least one
+    abandoned cart. It records the number of carts with discount (could be
+    zero). Only logged on the 1P NTP. Note that even if the user has Google as
+    their default search engine, Incognito and Guest mode NTPs are not
+    considered 1P and don't log this histogram.
+  </summary>
+</histogram>
+
 <histogram name="NewTabPage.Click" enum="NTPElement" expires_after="2022-01-01">
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
@@ -1079,6 +1163,9 @@
 
 <histogram name="NewTabPage.MostVisitedAge" units="seconds"
     expires_after="2021-08-09">
+  <obsolete>
+    Removed 2021-07.
+  </obsolete>
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1674,6 +1761,9 @@
 
 <histogram name="NewTabPage.SuggestionsImpressionAge" units="seconds"
     expires_after="2021-08-09">
+  <obsolete>
+    Removed 2021-07.
+  </obsolete>
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
diff --git a/tools/metrics/histograms/histograms_xml/notifications/histograms.xml b/tools/metrics/histograms/histograms_xml/notifications/histograms.xml
index fd3092ed..b221ae22 100644
--- a/tools/metrics/histograms/histograms_xml/notifications/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/notifications/histograms.xml
@@ -106,14 +106,15 @@
   <owner>peter@chromium.org</owner>
   <summary>
     Records the number of times the 'Notifications muted' notification got shown
-    before the user took an action. Clicking on 'Show' can only be recorded once
-    per session while 'Body' and 'Close' may be recorded multiple times. Logged
-    each time the user interacts with the notification. {Action}
+    before the user took an action. Clicking on 'Show' and 'Snooze' can only be
+    recorded once per session while 'Body' and 'Close' may be recorded multiple
+    times. Logged each time the user interacts with the notification. {Action}
   </summary>
   <token key="Action">
     <variant name="Body"/>
     <variant name="Close"/>
     <variant name="Show"/>
+    <variant name="Snooze"/>
   </token>
 </histogram>
 
@@ -130,6 +131,7 @@
     <variant name="Body"/>
     <variant name="Close"/>
     <variant name="Show"/>
+    <variant name="Snooze"/>
   </token>
 </histogram>
 
@@ -190,6 +192,19 @@
   </summary>
 </histogram>
 
+<histogram name="Notifications.Blocker.ScreenCapture.SnoozedCount"
+    units="notifications" expires_after="2021-11-21">
+  <owner>knollr@chromium.org</owner>
+  <owner>peter@chromium.org</owner>
+  <summary>
+    The number of snoozed notifications that got prevented from showing up on
+    screen during a screen capture session. This means that the user clicked on
+    the &quot;Snooze&quot; action of a muted notification and continued to
+    receive notifications but we queued them without notifying the user at all.
+    Logged once after each screen capture session ends.
+  </summary>
+</histogram>
+
 <histogram name="Notifications.Chime.Android.Events" enum="ChimeEvent"
     expires_after="never">
   <owner>hesen@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index a07f2b4c..ae37844 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -4683,9 +4683,20 @@
   </summary>
 </histogram>
 
+<histogram name="Display.BlockZeroSerialNumberType"
+    enum="BlockZeroSerialNumberType" expires_after="2022-07-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>chromeos-gfx@google.com</owner>
+  <summary>
+    The type of serial number retrived from block zero of a display's EDID
+    during EDID parsing.
+  </summary>
+</histogram>
+
 <histogram name="Display.ParseEdidFailure" enum="ParseEdidFailure"
     expires_after="2021-11-14">
   <owner>sashamcintosh@chromium.org</owner>
+  <owner>gildekel@chromium.org</owner>
   <owner>chromeos-gfx@google.com</owner>
   <summary>
     Type of failure that occurs during EDID parsing. Typically the failure is
@@ -4694,6 +4705,16 @@
   </summary>
 </histogram>
 
+<histogram name="Display.ParseEdidOptionals" enum="ParseEdidOptionals"
+    expires_after="2022-07-01">
+  <owner>gildekel@chromium.org</owner>
+  <owner>chromeos-gfx@google.com</owner>
+  <summary>
+    The availability (or lack thereof) of tracked optional fields during EDID
+    parsing of external.
+  </summary>
+</histogram>
+
 <histogram name="DisplayManager.InternalDisplayZoomPercentage" units="%"
     expires_after="2022-06-15">
   <owner>zentaro@chromium.org</owner>
@@ -8417,117 +8438,6 @@
   </summary>
 </histogram>
 
-<histogram name="KeyboardAccessory.AccessoryActionImpression"
-    enum="AccessoryAction" expires_after="2021-12-05">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records whenever users faces an action in the accessory bar or
-    one of its sheets.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessoryActionSelected"
-    enum="AccessoryAction" expires_after="2021-12-05">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records whenever users select an action in the accessory bar
-    or one of its sheets.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessoryBarShown"
-    enum="AccessoryBarContents" expires_after="2021-12-05">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records how often users encounter the keyboard accessory bar.
-    Its buckets show the contents when it came up. Every bucket may be logged up
-    to one time per impression.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessorySheetSuggestionCount" units="count"
-    expires_after="2021-10-04">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records how many suggestions a user faced when opening a
-    sheet. The base histogram counts impressions across all sheets.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessorySheetSuggestionsSelected"
-    enum="AccessorySuggestionType" expires_after="2021-07-27">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records which type of suggestion was selected from an open
-    sheet.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessorySheetTriggered"
-    enum="AccessorySheetTrigger" expires_after="2021-12-05">
-  <owner>fhorschig@chromium.org</owner>
-  <owner>ioanap@chromium.org</owner>
-  <summary>
-    Android only. Records how often the bottom sheet was opened or closed by a
-    user and the overall count of closures. Closing buckets may be logged up to
-    one time per trigger. There are suffixes for each specific sheet type.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessoryToggleClicked"
-    enum="AccessoryToggleType" expires_after="2021-12-05">
-  <owner>ioanap@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Android only. Records how often the user clicks on a certain toggle when
-    opening an accessory sheet together with the state the toggle was in before
-    clicking.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.AccessoryToggleImpression"
-    enum="AccessoryToggleType" expires_after="2021-12-05">
-  <owner>ioanap@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Android only. Records how often the user sees a certain toggle when opening
-    an accessory sheet together with the state the toggle was in.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.DisabledSavingAccessoryImpressions"
-    enum="BooleanShown" expires_after="M95">
-  <owner>ioanap@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Android only. Records the number of times that the keyboard accessory was
-    shown on a form for which saving is disabled (with a crossed-out key icon).
-    Recorded when the user focuses the password field.
-
-    Note: Only the &quot;Shown&quot; bucket should contain samples.
-  </summary>
-</histogram>
-
-<histogram name="KeyboardAccessory.GenerationDialogChoice.{GenerationType}"
-    enum="GenerationDialogChoice" expires_after="M95">
-  <owner>ioanap@chromium.org</owner>
-  <owner>vasilii@chromium.org</owner>
-  <summary>
-    Android only. Records the interactions with the password generation dialog
-    for {GenerationType}. Recorded when the user taps a button in the dialog or
-    dismsses it.
-  </summary>
-  <token key="GenerationType">
-    <variant name="Automatic" summary="automatic generation"/>
-    <variant name="Manual" summary="manual generation"/>
-  </token>
-</histogram>
-
 <histogram name="Kiosk.Launch.CryptohomeFailure" enum="LoginFailureReason"
     expires_after="2021-11-28">
   <owner>xiyuan@chromium.org</owner>
@@ -10694,6 +10604,33 @@
   </summary>
 </histogram>
 
+<histogram name="NoteCreation.CreationStatus" enum="BooleanCreated"
+    expires_after="2021-12-01">
+  <owner>sebsg@chromium.org</owner>
+  <owner>chrome-creation@google.com</owner>
+  <summary>
+    Records whether user created a note when they were in the creation flow of
+    the feature.
+  </summary>
+</histogram>
+
+<histogram name="NoteCreation.Funnel" enum="NoteCreationFunnel"
+    expires_after="2021-12-01">
+  <owner>sebsg@chromium.org</owner>
+  <owner>chrome-creation@google.com</owner>
+  <summary>
+    Records the different states of the funnel that a user goes through in the
+    note creation feature.
+  </summary>
+</histogram>
+
+<histogram name="NoteCreation.NoteShared" enum="BooleanShared"
+    expires_after="2021-12-01">
+  <owner>sebsg@chromium.org</owner>
+  <owner>chrome-creation@google.com</owner>
+  <summary>Records whether the created note was shared or not.</summary>
+</histogram>
+
 <histogram name="NQE.CachedNetworkQualityAvailable" enum="BooleanAvailable"
     expires_after="2021-10-10">
   <owner>tbansal@chromium.org</owner>
@@ -18961,6 +18898,17 @@
   </summary>
 </histogram>
 
+<histogram name="Webapp.SystemApps.BackgroundTaskStartDelay" units="ms"
+    expires_after="2022-01-05">
+  <owner>dominicschulz@google.com</owner>
+  <owner>qjw@chromium.org</owner>
+  <summary>
+    Records how long the SWA background task waits for the system to become idle
+    before starting to run. Recorded in milliseconds, from 1 millisecond to 1
+    hour. This is logged when a SWA background task starts.
+  </summary>
+</histogram>
+
 <histogram name="Webapp.SystemApps.BadNavigate.Type" units="App ID"
     expires_after="2021-09-01">
   <owner>calamity@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml
index ecd22317..2a147fbb 100644
--- a/tools/metrics/histograms/histograms_xml/password/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -26,6 +26,117 @@
   <variant name="PasswordFieldOnFocus" summary="on focus event"/>
 </variants>
 
+<histogram name="KeyboardAccessory.AccessoryActionImpression"
+    enum="AccessoryAction" expires_after="2021-12-05">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records whenever users faces an action in the accessory bar or
+    one of its sheets.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessoryActionSelected"
+    enum="AccessoryAction" expires_after="2021-12-05">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records whenever users select an action in the accessory bar
+    or one of its sheets.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessoryBarShown"
+    enum="AccessoryBarContents" expires_after="2021-12-05">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records how often users encounter the keyboard accessory bar.
+    Its buckets show the contents when it came up. Every bucket may be logged up
+    to one time per impression.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessorySheetSuggestionCount" units="count"
+    expires_after="2021-10-04">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records how many suggestions a user faced when opening a
+    sheet. The base histogram counts impressions across all sheets.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessorySheetSuggestionsSelected"
+    enum="AccessorySuggestionType" expires_after="2021-12-05">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records which type of suggestion was selected from an open
+    sheet.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessorySheetTriggered"
+    enum="AccessorySheetTrigger" expires_after="2021-12-05">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>ioanap@chromium.org</owner>
+  <summary>
+    Android only. Records how often the bottom sheet was opened or closed by a
+    user and the overall count of closures. Closing buckets may be logged up to
+    one time per trigger. There are suffixes for each specific sheet type.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessoryToggleClicked"
+    enum="AccessoryToggleType" expires_after="2021-12-05">
+  <owner>ioanap@chromium.org</owner>
+  <owner>fhorschig@chromium.org</owner>
+  <summary>
+    Android only. Records how often the user clicks on a certain toggle when
+    opening an accessory sheet together with the state the toggle was in before
+    clicking.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.AccessoryToggleImpression"
+    enum="AccessoryToggleType" expires_after="2021-12-05">
+  <owner>ioanap@chromium.org</owner>
+  <owner>fhorschig@chromium.org</owner>
+  <summary>
+    Android only. Records how often the user sees a certain toggle when opening
+    an accessory sheet together with the state the toggle was in.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.DisabledSavingAccessoryImpressions"
+    enum="BooleanShown" expires_after="M95">
+  <owner>ioanap@chromium.org</owner>
+  <owner>fhorschig@chromium.org</owner>
+  <summary>
+    Android only. Records the number of times that the keyboard accessory was
+    shown on a form for which saving is disabled (with a crossed-out key icon).
+    Recorded when the user focuses the password field.
+
+    Note: Only the &quot;Shown&quot; bucket should contain samples.
+  </summary>
+</histogram>
+
+<histogram name="KeyboardAccessory.GenerationDialogChoice.{GenerationType}"
+    enum="GenerationDialogChoice" expires_after="M95">
+  <owner>ioanap@chromium.org</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Android only. Records the interactions with the password generation dialog
+    for {GenerationType}. Recorded when the user taps a button in the dialog or
+    dismsses it.
+  </summary>
+  <token key="GenerationType">
+    <variant name="Automatic" summary="automatic generation"/>
+    <variant name="Manual" summary="manual generation"/>
+  </token>
+</histogram>
+
 <histogram name="PasswordBubble.CompromisedBubble.CheckClicked"
     enum="BooleanClicked" expires_after="2021-11-14">
   <owner>vasilii@chromium.org</owner>
@@ -1457,6 +1568,9 @@
 
 <histogram name="PasswordManager.LeakDetection.AccessTokenFetchStatus"
     enum="GoogleServiceAuthError" expires_after="2021-08-09">
+  <obsolete>
+    Removed in M93.
+  </obsolete>
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1467,6 +1581,9 @@
 
 <histogram name="PasswordManager.LeakDetection.AccessTokenNetErrorCode"
     enum="NetErrorCodes" expires_after="2021-08-09">
+  <obsolete>
+    Removed in M93.
+  </obsolete>
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1484,6 +1601,9 @@
 
 <histogram name="PasswordManager.LeakDetection.AnalyzeSingleLeakResponseTime"
     units="ms" expires_after="2021-08-09">
+  <obsolete>
+    Removed in M93.
+  </obsolete>
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>The time it took to analyze a single leak lookup response.</summary>
@@ -1617,7 +1737,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.ReceiveSingleLeakResponseTime"
-    units="ms" expires_after="2021-08-09">
+    units="ms" expires_after="M100">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2321,7 +2441,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TouchToFill.CredentialIndex" units="index"
-    expires_after="2021-08-09">
+    expires_after="2021-12-19">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/permissions/histograms.xml b/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
index c56695aa..d77c756 100644
--- a/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/permissions/histograms.xml
@@ -589,6 +589,19 @@
   </token>
 </histogram>
 
+<histogram name="Permissions.QuietChip.TimeToInteraction" units="ms"
+    expires_after="2021-10-25">
+  <owner>elklm@chromium.org</owner>
+  <owner>engedy@chromium.org</owner>
+  <summary>
+    Records how long it takes for the user to click on the quiet chip after it
+    was shown. Chip framework is only available on Desktop. Recorded only if the
+    user clicks on the quiet chip. We can learn what % of prompts get ignored by
+    comparing this metric and
+    `PermissionPromptDisposition.LocationBarLeftQuietChip`.
+  </summary>
+</histogram>
+
 <histogram
     name="Permissions.QuietNotificationPrompts.DidEnableAdapativelyInPrefs"
     enum="Boolean" expires_after="2021-10-10">
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
index bcd3cd2..8c3500c 100644
--- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -1282,7 +1282,10 @@
 </histogram>
 
 <histogram name="Sync.Startup.TypeTriggeringInit" enum="SyncModelTypes"
-    expires_after="2021-08-15">
+    expires_after="M92">
+  <obsolete>
+    Removed in M93.
+  </obsolete>
   <owner>mastiz@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <component>Services&gt;Sync</component>
diff --git a/tools/metrics/histograms/histograms_xml/v8/histograms.xml b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
index fd4e932c..7226011 100644
--- a/tools/metrics/histograms/histograms_xml/v8/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/v8/histograms.xml
@@ -1409,6 +1409,10 @@
 
 <histogram name="V8.WasmFunctionSizeBytes" units="bytes"
     expires_after="2021-08-01">
+  <obsolete>
+    Removed 07/2021 in favor of V8.WasmHugeFunctionSizeBytes which gives a
+    better overview about critical functions.
+  </obsolete>
   <owner>ecmziegler@chromium.org</owner>
   <owner>adamk@chromium.org</owner>
   <owner>clemensb@chromium.org</owner>
@@ -1429,6 +1433,18 @@
   </summary>
 </histogram>
 
+<histogram name="V8.WasmHugeFunctionSizeBytes" units="bytes"
+    expires_after="2022-07-01">
+  <owner>ecmziegler@chromium.org</owner>
+  <owner>adamk@chromium.org</owner>
+  <owner>clemensb@chromium.org</owner>
+  <summary>
+    Size of a huge WebAssembly function in bytes. A function is considered huge
+    if it is larger than 100kB. Recorded on each compilation of a single
+    function, either synchronous, asynchronous, or lazily.
+  </summary>
+</histogram>
+
 <histogram name="V8.WasmInstantiateModuleMicroSeconds" units="microseconds"
     expires_after="2021-12-05">
   <owner>ecmziegler@chromium.org</owner>
diff --git a/tools/origin_trials/check_token.py b/tools/origin_trials/check_token.py
index a18a4ba8..33a0352e 100755
--- a/tools/origin_trials/check_token.py
+++ b/tools/origin_trials/check_token.py
@@ -222,7 +222,8 @@
   if (usage_restriction is not None and version != VERSION3):
     print("The usage field can only be be set in Version 3 token.")
     sys.exit(1)
-  if (usage_restriction not in USAGE_RESTRICTION):
+  if (usage_restriction is not None
+      and usage_restriction not in USAGE_RESTRICTION):
     print("Only empty string and \"subset\" are supported in the usage field.")
     sys.exit(1)
 
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 0542f65..b35d2a2 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@
 {
     "trace_processor_shell": {
         "win": {
-            "hash": "1c01e6117f47322571c17ff23559e3c989634602",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/e989e5e45ab55e146e4c55dd16092d0af5332313/trace_processor_shell.exe"
+            "hash": "82e3f4365393d31a587d58b9ae66e9f81461e960",
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/ca06eb435506f54cf6a7c013a6c545726532f2b3/trace_processor_shell.exe"
         },
         "mac": {
-            "hash": "073571b5c0f10cf7487fbabc40a38e8dab74c93f",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/e989e5e45ab55e146e4c55dd16092d0af5332313/trace_processor_shell"
+            "hash": "e9c26d8ab8a0a60c936bfbd07de9074b2470b392",
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/ca06eb435506f54cf6a7c013a6c545726532f2b3/trace_processor_shell"
         },
         "linux": {
-            "hash": "00b0be1a7b90c081a7fda9d9058105fb403c51b7",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/e989e5e45ab55e146e4c55dd16092d0af5332313/trace_processor_shell"
+            "hash": "81aad5d60c5ed2f7b1a7ff926de7e6a06fe1d097",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/80c6050169a35f725abc5390a7ef1bc36298462f/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 4c3858e..a367711 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -13,6 +13,7 @@
 
 # Benchmark: blink_perf.accessibility
 crbug.com/1114112 [ android-nexus-5x android-webview ] blink_perf.accessibility/build-table.html [ Skip ]
+crbug.com/1226849 [ android-nexus-5x android-webview ] blink_perf.accessibility/line-breaks.html [ Skip ]
 
 # Benchmark: blink_perf.bindings
 crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/structured-clone-json-deserialize.html [ Skip ]
@@ -72,6 +73,9 @@
 # Benchmark: dromaeo
 crbug.com/1050065 [ android-pixel-2 ] dromaeo/http://dromaeo.com?dom-modify [ Skip ]
 
+# Benchmark: desktop_ui
+crbug.com/1226867 [ win ] desktop_ui/tab_search:100_recently_closed [ Skip ]
+
 # Benchmark: blink_perf.svg
 crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/SvgCubics.html [ Skip ]
 crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/Debian.html [ Skip ]
@@ -211,6 +215,7 @@
 crbug.com/1211795 [ mac ] rendering.desktop/camera_to_webgl [ Skip ]
 crbug.com/1211795 [ mac ] rendering.desktop/skelebuddies_wasm_2020 [ Skip ]
 crbug.com/1211795 [ mac ] rendering.desktop/skelebuddies_wasm_2020_fast_call [ Skip ]
+crbug.com/1226854 [ mac ] rendering.desktop/text_scrollbar_* [ Skip ]
 
 # Benchmark: rendering.mobile
 crbug.com/785485 [ android-webview ] rendering.mobile/kevs_3d [ Skip ]
@@ -264,6 +269,7 @@
 crbug.com/1193722 [ android-pixel-2 android-webview ] rendering.mobile/espn_pathological_2018 [ Skip ]
 crbug.com/1193722 [ android-pixel-4 ] rendering.mobile/espn_pathological_2018 [ Skip ]
 crbug.com/1188586 [ android-pixel-4 android-webview ] rendering.mobile/text_hover_* [ Skip ]
+crbug.com/1226854 [ android ] rendering.mobile/text_scrollbar_* [ Skip ]
 
 # Benchmark: rasterize_and_record_micro.top_25
 crbug.com/764543 rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
diff --git a/tools/perf/page_sets/desktop_ui/tab_search_story.py b/tools/perf/page_sets/desktop_ui/tab_search_story.py
index f5ad58e0..6d62f63 100644
--- a/tools/perf/page_sets/desktop_ui/tab_search_story.py
+++ b/tools/perf/page_sets/desktop_ui/tab_search_story.py
@@ -158,21 +158,21 @@
   NAME = 'tab_search:10_recently_closed'
   URL_LIST = ['chrome://version?q={}'.format(i) for i in range(10)]
   URL = URL_LIST[0]
-  WAIT_FOR_NETWORK_QUIESCENCE = False
+  WAIT_FOR_NETWORK_QUIESCENCE = True
 
 
 class TabSearchStoryRecentlyClosed50(TabSearchRecentlyClosedStory):
   NAME = 'tab_search:50_recently_closed'
   URL_LIST = ['chrome://version?q={}'.format(i) for i in range(50)]
   URL = URL_LIST[0]
-  WAIT_FOR_NETWORK_QUIESCENCE = False
+  WAIT_FOR_NETWORK_QUIESCENCE = True
 
 
 class TabSearchStoryRecentlyClosed100(TabSearchRecentlyClosedStory):
   NAME = 'tab_search:100_recently_closed'
   URL_LIST = ['chrome://version?q={}'.format(i) for i in range(100)]
   URL = URL_LIST[0]
-  WAIT_FOR_NETWORK_QUIESCENCE = False
+  WAIT_FOR_NETWORK_QUIESCENCE = True
 
 
 class TabSearchStoryTop10(TabSearchStory):
diff --git a/tools/traffic_annotation/scripts/check_annotations.py b/tools/traffic_annotation/scripts/check_annotations.py
index 1842ec2d..f87f566a 100755
--- a/tools/traffic_annotation/scripts/check_annotations.py
+++ b/tools/traffic_annotation/scripts/check_annotations.py
@@ -23,7 +23,7 @@
 
 # If the auditor.py part of this test starts failing, please set
 # TEST_PYTHON_AUDITOR to "False" and file a bug (see comment above).
-TEST_PYTHON_AUDITOR = False
+TEST_PYTHON_AUDITOR = True
 
 # Threshold for the change list size to trigger full test.
 CHANGELIST_SIZE_TO_TRIGGER_FULL_TEST = 100
diff --git a/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py b/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py
index 5c1b271..2b7ac62 100755
--- a/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py
+++ b/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py
@@ -22,7 +22,7 @@
 
 # If the auditor.py part of this test starts failing, please set
 # TEST_PYTHON_AUDITOR to "False" and file a bug (see comment above).
-TEST_PYTHON_AUDITOR = False
+TEST_PYTHON_AUDITOR = True
 
 MINIMUM_EXPECTED_NUMBER_OF_ANNOTATIONS = 260
 
diff --git a/tools/typescript/ts_library.gni b/tools/typescript/ts_library.gni
index 645afbc..e29fb803 100644
--- a/tools/typescript/ts_library.gni
+++ b/tools/typescript/ts_library.gni
@@ -107,6 +107,9 @@
       "chrome://resources/*|" +
           rebase_path("$root_gen_dir/ui/webui/resources/preprocessed/*",
                       target_gen_dir),
+      "//resources/*|" +
+          rebase_path("$root_gen_dir/ui/webui/resources/preprocessed/*",
+                      target_gen_dir),
       "chrome://resources/polymer/v3_0/*|" +
           rebase_path("//third_party/polymer/v3_0/components-chromium/*",
                       target_gen_dir),
diff --git a/ui/accessibility/platform/inspect/ax_inspect.cc b/ui/accessibility/platform/inspect/ax_inspect.cc
index 7cf394ad..29704c9 100644
--- a/ui/accessibility/platform/inspect/ax_inspect.cc
+++ b/ui/accessibility/platform/inspect/ax_inspect.cc
@@ -22,6 +22,9 @@
 
 AXPropertyFilter::AXPropertyFilter(const AXPropertyFilter&) = default;
 
+AXPropertyFilter& AXPropertyFilter::operator=(const AXPropertyFilter&) =
+    default;
+
 AXPropertyFilter::AXPropertyFilter(const std::string& str, Type type)
     : match_str(str), type(type) {
   size_t index = str.find(';');
diff --git a/ui/accessibility/platform/inspect/ax_inspect.h b/ui/accessibility/platform/inspect/ax_inspect.h
index d3def966..55980f3 100644
--- a/ui/accessibility/platform/inspect/ax_inspect.h
+++ b/ui/accessibility/platform/inspect/ax_inspect.h
@@ -63,6 +63,7 @@
 
   AXPropertyFilter(const std::string& str, Type type);
   AXPropertyFilter(const AXPropertyFilter&);
+  AXPropertyFilter& operator=(const AXPropertyFilter&);
 };
 
 // A single node filter specification  which will exclude any node where the
diff --git a/ui/android/java/res/values/attrs.xml b/ui/android/java/res/values/attrs.xml
index 9a656c4..29af8f9 100644
--- a/ui/android/java/res/values/attrs.xml
+++ b/ui/android/java/res/values/attrs.xml
@@ -11,6 +11,7 @@
     <!-- Material roles currently only used in downstream. Define them here
          so public builds do not complain the attribute is not found. Removal
          tracked in https://crbug.com/1216204. -->
+    <attr name="colorOnPrimaryContainer" format="color"/>
     <attr name="colorOnSurfaceVariant" format="color"/>
     <attr name="colorOnSurfaceInverse" format="color"/>
     <attr name="elevationOverlayAccentColor" format="color"/>
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml
index 691686d..54a25a3 100644
--- a/ui/android/java/res/values/color_palette.xml
+++ b/ui/android/java/res/values/color_palette.xml
@@ -10,12 +10,14 @@
     <color name="baseline_primary_200">#A8C7FA</color>
     <color name="baseline_primary_600">#0B57D0</color>
     <color name="baseline_primary_800">#062E6F</color>
+    <color name="baseline_primary_900">#041E49</color>
     <color name="baseline_neutral_100">#E3E3E3</color>
     <color name="baseline_neutral_100_alpha_12">#1EE3E3E3</color>
     <color name="baseline_neutral_900_alpha_12">#1E1F1F1F</color>
     <color name="baseline_neutral_900_with_neutral_100_alpha_38">#696969</color>
     <color name="baseline_neutral_variant_100">#E1E3E1</color>
     <color name="baseline_neutral_variant_200">#C4C7C5</color>
+    <color name="baseline_neutral_variant_200_alpha_15">#26C4C7C5</color>
     <color name="baseline_neutral_variant_400">#8E918F</color>
 
     <color name="baseline_neutral_900_with_neutral_200_alpha_12_with_primary_200_alpha_2">#353637</color>
diff --git a/ui/aura/client/drag_drop_delegate.cc b/ui/aura/client/drag_drop_delegate.cc
index 2e250bc..f7b0d4e8 100644
--- a/ui/aura/client/drag_drop_delegate.cc
+++ b/ui/aura/client/drag_drop_delegate.cc
@@ -17,6 +17,8 @@
 DragUpdateInfo::DragUpdateInfo(int op, ui::DataTransferEndpoint endpoint)
     : drag_operation(op), data_endpoint(endpoint) {}
 
+DragUpdateInfo::DragUpdateInfo(const DragUpdateInfo& update_info) = default;
+
 DragUpdateInfo& DragUpdateInfo::operator=(const DragUpdateInfo& update_info) =
     default;
 
diff --git a/ui/aura/client/drag_drop_delegate.h b/ui/aura/client/drag_drop_delegate.h
index 717ff6ed..5f1eca3 100644
--- a/ui/aura/client/drag_drop_delegate.h
+++ b/ui/aura/client/drag_drop_delegate.h
@@ -27,6 +27,7 @@
   DragUpdateInfo();
   DragUpdateInfo(int op, ui::DataTransferEndpoint endpoint);
 
+  DragUpdateInfo(const DragUpdateInfo& update_info);
   DragUpdateInfo& operator=(const DragUpdateInfo& update_info);
 
   // A bitmask of the DragDropTypes::DragOperation supported.
diff --git a/ui/base/cocoa/constrained_window/constrained_window_animation.mm b/ui/base/cocoa/constrained_window/constrained_window_animation.mm
index de254513..c894456 100644
--- a/ui/base/cocoa/constrained_window/constrained_window_animation.mm
+++ b/ui/base/cocoa/constrained_window/constrained_window_animation.mm
@@ -7,12 +7,12 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
 #import "base/mac/foundation_util.h"
 #include "base/native_library.h"
 #include "base/notreached.h"
-#include "base/stl_util.h"
 #include "ui/gfx/animation/tween.h"
 
 // The window animations in this file use private APIs as described here:
diff --git a/ui/base/l10n/l10n_util_mac_unittest.mm b/ui/base/l10n/l10n_util_mac_unittest.mm
index 9b28024..738cd92 100644
--- a/ui/base/l10n/l10n_util_mac_unittest.mm
+++ b/ui/base/l10n/l10n_util_mac_unittest.mm
@@ -5,7 +5,7 @@
 #import <Foundation/Foundation.h>
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/sys_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/ui/base/models/table_model.cc b/ui/base/models/table_model.cc
index 91453d5..9f8e19d 100644
--- a/ui/base/models/table_model.cc
+++ b/ui/base/models/table_model.cc
@@ -38,6 +38,8 @@
 
 TableColumn::TableColumn(const TableColumn& other) = default;
 
+TableColumn& TableColumn::operator=(const TableColumn& other) = default;
+
 // TableModel -----------------------------------------------------------------
 
 // Used for sorting.
diff --git a/ui/base/models/table_model.h b/ui/base/models/table_model.h
index dcb2497..7cd5fca 100644
--- a/ui/base/models/table_model.h
+++ b/ui/base/models/table_model.h
@@ -70,6 +70,7 @@
   TableColumn();
   TableColumn(int id, Alignment alignment, int width, float percent);
   TableColumn(const TableColumn& other);
+  TableColumn& operator=(const TableColumn& other);
 
   // A unique identifier for the column.
   int id;
diff --git a/ui/base/test/ui_controls_mac.mm b/ui/base/test/ui_controls_mac.mm
index 979aca2..198fb82 100644
--- a/ui/base/test/ui_controls_mac.mm
+++ b/ui/base/test/ui_controls_mac.mm
@@ -9,9 +9,9 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/cxx17_backports.h"
 #import "base/mac/foundation_util.h"
 #import "base/mac/scoped_objc_class_swizzler.h"
-#include "base/stl_util.h"
 #include "base/task/current_thread.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "ui/base/cocoa/cocoa_base_utils.h"
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
index 384150d..94430ef 100644
--- a/ui/base/ui_base_switches.cc
+++ b/ui/base/ui_base_switches.cc
@@ -6,6 +6,14 @@
 
 namespace switches {
 
+#if defined(OS_ANDROID)
+// Disable overscroll edge effects like those found in Android views.
+const char kDisableOverscrollEdgeEffect[] = "disable-overscroll-edge-effect";
+
+// Disable the pull-to-refresh effect when vertically overscrolling content.
+const char kDisablePullToRefreshEffect[] = "disable-pull-to-refresh-effect";
+#endif
+
 #if defined(OS_MAC)
 // Disable use of AVFoundation to draw video content.
 const char kDisableAVFoundationOverlays[] = "disable-avfoundation-overlays";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
index 07ce187..bae5bce 100644
--- a/ui/base/ui_base_switches.h
+++ b/ui/base/ui_base_switches.h
@@ -12,6 +12,11 @@
 
 namespace switches {
 
+#if defined(OS_ANDROID)
+COMPONENT_EXPORT(UI_BASE) extern const char kDisableOverscrollEdgeEffect[];
+COMPONENT_EXPORT(UI_BASE) extern const char kDisablePullToRefreshEffect[];
+#endif
+
 #if defined(OS_MAC)
 COMPONENT_EXPORT(UI_BASE) extern const char kDisableAVFoundationOverlays[];
 COMPONENT_EXPORT(UI_BASE) extern const char kDisableMacOverlays[];
diff --git a/ui/base/ui_base_switches_util.cc b/ui/base/ui_base_switches_util.cc
index 1763af3..f85d9c0 100644
--- a/ui/base/ui_base_switches_util.cc
+++ b/ui/base/ui_base_switches_util.cc
@@ -7,10 +7,33 @@
 #include "base/command_line.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches.h"
 
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace switches {
 
+bool IsElasticOverscrollEnabled() {
+// On macOS this value is adjusted in `UpdateScrollbarTheme()`,
+// but the system default is true.
+#if defined(OS_MAC)
+  return true;
+#elif defined(OS_WIN)
+  return base::FeatureList::IsEnabled(features::kElasticOverscroll);
+#elif defined(OS_ANDROID)
+  return base::android::BuildInfo::GetInstance()->sdk_int() >=
+             base::android::SDK_VERSION_R &&
+         !base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kDisableOverscrollEdgeEffect) &&
+         base::FeatureList::IsEnabled(features::kElasticOverscroll);
+#else
+  return false;
+#endif
+}
+
 bool IsTouchDragDropEnabled() {
   const auto* const command_line = base::CommandLine::ForCurrentProcess();
 #if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_ANDROID)
diff --git a/ui/base/ui_base_switches_util.h b/ui/base/ui_base_switches_util.h
index 9928e56..a5ae8ff 100644
--- a/ui/base/ui_base_switches_util.h
+++ b/ui/base/ui_base_switches_util.h
@@ -9,6 +9,7 @@
 
 namespace switches {
 
+COMPONENT_EXPORT(UI_BASE) bool IsElasticOverscrollEnabled();
 COMPONENT_EXPORT(UI_BASE) bool IsTouchDragDropEnabled();
 
 }  // namespace switches
diff --git a/ui/chromeos/translations/ui_chromeos_strings_cs.xtb b/ui/chromeos/translations/ui_chromeos_strings_cs.xtb
index f3eeda8..c25d3245 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_cs.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_cs.xtb
@@ -168,7 +168,7 @@
 <translation id="2470939964922472929">Příliš mnohokrát jste zadali nesprávný PIN. Pokud chcete nastavit nový PIN, zadejte osmimístný kód PUK, který vám poskytl operátor.</translation>
 <translation id="2500392669976258912">gudžarátština (fonetická)</translation>
 <translation id="2515586267016047495">Alt</translation>
-<translation id="2517472476991765520">Vyhledat</translation>
+<translation id="2517472476991765520">Naskenovat</translation>
 <translation id="2534155362429831547">Byly smazány položky (celkem <ph name="NUMBER_OF_ITEMS" />)</translation>
 <translation id="2534460670861217804">Proxy server protokolu HTTPS</translation>
 <translation id="2541377937973966830">Obsah této složky je pouze ke čtení. Některé aktivity nejsou podporovány.</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ta.xtb b/ui/chromeos/translations/ui_chromeos_strings_ta.xtb
index 3aef633e..3a6e38fe 100644
--- a/ui/chromeos/translations/ui_chromeos_strings_ta.xtb
+++ b/ui/chromeos/translations/ui_chromeos_strings_ta.xtb
@@ -38,9 +38,9 @@
 <translation id="1291603679744561561">சிம் பூட்டப்பட்டுள்ளது</translation>
 <translation id="1293556467332435079">Files</translation>
 <translation id="1297922636971898492">Google இயக்ககம் இப்போது கிடைக்கவில்லை. Google இயக்ககம் இணைப்பு கிடைத்தவுடன் பதிவேற்றம் தானாகவே மறுதொடக்கம் செய்யப்படும்.</translation>
-<translation id="1307931752636661898">Linux கோப்புகளைப் பார்க்க முடியவில்லை</translation>
+<translation id="1307931752636661898">Linux ஃபைல்களைப் பார்க்க முடியவில்லை</translation>
 <translation id="1313405956111467313">தானியங்கு ப்ராக்ஸி உள்ளமைவு</translation>
-<translation id="1351692861129622852"><ph name="FILE_COUNT" /> கோப்புகளைப் பதிவிறக்குகிறது...</translation>
+<translation id="1351692861129622852"><ph name="FILE_COUNT" /> ஃபைல்களைப் பதிவிறக்குகிறது...</translation>
 <translation id="1353686479385938207"><ph name="PROVIDER_NAME" />: <ph name="NETWORK_NAME" /></translation>
 <translation id="1358735829858566124">கோப்பு அல்லது கோப்பகம் உபயோகிக்கக்கூடியதில்லை.</translation>
 <translation id="1363028406613469049">டிராக் எண்</translation>
@@ -71,7 +71,7 @@
 <translation id="162175252992296058">போர்ச்சுகீஸ் - யூஎஸ் சர்வதேசக் கீபோர்டு</translation>
 <translation id="1629521517399325891">நெட்வொர்க் அங்கீகாரத்திற்குப் பயனர் சான்றிதழ் கிடைக்கவில்லை.</translation>
 <translation id="1641780993263690097">சீனம் (பின்யின்)</translation>
-<translation id="1646019627374511909">ஆஃப்லைனில் பயன்படுத்த <ph name="NUMBER_OF_ITEMS" /> கோப்புகளைப் பதிவிறக்குகிறது</translation>
+<translation id="1646019627374511909">ஆஃப்லைனில் பயன்படுத்த <ph name="NUMBER_OF_ITEMS" /> ஃபைல்களைப் பதிவிறக்குகிறது</translation>
 <translation id="164969095109328410">Chrome சாதனம்</translation>
 <translation id="1661867754829461514">PIN இல்லை</translation>
 <translation id="166439687370499867">பகிர்ந்த நெட்வொர்க் உள்ளமைவுகளை மாற்றுவதற்கு அனுமதியில்லை</translation>
@@ -482,7 +482,7 @@
     Google இயக்ககத்தில் உள்ள கோப்புகள் சமீபத்திய மாற்றங்களுடன் இருக்கும், அவற்றை எந்தச் சாதனத்திலிருந்தும் அணுகலாம்.<ph name="MARKUP_3" />
     <ph name="MARKUP_4" />உங்கள் கோப்புகள் பாதுகாப்பாக இருக்கும்.<ph name="MARKUP_5" />
     சாதனத்திற்கு எந்தவிதப் பாதிப்பு ஏற்பட்டாலும், உங்கள் கோப்புகள் Google இயக்ககத்தில் பாதுகாப்பாகச் சேமிக்கப்பட்டிருக்கும்.<ph name="MARKUP_6" />
-    <ph name="MARKUP_7" />ஒரே இடத்தில் கோப்புகளைப் பகிரலாம், உருவாக்கலாம்,<ph name="MARKUP_8" />
+    <ph name="MARKUP_7" />ஒரே இடத்தில் ஃபைல்களைப் பகிரலாம், உருவாக்கலாம்,<ph name="MARKUP_8" />
      மேலும் பிறருடன் இணைந்து திருத்தலாம்.<ph name="MARKUP_9" /></translation>
 <translation id="5275973617553375938">Google இயக்கத்திலிருந்து மீட்கப்பட்ட கோப்புகள்</translation>
 <translation id="5288441970121584418">பர்கர்</translation>
@@ -529,7 +529,7 @@
    <ph name="LINE_BREAKS" />
    காப்பகம் அல்லது விர்ச்சுவல் வட்டிலுள்ள எல்லாக் கோப்புகளையும் மூடி, மீண்டும் முயலவும்.</translation>
 <translation id="5691596662111998220">அடடா, <ph name="FILE_NAME" /> இல்லை.</translation>
-<translation id="5698411045597658393"><ph name="NETWORK_NAME" />, திறக்கும்</translation>
+<translation id="5698411045597658393"><ph name="NETWORK_NAME" />, அனலாக் செய்யும்</translation>
 <translation id="5700087501958648444">ஆடியோ தகவல்</translation>
 <translation id="5724172041621205163">தாய் - பட்டாச்சோட் கீபோர்டு</translation>
 <translation id="5731409020711461763">1 புதிய படம்</translation>
@@ -771,7 +771,7 @@
     குறைவான படங்களைத் தேர்ந்தெடுத்து முயலவும்.</translation>
 <translation id="7827012282502221009"><ph name="NUMBER_OF_TB" /> டெ.பை.</translation>
 <translation id="7831491651892296503">நெட்வொர்க்கை உள்ளமைப்பதில் பிழை</translation>
-<translation id="7839804798877833423">இந்த கோப்புகளைப் பெற்றால், மொபைல் டேட்டாவில் தோராயமாக <ph name="FILE_SIZE" /> ஐப் பயன்படுத்தும்.</translation>
+<translation id="7839804798877833423">இந்த ஃபைல்களைப் பெற்றால், மொபைல் டேட்டாவில் தோராயமாக <ph name="FILE_SIZE" /> ஐப் பயன்படுத்தும்.</translation>
 <translation id="7846076177841592234">தேர்வை ரத்துசெய்</translation>
 <translation id="7847617962681804761">மொபைல் டேட்டாவைப் பயன்படுத்த பின் (PIN) தேவை</translation>
 <translation id="7853966320808728790">ஃபிரஞ்ச் பீபோ</translation>
diff --git a/ui/color/cros/native_color_mixers.cc b/ui/color/cros/native_color_mixers.cc
index a03ba20..9f6b525 100644
--- a/ui/color/cros/native_color_mixers.cc
+++ b/ui/color/cros/native_color_mixers.cc
@@ -4,8 +4,6 @@
 
 #include "ui/color/color_mixers.h"
 
-#include "base/notreached.h"
-
 namespace ui {
 
 void AddNativeCoreColorMixer(ColorProvider* provider,
diff --git a/ui/color/fuchsia/native_color_mixers.cc b/ui/color/fuchsia/native_color_mixers.cc
index e8a68f6..545cb17 100644
--- a/ui/color/fuchsia/native_color_mixers.cc
+++ b/ui/color/fuchsia/native_color_mixers.cc
@@ -4,20 +4,16 @@
 
 #include "ui/color/color_mixers.h"
 
-#include "base/notreached.h"
-
 namespace ui {
 
 void AddNativeCoreColorMixer(ColorProvider* provider,
                              bool dark_window,
                              bool high_contrast) {
-  NOTIMPLEMENTED();
 }
 
 void AddNativeUiColorMixer(ColorProvider* provider,
                            bool dark_window,
                            bool high_contrast) {
-  NOTIMPLEMENTED();
 }
 
 void AddNativePostprocessingMixer(ColorProvider* provider) {}
diff --git a/ui/color/linux/native_color_mixers.cc b/ui/color/linux/native_color_mixers.cc
index e8a68f6..545cb17 100644
--- a/ui/color/linux/native_color_mixers.cc
+++ b/ui/color/linux/native_color_mixers.cc
@@ -4,20 +4,16 @@
 
 #include "ui/color/color_mixers.h"
 
-#include "base/notreached.h"
-
 namespace ui {
 
 void AddNativeCoreColorMixer(ColorProvider* provider,
                              bool dark_window,
                              bool high_contrast) {
-  NOTIMPLEMENTED();
 }
 
 void AddNativeUiColorMixer(ColorProvider* provider,
                            bool dark_window,
                            bool high_contrast) {
-  NOTIMPLEMENTED();
 }
 
 void AddNativePostprocessingMixer(ColorProvider* provider) {}
diff --git a/ui/display/display_layout.cc b/ui/display/display_layout.cc
index 898aea81..ba2fa35 100644
--- a/ui/display/display_layout.cc
+++ b/ui/display/display_layout.cc
@@ -395,12 +395,10 @@
   DCHECK_GE(kMaxValidOffset, abs(offset));
 }
 
-DisplayPlacement::DisplayPlacement(const DisplayPlacement& placement)
-    : display_id(placement.display_id),
-      parent_display_id(placement.parent_display_id),
-      position(placement.position),
-      offset(placement.offset),
-      offset_reference(placement.offset_reference) {}
+DisplayPlacement::DisplayPlacement(const DisplayPlacement&) = default;
+
+DisplayPlacement& DisplayPlacement::operator=(const DisplayPlacement&) =
+    default;
 
 bool DisplayPlacement::operator==(const DisplayPlacement& other) const {
   return display_id == other.display_id &&
diff --git a/ui/display/display_layout.h b/ui/display/display_layout.h
index 3f17378..c63ed4e 100644
--- a/ui/display/display_layout.h
+++ b/ui/display/display_layout.h
@@ -71,7 +71,8 @@
                    int offset,
                    OffsetReference offset_reference);
 
-  DisplayPlacement(const DisplayPlacement& placement);
+  DisplayPlacement(const DisplayPlacement&);
+  DisplayPlacement& operator=(const DisplayPlacement&);
 
   bool operator==(const DisplayPlacement& other) const;
   bool operator!=(const DisplayPlacement& other) const;
diff --git a/ui/display/mac/screen_mac.mm b/ui/display/mac/screen_mac.mm
index 8115029..697c81ab 100644
--- a/ui/display/mac/screen_mac.mm
+++ b/ui/display/mac/screen_mac.mm
@@ -13,12 +13,12 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/mac/sdk_forward_declarations.h"
-#include "base/stl_util.h"
 #include "base/timer/timer.h"
 #include "base/trace_event/trace_event.h"
 #include "ui/display/display.h"
diff --git a/ui/display/util/edid_parser.cc b/ui/display/util/edid_parser.cc
index cf09ef9..291e6d1 100644
--- a/ui/display/util/edid_parser.cc
+++ b/ui/display/util/edid_parser.cc
@@ -11,12 +11,13 @@
 
 #include "base/check.h"
 #include "base/hash/hash.h"
+#include "base/hash/md5.h"
 #include "base/metrics/histogram_functions.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/sys_byteorder.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
-#include "ui/display/types/display_constants.h"
 #include "ui/display/util/display_util.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -24,6 +25,13 @@
 namespace {
 
 constexpr char kParseEdidFailureMetric[] = "Display.ParseEdidFailure";
+constexpr char kParseExternalDisplayEdidOptionalsMetric[] =
+    "Display.External.ParseEdidOptionals";
+constexpr char kBlockZeroSerialNumberTypeMetric[] =
+    "Display.External.BlockZeroSerialNumberType";
+constexpr char kNumOfSerialNumbersProvidedByExternalDisplay[] =
+    "Display.External.NumOfSerialNumbersProvided";
+constexpr uint8_t kMaxSerialNumberCount = 2;
 
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
@@ -37,12 +45,57 @@
   kChromaticityCoordinates = 6,
   kDisplayName = 7,
   kExtensions = 8,
-  kMaxValue = kExtensions,
+  kSerialNumber = 9,
+  kWeekOfManufacture = 10,
+  kPhysicalSize = 11,
+  kMaxValue = kPhysicalSize,
 };
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. This enum is used to track the
+// availability (or lack thereof) of optional fields during EDID parsing.
+enum class ParseEdidOptionals {
+  kAllAvailable = 0,
+  kBlockZeroSerialNumber = 1,
+  kDescriptorBlockSerialNumber = 2,
+  kWeekOfManufacture = 3,
+  kPhysicalSize = 4,
+  kMaxValue = kPhysicalSize,
+};
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. This enum is used to track the
+// serial number types that can be retrieved from an EDID's block zero.
+enum class BlockZeroSerialNumberType {
+  kNormal = 0,
+  kRepeatingPattern = 1,
+  kNoSerialNumber = 2,
+  kMaxValue = kNoSerialNumber,
+};
+
+BlockZeroSerialNumberType GetSerialNumberType(const uint8_t serial_number[],
+                                              size_t size) {
+  int sum = serial_number[0];
+  bool all_equal = true;
+  for (size_t i = 1; i < size; ++i) {
+    sum += serial_number[i];
+    if (serial_number[i - 1] != serial_number[i])
+      all_equal = false;
+  }
+
+  if (sum == 0)
+    return BlockZeroSerialNumberType::kNoSerialNumber;
+
+  if (all_equal)
+    return BlockZeroSerialNumberType::kRepeatingPattern;
+
+  return BlockZeroSerialNumberType::kNormal;
+}
 }  // namespace
 
-EdidParser::EdidParser(const std::vector<uint8_t>& edid_blob)
-    : manufacturer_id_(0),
+EdidParser::EdidParser(const std::vector<uint8_t>& edid_blob, bool is_external)
+    : is_external_display_(is_external),
+      manufacturer_id_(0),
       product_id_(0),
       year_of_manufacture_(display::kInvalidYearOfManufacture),
       gamma_(0.0),
@@ -136,11 +189,63 @@
   }
   product_id_ = (edid[kProductIdOffset] << 8) + edid[kProductIdOffset + 1];
 
+  //   Bytes 12-15: dislay serial number, in little-endian (LSB). This field is
+  //   optional and its absence is marked by having all bytes set to 0x00.
+  //   Values do not represent ASCII characters.
+  constexpr size_t kSerialNumberOffset = 12;
+  constexpr size_t kSerialNumberLength = 4;
+
+  if (edid.size() < kSerialNumberOffset + kSerialNumberLength) {
+    base::UmaHistogramEnumeration(kParseEdidFailureMetric,
+                                  ParseEdidFailure::kSerialNumber);
+    return;  // Any other fields below are beyond this edid offset.
+  }
+
+  const uint8_t serial_number_bytes[kSerialNumberLength] = {
+      edid[kSerialNumberOffset], edid[kSerialNumberOffset + 1],
+      edid[kSerialNumberOffset + 2], edid[kSerialNumberOffset + 3]};
+
+  // Report the type of serial number encountered in block zero of external
+  // displays: empty (==0), repeating pattern (e.g. 01010101 or 0F0F0F0F),
+  // or normal.
+  if (is_external_display_) {
+    base::UmaHistogramEnumeration(
+        kBlockZeroSerialNumberTypeMetric,
+        GetSerialNumberType(serial_number_bytes,
+                            base::size(serial_number_bytes)));
+  }
+
+  const uint32_t serial_number =
+      serial_number_bytes[0] + (serial_number_bytes[1] << 8) +
+      (serial_number_bytes[2] << 16) + (serial_number_bytes[3] << 24);
+  if (serial_number) {
+    block_zero_serial_number_hash_ =
+        base::MD5String(base::NumberToString(serial_number));
+  }
+
   // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision
   // 2, Sep 2006, Sec 3.4.4 "Week and Year of Manufacture or Model Year: 2
   // Bytes".
+  constexpr size_t kWeekOfManufactureOffset = 16;
+  constexpr uint32_t kValidWeekValueUpperBound = 0x36;
+  constexpr uint32_t kModelYearMarker = 0xFF;
+
+  if (edid.size() < kWeekOfManufactureOffset + 1) {
+    base::UmaHistogramEnumeration(kParseEdidFailureMetric,
+                                  ParseEdidFailure::kWeekOfManufacture);
+    return;  // Any other fields below are beyond this edid offset.
+  }
+  {
+    const uint8_t byte_data = edid[kWeekOfManufactureOffset];
+    // Store the value if it's within the range of 1-54 or equals to 0xFF.
+    if ((byte_data > 0x00 && byte_data <= kValidWeekValueUpperBound) ||
+        byte_data == kModelYearMarker) {
+      week_of_manufacture_ = byte_data;
+    }
+  }
+
   constexpr size_t kYearOfManufactureOffset = 17;
-  constexpr uint32_t kValidValueLowerBound = 0x10;
+  constexpr uint32_t kValidYearValueLowerBound = 0x10;
   constexpr int32_t kYearOffset = 1990;
 
   if (edid.size() < kYearOfManufactureOffset + 1) {
@@ -148,9 +253,11 @@
                                   ParseEdidFailure::kYearOfManufacture);
     return;  // Any other fields below are beyond this edid offset.
   }
-  const uint8_t byte_data = edid[kYearOfManufactureOffset];
-  if (byte_data >= kValidValueLowerBound)
-    year_of_manufacture_ = byte_data + kYearOffset;
+  {
+    const uint8_t byte_data = edid[kYearOfManufactureOffset];
+    if (byte_data >= kValidYearValueLowerBound)
+      year_of_manufacture_ = byte_data + kYearOffset;
+  }
 
   // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision
   // 1, Feb 2000, Sec 3.6 "Basic Display Parameters and Features: 5 bytes"
@@ -178,6 +285,19 @@
         kColorBitDepthOffset)];
   }
 
+  constexpr size_t kEDIDMaxHorizontalImageSizeOffset = 21;
+  constexpr size_t kEDIDMaxVerticalImageSizeOffset = 22;
+
+  if (edid.size() < kEDIDMaxVerticalImageSizeOffset + 1) {
+    base::UmaHistogramEnumeration(kParseEdidFailureMetric,
+                                  ParseEdidFailure::kPhysicalSize);
+    return;  // Any other fields below are beyond this edid offset.
+  }
+  const gfx::Size max_image_size(edid[kEDIDMaxHorizontalImageSizeOffset],
+                                 edid[kEDIDMaxVerticalImageSizeOffset]);
+  if (!max_image_size.IsEmpty())
+    max_image_size_ = max_image_size;
+
   // Constants are taken from "VESA Enhanced EDID Standard" Release A, Revision
   // 2, Sep 2006, Sec. 3.6.3 "Display Transfer Characteristics (GAMMA ): 1 Byte"
   constexpr size_t kGammaOffset = 23;
@@ -277,6 +397,7 @@
   constexpr size_t kDescriptorLength = 18;
   // The specifier types.
   constexpr uint8_t kMonitorNameDescriptor = 0xfc;
+  constexpr uint8_t kMonitorSerialNumberDescriptor = 0xff;
 
   display_name_.clear();
   for (size_t i = 0; i < kNumDescriptors; ++i) {
@@ -314,7 +435,7 @@
     // If the descriptor contains the display name, it has the following
     // structure:
     //   bytes 0-2, 4: \0
-    //   byte 3: descriptor type, defined above.
+    //   byte 3: 0xfc
     //   bytes 5-17: text data, ending with \r, padding with spaces
     // we should check bytes 0-2 and 4, since it may have other values in
     // case that the descriptor contains other type of data.
@@ -325,6 +446,26 @@
       base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &display_name_);
       continue;
     }
+
+    // If the descriptor contains the display's product serial number, it has
+    // the following structure:
+    //   bytes 0-2, 4: \0
+    //   byte 3: 0xff
+    //   bytes 5-17: text data, ending with \r, padding with spaces
+    // we should check bytes 0-2 and 4, since it may have other values in
+    // case that the descriptor contains other type of data.
+    if (edid[offset] == 0 && edid[offset + 1] == 0 && edid[offset + 2] == 0 &&
+        edid[offset + 3] == kMonitorSerialNumberDescriptor &&
+        edid[offset + 4] == 0) {
+      std::string serial_number(
+          reinterpret_cast<const char*>(&edid[offset + 5]),
+          kDescriptorLength - 5);
+      base::TrimWhitespaceASCII(serial_number, base::TRIM_TRAILING,
+                                &serial_number);
+      if (!serial_number.empty())
+        descriptor_block_serial_number_hash_ = base::MD5String(serial_number);
+      continue;
+    }
   }
 
   // Verify if the |display_name_| consists of printable characters only.
@@ -492,6 +633,46 @@
   }
   base::UmaHistogramEnumeration(kParseEdidFailureMetric,
                                 ParseEdidFailure::kNoError);
+  ReportEdidOptionalsForExternalDisplay();
+}
+
+void EdidParser::ReportEdidOptionalsForExternalDisplay() const {
+  if (!is_external_display_)
+    return;
+
+  bool all_optionals_available = true;
+
+  if (!week_of_manufacture_.has_value()) {
+    all_optionals_available = false;
+    base::UmaHistogramEnumeration(kParseExternalDisplayEdidOptionalsMetric,
+                                  ParseEdidOptionals::kWeekOfManufacture);
+  }
+  if (!max_image_size_.has_value()) {
+    all_optionals_available = false;
+    base::UmaHistogramEnumeration(kParseExternalDisplayEdidOptionalsMetric,
+                                  ParseEdidOptionals::kPhysicalSize);
+  }
+  uint8_t serial_number_count = kMaxSerialNumberCount;
+  if (!block_zero_serial_number_hash_.has_value()) {
+    all_optionals_available = false;
+    serial_number_count--;
+    base::UmaHistogramEnumeration(kParseExternalDisplayEdidOptionalsMetric,
+                                  ParseEdidOptionals::kBlockZeroSerialNumber);
+  }
+  if (!descriptor_block_serial_number_hash_.has_value()) {
+    all_optionals_available = false;
+    serial_number_count--;
+    base::UmaHistogramEnumeration(
+        kParseExternalDisplayEdidOptionalsMetric,
+        ParseEdidOptionals::kDescriptorBlockSerialNumber);
+  }
+  base::UmaHistogramExactLinear(kNumOfSerialNumbersProvidedByExternalDisplay,
+                                serial_number_count, kMaxSerialNumberCount);
+
+  if (all_optionals_available) {
+    base::UmaHistogramEnumeration(kParseExternalDisplayEdidOptionalsMetric,
+                                  ParseEdidOptionals::kAllAvailable);
+  }
 }
 
 }  // namespace display
diff --git a/ui/display/util/edid_parser.h b/ui/display/util/edid_parser.h
index 8478d12..c48c2b30 100644
--- a/ui/display/util/edid_parser.h
+++ b/ui/display/util/edid_parser.h
@@ -15,6 +15,7 @@
 #include "base/macros.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
+#include "ui/display/types/display_constants.h"
 #include "ui/display/util/display_util_export.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/size.h"
@@ -27,13 +28,26 @@
 // a few utility postprocessings.
 class DISPLAY_UTIL_EXPORT EdidParser {
  public:
-  explicit EdidParser(const std::vector<uint8_t>& edid_blob);
+  explicit EdidParser(const std::vector<uint8_t>& edid_blob,
+                      bool is_external = false);
   ~EdidParser();
 
   uint16_t manufacturer_id() const { return manufacturer_id_; }
   uint16_t product_id() const { return product_id_; }
+  std::string block_zero_serial_number_hash() const {
+    return block_zero_serial_number_hash_.value_or("");
+  }
+  std::string descriptor_block_serial_number_hash() const {
+    return descriptor_block_serial_number_hash_.value_or("");
+  }
+  gfx::Size max_image_size() const {
+    return max_image_size_.value_or(gfx::Size());
+  }
   const std::string& display_name() const { return display_name_; }
   const gfx::Size& active_pixel_size() const { return active_pixel_size_; }
+  int32_t week_of_manufacture() const {
+    return week_of_manufacture_.value_or(0);
+  }
   int32_t year_of_manufacture() const { return year_of_manufacture_; }
   bool has_overscan_flag() const { return overscan_flag_.has_value(); }
   bool overscan_flag() const { return overscan_flag_.value(); }
@@ -74,11 +88,22 @@
   // Parses |edid_blob|, filling up as many as possible fields below.
   void ParseEdid(const std::vector<uint8_t>& edid);
 
+  // We collect optional fields UMAs for external external displays only.
+  void ReportEdidOptionalsForExternalDisplay() const;
+
+  // Whether or not this EDID belongs to an external display.
+  bool is_external_display_;
+
   uint16_t manufacturer_id_;
   uint16_t product_id_;
+  absl::optional<std::string> block_zero_serial_number_hash_;
+  absl::optional<std::string> descriptor_block_serial_number_hash_;
+  absl::optional<gfx::Size> max_image_size_;
   std::string display_name_;
   // Active pixel size from the first detailed timing descriptor in the EDID.
   gfx::Size active_pixel_size_;
+  // When |week_of_manufacture_| == 0xFF, |year_of_manufacture_| is model year.
+  absl::optional<int32_t> week_of_manufacture_;
   int32_t year_of_manufacture_;
   absl::optional<bool> overscan_flag_;
   double gamma_;
@@ -94,4 +119,4 @@
 
 }  // namespace display
 
-#endif // UI_DISPLAY_UTIL_EDID_PARSER_H_
+#endif  // UI_DISPLAY_UTIL_EDID_PARSER_H_
diff --git a/ui/display/util/edid_parser_unittest.cc b/ui/display/util/edid_parser_unittest.cc
index 26f61e58..c9f12bb38 100644
--- a/ui/display/util/edid_parser_unittest.cc
+++ b/ui/display/util/edid_parser_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/containers/flat_set.h"
 #include "base/cxx17_backports.h"
+#include "base/hash/md5.h"
 #include "base/numerics/ranges.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
@@ -49,6 +50,75 @@
     "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71";
 constexpr size_t kNormalDisplayLength = base::size(kNormalDisplay);
 
+// Max image display is an optional field and is omitted in this display by
+// setting bytes 21-22 to 0x00.
+constexpr unsigned char kNoMaxImageSizeDisplay[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01"
+    "\x02\x16\x01\x04\xb5\x00\x00\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
+    "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+    "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
+    "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
+    "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
+    "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff"
+    "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71";
+constexpr size_t kNoMaxImageSizeDisplayLength =
+    base::size(kNoMaxImageSizeDisplay);
+
+// Serial number is in bytes 12-15 of Block 0. Serial number descriptor
+// (tag: 0xff) is omitted and replaced by a dummy descriptor (tag: 0x10).
+constexpr unsigned char kBlockZeroSerialNumberOnlyDisplay[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01"
+    "\x02\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
+    "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+    "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
+    "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
+    "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
+    "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\x10"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71";
+constexpr size_t kBlockZeroSerialNumberOnlyDisplayLength =
+    base::size(kBlockZeroSerialNumberOnlyDisplay);
+
+// Serial number is unavilable. Omitted from bytes 12-15 of block zero and SN
+// descriptor (tag: 0xff).
+constexpr unsigned char kNoSerialNumberDisplay[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x00\x00\x00\x00"
+    "\x02\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
+    "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+    "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
+    "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
+    "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
+    "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\x10"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x71";
+constexpr size_t kNoSerialNumberDisplayLength =
+    base::size(kNoSerialNumberDisplay);
+
+// Week of manufacture is optional and is omitted in this display
+// (0x00 at byte 16).
+constexpr unsigned char kNoWeekOfManufactureDisplay[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01"
+    "\x00\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
+    "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+    "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
+    "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
+    "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
+    "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff"
+    "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71";
+constexpr size_t kNoWeekOfManufactureDisplayLength =
+    base::size(kNoWeekOfManufactureDisplay);
+
+// Week of manufacture can be used to signal that year of manufacture is the
+// model year by setting byte 16 to 0xff.
+constexpr unsigned char kModelYearDisplay[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01"
+    "\xff\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
+    "\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+    "\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
+    "\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
+    "\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
+    "\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff"
+    "\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71";
+constexpr size_t kModelYearDisplayLength = base::size(kModelYearDisplay);
+
 constexpr unsigned char kInternalDisplay[] =
     "\x00\xff\xff\xff\xff\xff\xff\x00\x4c\xa3\x42\x31\x00\x00\x00\x00"
     "\x00\x15\x01\x03\x80\x1a\x10\x78\x0a\xd3\xe5\x95\x5c\x60\x90\x27"
@@ -185,6 +255,16 @@
     "\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd";
 constexpr size_t kHDRMetadataLength = base::size(kHDRMetadata);
 
+const std::string kNoSerialNumber = "";
+const gfx::Size kNoMaxImageSize = gfx::Size(0, 0);
+constexpr uint8_t kNoWeekOfManufactureTag = 0x00;
+constexpr uint8_t kModelYearTag = 0xff;
+// 16843009 == 0x01010101
+const std::string kGenericBlockZeroHashedSerialNumber =
+    base::MD5String(std::string("16843009"));
+const std::string kNormalDisplayHashedDescriptorBlockSerialNumber =
+    base::MD5String(std::string("CN4202137Q"));
+
 // Primaries coordinates ({RX, RY, GX, GY, BX, BY, WX, WY}) calculated by hand
 // and rounded to 4 decimal places.
 constexpr SkColorSpacePrimaries kNormalDisplayPrimaries = {
@@ -240,8 +320,12 @@
 struct TestParams {
   uint16_t manufacturer_id;
   uint16_t product_id;
+  std::string block_zero_serial_number_hash;
+  std::string descriptor_block_serial_number_hash;
+  gfx::Size max_image_size;
   std::string display_name;
   gfx::Size active_pixel_size;
+  int32_t week_of_manufacture;
   int32_t year_of_manufacture;
   bool overscan_flag;
   double gamma;
@@ -263,8 +347,12 @@
 } kTestCases[] = {
     {0x22f0u,
      0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNormalDisplayHashedDescriptorBlockSerialNumber,
+     gfx::Size(64, 40),
      "HP Z 30w",  // non-ascii char in display name.
      gfx::Size(2560, 1600),
+     2,
      2012,
      false,
      2.2,
@@ -281,8 +369,12 @@
      kBadDisplayNameLength},
     {0x22f0u,
      0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNormalDisplayHashedDescriptorBlockSerialNumber,
+     gfx::Size(64, 40),
      "HP ZR30w",
      gfx::Size(2560, 1600),
+     2,
      2012,
      false,
      2.2,
@@ -297,10 +389,124 @@
      absl::nullopt,
      kNormalDisplay,
      kNormalDisplayLength},
+    {0x22f0u,
+     0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNormalDisplayHashedDescriptorBlockSerialNumber,
+     kNoMaxImageSize,
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     2,
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     absl::nullopt,
+     kNoMaxImageSizeDisplay,
+     kNoMaxImageSizeDisplayLength},
+    {0x22f0u,
+     0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(64, 40),
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     2,
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     absl::nullopt,
+     kBlockZeroSerialNumberOnlyDisplay,
+     kBlockZeroSerialNumberOnlyDisplayLength},
+    {0x22f0u,
+     0x6c28u,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(64, 40),
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     2,
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     absl::nullopt,
+     kNoSerialNumberDisplay,
+     kNoSerialNumberDisplayLength},
+    {0x22f0u,
+     0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNormalDisplayHashedDescriptorBlockSerialNumber,
+     gfx::Size(64, 40),
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     kNoWeekOfManufactureTag,
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     absl::nullopt,
+     kNoWeekOfManufactureDisplay,
+     kNoWeekOfManufactureDisplayLength},
+    {0x22f0u,
+     0x6c28u,
+     kGenericBlockZeroHashedSerialNumber,
+     kNormalDisplayHashedDescriptorBlockSerialNumber,
+     gfx::Size(64, 40),
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     kModelYearTag,
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     absl::nullopt,
+     kModelYearDisplay,
+     kModelYearDisplayLength},
     {0x4ca3u,
      0x4231u,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(26, 16),
      "",
      gfx::Size(1280, 800),
+     kNoWeekOfManufactureTag,
      2011,
      false,
      2.2,
@@ -317,8 +523,12 @@
      kInternalDisplayLength},
     {0x4c2du,
      0xfe08u,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(16, 9),
      "SAMSUNG",
      gfx::Size(1920, 1080),
+     41,
      2011,
      true,
      2.2,
@@ -335,8 +545,12 @@
      kOverscanDisplayLength},
     {0x10ACu,
      0x6440u,
+     base::MD5String("842018892"),  // == LSB of 0x4c, 0x30, 0x30, 0x32
+     base::MD5String("PH5NY13N200L"),
+     gfx::Size(64, 40),
      "DELL U3011",
      gfx::Size(1920, 1200),
+     12,
      2011,
      false,
      2.2,
@@ -353,8 +567,12 @@
      kMisdetectedDisplayLength},
     {0x22f0u,
      0x7626u,
+     kGenericBlockZeroHashedSerialNumber,
+     base::MD5String("CNK80204HM"),
+     gfx::Size(52, 33),
      "HP LP2465",
      gfx::Size(1920, 1200),
+     2,
      2008,
      false,
      2.2,
@@ -371,8 +589,12 @@
      kLP2565ALength},
     {0x22f0u,
      0x7526u,
+     kGenericBlockZeroHashedSerialNumber,
+     base::MD5String("CNK80204HM"),
+     gfx::Size(52, 33),
      "HP LP2465",
      gfx::Size(1920, 1200),
+     2,
      2008,
      false,
      2.2,
@@ -389,8 +611,12 @@
      kLP2565BLength},
     {0x22f0u,
      0x7532u,
+     kGenericBlockZeroHashedSerialNumber,
+     base::MD5String("CNC7270MW0"),
+     gfx::Size(70, 39),
      "HP Z32x",
      gfx::Size(3840, 2160),
+     27,
      2017,
      false,
      2.2,
@@ -407,8 +633,12 @@
      kHPz32xLength},
     {0x30E4u,
      0x2E04u,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(27, 18),
      "",
      gfx::Size(2560, 1700),
+     kNoWeekOfManufactureTag,
      2014,
      false,
      2.5,
@@ -425,8 +655,12 @@
      kSamusLength},
     {0x4D10u,
      0x8A14u,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(26, 17),
      "LQ123P1JX32",
      gfx::Size(2400, 1600),
+     22,
      2017,
      false,
      2.2,
@@ -443,8 +677,12 @@
      kEveLength},
     {19501u,
      62989u,
+     base::MD5String("16780800"),  // == LSB of 0x00, 0x0e, 0x00 0x01
+     kNoSerialNumber,
+     gfx::Size(95, 54),
      "SAMSUNG",
      gfx::Size(3840, 2160),
+     1,
      2017,
      true,
      2.2,
@@ -466,8 +704,12 @@
     // Empty Edid, which is tantamount to error.
     {0,
      0,
+     kNoSerialNumber,
+     kNoSerialNumber,
+     gfx::Size(0, 0),
      "",
      gfx::Size(0, 0),
+     kNoWeekOfManufactureTag,
      display::kInvalidYearOfManufacture,
      false,
      0.0,
@@ -500,8 +742,14 @@
 TEST_P(EDIDParserTest, ParseEdids) {
   EXPECT_EQ(parser_.manufacturer_id(), GetParam().manufacturer_id);
   EXPECT_EQ(parser_.product_id(), GetParam().product_id);
+  EXPECT_EQ(parser_.block_zero_serial_number_hash(),
+            GetParam().block_zero_serial_number_hash);
+  EXPECT_EQ(parser_.descriptor_block_serial_number_hash(),
+            GetParam().descriptor_block_serial_number_hash);
+  EXPECT_EQ(parser_.max_image_size(), GetParam().max_image_size);
   EXPECT_EQ(parser_.display_name(), GetParam().display_name);
   EXPECT_EQ(parser_.active_pixel_size(), GetParam().active_pixel_size);
+  EXPECT_EQ(parser_.week_of_manufacture(), GetParam().week_of_manufacture);
   EXPECT_EQ(parser_.year_of_manufacture(), GetParam().year_of_manufacture);
   EXPECT_EQ(parser_.has_overscan_flag(), GetParam().overscan_flag);
   if (parser_.has_overscan_flag())
diff --git a/ui/events/gesture_detection/gesture_event_data.cc b/ui/events/gesture_detection/gesture_event_data.cc
index d32d126..da195f3 100644
--- a/ui/events/gesture_detection/gesture_event_data.cc
+++ b/ui/events/gesture_detection/gesture_event_data.cc
@@ -79,6 +79,9 @@
 
 GestureEventData::GestureEventData(const GestureEventData& other) = default;
 
+GestureEventData& GestureEventData::operator=(const GestureEventData& other) =
+    default;
+
 GestureEventData::GestureEventData()
     : motion_event_id(0),
       primary_tool_type(MotionEvent::ToolType::UNKNOWN),
diff --git a/ui/events/gesture_detection/gesture_event_data.h b/ui/events/gesture_detection/gesture_event_data.h
index f805e58..7bf4581 100644
--- a/ui/events/gesture_detection/gesture_event_data.h
+++ b/ui/events/gesture_detection/gesture_event_data.h
@@ -32,6 +32,7 @@
                    uint32_t unique_touch_event_id);
   GestureEventData(EventType type, const GestureEventData&);
   GestureEventData(const GestureEventData& other);
+  GestureEventData& operator=(const GestureEventData& other);
 
   EventType type() const { return details.type(); }
 
diff --git a/ui/events/gesture_detection/motion_event_generic.cc b/ui/events/gesture_detection/motion_event_generic.cc
index fbfd6b93..d879f35 100644
--- a/ui/events/gesture_detection/motion_event_generic.cc
+++ b/ui/events/gesture_detection/motion_event_generic.cc
@@ -55,6 +55,9 @@
 
 PointerProperties::PointerProperties(const PointerProperties& other) = default;
 
+PointerProperties& PointerProperties::operator=(
+    const PointerProperties& other) = default;
+
 void PointerProperties::SetAxesAndOrientation(float radius_x,
                                               float radius_y,
                                               float rotation_angle_degree) {
diff --git a/ui/events/gesture_detection/motion_event_generic.h b/ui/events/gesture_detection/motion_event_generic.h
index e9ae85c..13a0d7f 100644
--- a/ui/events/gesture_detection/motion_event_generic.h
+++ b/ui/events/gesture_detection/motion_event_generic.h
@@ -19,6 +19,7 @@
   PointerProperties(float x, float y, float touch_major);
   PointerProperties(const MotionEvent& event, size_t pointer_index);
   PointerProperties(const PointerProperties& other);
+  PointerProperties& operator=(const PointerProperties& other);
 
   // Sets |touch_major|, |touch_minor|, and |orientation| from the given radius
   // and rotation angle (in degrees).
diff --git a/ui/events/keycodes/keyboard_code_conversion_mac.mm b/ui/events/keycodes/keyboard_code_conversion_mac.mm
index 326313e..9988882 100644
--- a/ui/events/keycodes/keyboard_code_conversion_mac.mm
+++ b/ui/events/keycodes/keyboard_code_conversion_mac.mm
@@ -9,10 +9,10 @@
 #import <Carbon/Carbon.h>
 
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
 #include "base/mac/mac_logging.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "base/memory/scoped_policy.h"
-#include "base/stl_util.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 
 namespace ui {
diff --git a/ui/events/pointer_details.cc b/ui/events/pointer_details.cc
index 3d51033..b6dc54df 100644
--- a/ui/events/pointer_details.cc
+++ b/ui/events/pointer_details.cc
@@ -44,7 +44,9 @@
   }
 }
 
-PointerDetails::PointerDetails(const PointerDetails& other) = default;
+PointerDetails::PointerDetails(const PointerDetails&) = default;
+
+PointerDetails& PointerDetails::operator=(const PointerDetails&) = default;
 
 bool PointerDetails::operator==(const PointerDetails& other) const {
   return pointer_type == other.pointer_type && radius_x == other.radius_x &&
diff --git a/ui/events/pointer_details.h b/ui/events/pointer_details.h
index 131dfaa..e2f5f29 100644
--- a/ui/events/pointer_details.h
+++ b/ui/events/pointer_details.h
@@ -41,6 +41,7 @@
                  float tilt_y = 0.0f,
                  float tangential_pressure = 0.0f);
   PointerDetails(const PointerDetails& other);
+  PointerDetails& operator=(const PointerDetails& other);
 
   bool operator==(const PointerDetails& other) const;
 
diff --git a/ui/file_manager/base/gn/js_test_gen_html.gni b/ui/file_manager/base/gn/js_test_gen_html.gni
index c601384..01b3612 100644
--- a/ui/file_manager/base/gn/js_test_gen_html.gni
+++ b/ui/file_manager/base/gn/js_test_gen_html.gni
@@ -4,12 +4,14 @@
 
 import("//third_party/closure_compiler/js_unit_tests.gni")
 
-# Describes a list of js_unittest targets that will each have an HTML file
-# generated listing all its (flattened) js dependencies, for loading as a test.
+# Describes a list of js_unittest targets that will each have a generated HTML
+# file that imports the test JS module and adds the test* functions to the
+# window to be consumed by the test harness.
 #
-# A companion group target with a "_type_check_auto" suffix is also generated with
-# this template. This depends on a list of js_type_check(..) targets -- one for
-# each test -- that will type check the test js file and its dependency subtree.
+# A companion group target with a "_type_check_auto" suffix is also generated
+# with this template. This depends on a list of js_type_check(..) targets -- one
+# for # each test -- that will type check the test js file and its dependency
+# subtree.
 #
 # Must be declared after the js_library targets it depends on.
 #
@@ -19,21 +21,9 @@
 #   deps:
 #     List of js_unittest targets to depend on
 #
-#   mocks:
-#     An optional list of .js files to load before any other scripts
-#
-#   html_import:
-#     Boolean indicating that it's a Polymer element being tested, thus it
-#     generates HTMLImport instead of <script>. Only the main element is
-#     imported.
-#
-#   js_module:
-#     Boolean indicating that it's a JS module so the HTML file will only
-#     contain <script type="module" src="..._unittest.m.js"> and traditional
-#     <script>s for mocks.
-#
 #   is_polymer3:
-#     Boolean indicating that it's a test for a Polymer 3 element.
+#     Boolean indicating that it's a test for a Polymer 3 element, the only
+#     difference is the js_type_check() rule also has the is_polymer3=true.
 #
 #
 # Non-Polymer example:
@@ -43,7 +33,6 @@
 #       ":bar_unittest",
 #       ":baz_unittest",
 #     ]
-#     mocks = [ "my_mocks.js" ]
 #   }
 #
 #   group("closure_compile") {
@@ -58,30 +47,19 @@
 #
 # Polymer example:
 #   js_test_gen_html("polymer_tests") {
+#     is_polymer3 = true
 #     deps = [
 #       ":element1_unittest",
 #     ]
-#     html_import = true
 #   }
 #
-#   For "element1_unittest" instead of <script src="element1.js"> it will
-#   generate <link rel="import" href="element1.html">. Note the different
-#   extensions (.html vs .js). Ffor all other deps it will still use
-#   <script src="chrome://file_manager_test/$DEP_PATH">.
-#
 template("js_test_gen_html") {
   html_gen_target_name = target_name + "_gen_html"
   action_foreach(html_gen_target_name) {
     script_path = "//ui/file_manager/base/gn/"
     script = "$script_path/js_test_gen_html.py"
-    forward_variables_from(invoker,
-                           [
-                             "deps",
-                             "mocks",
-                             "html_import",
-                             "js_module",
-                             "is_polymer3",
-                           ])
+    forward_variables_from(invoker, [ "deps" ])
+
     testonly = true
     sources = []
     foreach(dep, deps) {
@@ -95,51 +73,29 @@
       rebase_path("//"),
     ]
     args += [ "--input" ] + [ "{{source}}" ]
-
-    args += [
-      "--target_name",
-      "{{source_name_part}}",
-    ]
-
-    if (defined(html_import) && html_import) {
-      args += [ "--html_import" ]
-    }
-
-    if (defined(js_module) && js_module) {
-      args += [ "--js_module" ]
-    }
-
-    # Polymer3 implies --js_module for the generated HTML.
-    if (defined(is_polymer3) && is_polymer3) {
-      args += [ "--js_module" ]
-    }
-
-    if (defined(mocks)) {
-      args += [ "--mocks" ] + rebase_path(mocks, root_build_dir)
-      data = mocks
-    }
   }
+
   type_check_deps = []
   foreach(dep, invoker.deps) {
     type_check_target_name = target_name + "_" + dep + "_type_check_auto"
     type_check_deps += [ ":$type_check_target_name" ]
     js_type_check(type_check_target_name) {
-      if (defined(invoker.js_module) && invoker.js_module) {
-      } else if (defined(invoker.is_polymer3) && invoker.is_polymer3) {
-        is_polymer3 = true
-      } else {
-        uses_legacy_modules = true
-      }
       testonly = true
-      forward_variables_from(invoker, [ "closure_flags" ])
+      forward_variables_from(invoker,
+                             [
+                               "closure_flags",
+                               "is_polymer3",
+                             ])
       deps = [ dep ]
     }
   }
+
   type_check_group_name = target_name + "_type_check_auto"
   group(type_check_group_name) {
     testonly = true
     deps = type_check_deps
   }
+
   group(target_name) {
     data = get_target_outputs(":$html_gen_target_name")
     testonly = true
diff --git a/ui/file_manager/base/gn/js_test_gen_html.py b/ui/file_manager/base/gn/js_test_gen_html.py
index 4a8b0894..761a57be 100644
--- a/ui/file_manager/base/gn/js_test_gen_html.py
+++ b/ui/file_manager/base/gn/js_test_gen_html.py
@@ -7,182 +7,42 @@
 import sys
 from argparse import ArgumentParser
 
-_HTML_FILE = r"""<!DOCTYPE html>
-<html>
-<script>
-// Basic include checker.
-window.addEventListener('error', function(e) {
-  if ((e.target instanceof HTMLScriptElement)) {
-    console.log('ERROR loading <script> element (does it exist?):\n\t' +
-                e.srcElement.src + '\n\tIncluded from: ' +
-                e.srcElement.baseURI);
-  }
-}, true /* useCapture */);
-</script>
-<body>
-"""
-
-_CLASSIC_SCRIPT = r'<script src="%s"></script>'
+_HTML_FILE_START = r'''<!DOCTYPE html>'''
 _JS_MODULE = r'<script type="module" src="%s"></script>'
 _JS_MODULE_REGISTER_TESTS = r'''
 <script>
-// Push all entities to global namespace to be visible to the test harness:
-// ui/webui/resources/js/webui_resource_test.js
-import('%s').then(TestModule => {
-  for (const name in TestModule) {
-    window[name] = TestModule[name];
-  }
-});
+  // Push all entities to global namespace to be visible to the test harness:
+  // ui/webui/resources/js/webui_resource_test.js
+  const js_module_url = '%s';
+  import(js_module_url).then(TestModule => {
+    for (const name in TestModule) {
+      window[name] = TestModule[name];
+    }
+  });
 </script>
 '''
-_IMPORT = r'<link rel="import" href="%s">'
-_HTML_IMPORT_POLYFIL =  _CLASSIC_SCRIPT  % (
-    'chrome://resources/polymer/v1_0/html-imports/html-imports.min.js')
-
-_HTML_FOOTER = r"""
-</body>
-</html>
-"""
-
-_ELEMENTS_BUNDLE_IMPORTED = False
-_ELEMENTS_BUNDLE = _IMPORT % (
-  'chrome://file_manager_test/ui/file_manager/file_manager/foreground/elements'
-  '/elements_bundle.html')
 
 
-
-def _process_deps(unique_deps, dep_type, target_name):
-  """Processes all deps strings, yielding each HTML tag to include the dep.
-
-  Args:
-    unique_deps: Iterator of strings, for all deps to be processed.
-    dep_type: String: 'classic_script' | 'js_module' |
-      'js_module_register_tests' | 'html_import'.
-    target_name: Current test target name, used to infer the main Polymer
-      element for HTMLImport. element_unitest => element.js/element.html.
-
-  Returns:
-    Iterator of strings, each string is a HTML tag <script> or <link>.
-  """
-  for dep in unique_deps:
-    # Scripts from cr_elements are included via HTML imports.
-    if '/cr_elements/' in dep:
-      continue
-
-    # Special case for jstemplate which has multiple files but we server all of
-    # them combined from chrome://resources/js/jstemplate_compiled.js
-    if '/jstemplate/' in dep:
-      if '/jstemplate.js' in dep:
-        yield ('<script src='
-               '"chrome://resources/js/jstemplate_compiled.js"></script>')
-      # just ignore other files files from /jstemplate/
-      continue
-
-    # Ignoring Polymer files, because they're loaded by the HTML imports from
-    # other files.
-    if 'third_party/polymer/' in dep:
-      continue
-
-    # These files are loaded via HTML import. Don't load them again here: that
-    # would cause the tests to fail.
-    if 'parse_html_subset.js' in dep:
-      continue
-    if 'i18n_behavior.js' in dep:
-      continue
-
-    # Any JS from /elements/ will be HTML imported via the elements_bundle.html.
-    if 'file_manager/foreground/elements/' in dep and not'_unittest' in dep:
-      global _ELEMENTS_BUNDLE_IMPORTED
-      if not _ELEMENTS_BUNDLE_IMPORTED:
-        yield _ELEMENTS_BUNDLE
-        _ELEMENTS_BUNDLE_IMPORTED = True
-      continue
-
-    # Map file_manager files:
-    dep = dep.replace('ui/file_manager/',
-                      'chrome://file_manager_test/ui/file_manager/', 1)
-
-    # Extern files from closure in //third_party/
-    closure = 'third_party/closure_compiler/externs/'
-    dep = dep.replace(closure, 'chrome://file_manager_test/%s' % closure, 1)
-
-    # WebUI files (both Polymer and non-Polymer):
-    dep = dep.replace('ui/webui/resources/', 'chrome://resources/', 1)
-
-    # Remove the relative because all replaces above map to an absolute path in
-    # chrome://* and this URL scheme doesn't allow "..".
-    dep = dep.replace('../', '')
-
-    # Find the file being tested eg: element_unittest => element.js
-    implementation_file = target_name.replace('_unittest', '.js')
-
-    # If it should use HTMLImport the main element JS file shouldn't be
-    # included, instead we <link rel=import> its HTML file which in turn
-    # includes the JS file. Note that all other JS deps are included as
-    # <script>.
-    if dep_type == 'html_import'and dep.endswith(implementation_file):
-      dep = dep.replace('.js', '.html')
-      yield _IMPORT % (dep)
-    elif dep_type == 'js_module':
-      yield _JS_MODULE % (dep)
-    elif dep_type == 'js_module_register_tests':
-      yield _JS_MODULE_REGISTER_TESTS % (dep)
-    else:
-      # Normal dep, just return the <script src="dep.js">
-      yield _CLASSIC_SCRIPT % (dep)
-
-
-def _process_js_module(input_file, output_filename, mocks, target_name):
+def _process_js_module(input_file, output_filename):
   """Generates the HTML for a unittest based on JS Modules.
 
   Args:
     input_file: The path for the unittest JS module.
     output_filename: The path/filename for HTML to be generated.
-    mocks: List of strings, JS file names that will be included in the bottom to
-      overwrite JS implementation from deps.
-    target_name: Current test target name, used to infer the main Polymer
-      element for HTMLImport. element_unitest => element.js/element.html.
   """
 
-  with open(output_filename, 'w') as out:
-    out.write(_HTML_FILE)
-    for dep in _process_deps(mocks, 'js_module', target_name):
-      out.write(dep + '\n')
-    for dep in _process_deps([input_file], 'js_module', target_name):
-      out.write(dep + '\n')
-    for dep in _process_deps([input_file], 'js_module_register_tests',
-                             target_name):
-      out.write(dep + '\n')
-
-
-def _process(deps, output_filename, mocks, html_import, target_name):
-  """Generates the HTML file with all JS dependencies for JS unittest.
-
-  Args:
-    deps: List of strings for each dependency path.
-    output_filename: String, HTML file name that will be generated.
-    mocks: List of strings, JS file names that will be included in the bottom to
-      overwrite JS implementation from deps.
-    html_import: Boolean, indicate if HTMLImport should be used for testing
-      Polymer elements.
-    target_name: Current test target name, used to infer the main Polymer
-      element for HTMLImport. element_unitest => element.js/element.html.
-  """
+  # Map //ui/file_manager files to test URL:
+  js_module_url = input_file.replace(
+      'ui/file_manager/', 'chrome://file_manager_test/ui/file_manager/', 1)
 
   with open(output_filename, 'w') as out:
-    out.write(_HTML_FILE)
+    out.write(_HTML_FILE_START + '\n')
 
-    # Always add the HTML polyfil and the Polymer config.
-    out.write(_HTML_IMPORT_POLYFIL + '\n')
-    out.write(_IMPORT % ('chrome://resources/html/polymer.html') + '\n')
+    line = _JS_MODULE % (js_module_url)
+    out.write(line + '\n')
 
-    dep_type = 'html_import' if html_import else 'classic_script'
-    for dep in _process_deps(mocks, dep_type, target_name):
-      out.write(dep + '\n')
-    for dep in _process_deps(deps, dep_type, target_name):
-      out.write(dep + '\n')
-
-    out.write(_HTML_FOOTER)
+    line = _JS_MODULE_REGISTER_TESTS % (js_module_url)
+    out.write(line + '\n')
 
 
 def main():
@@ -199,42 +59,17 @@
       '--output',
       help='Generated html output with flattened dependencies',
       required=True)
-  parser.add_argument(
-      '-m',
-      '--mocks',
-      nargs='*',
-      default=[],
-      help='List of additional js files to load before others')
   parser.add_argument('-t', '--target_name', help='Test target name')
-  parser.add_argument(
-      '--html_import',
-      action='store_true',
-      help='Enable HTMLImports, used for Polymer elements')
-  parser.add_argument(
-      '--js_module',
-      action='store_true',
-      help='Enable JS Modules for the unittest file.')
   args = parser.parse_args()
 
-  if args.js_module:
-    # Convert from:
-    # gen/ui/file_manager/file_manager/common/js/example_unittest.m.js_library
-    # To:
-    # ui/file_manager/file_manager/common/js/example_unittest.m.js
-    path_test_file = args.input.replace('gen/', '', 1)
-    path_test_file = path_test_file.replace('.js_library', '.js')
-    _process_js_module(path_test_file, args.output, args.mocks,
-                              args.target_name)
-    return
-
-  # Append closure path to sys.path to be able to import js_unit_test.
-  sys.path.append(os.path.join(args.src_path, 'third_party/closure_compiler'))
-  from js_binary import CrawlDepsTree
-
-  deps, _ = CrawlDepsTree([args.input])
-
-  return _process(deps, args.output, args.mocks, args.html_import,
-                  args.target_name)
+  # Convert from:
+  # gen/ui/file_manager/file_manager/common/js/example_unittest.m.js_library
+  # To:
+  # ui/file_manager/file_manager/common/js/example_unittest.m.js
+  path_test_file = args.input.replace('gen/', '', 1)
+  path_test_file = path_test_file.replace('.js_library', '.js')
+  _process_js_module(path_test_file, args.output)
+  return
 
 
 if __name__ == '__main__':
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index 9553a7c..391dda0 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -773,7 +773,6 @@
     ":trash_unittest.m",
     ":volume_manager_unittest.m",
   ]
-  js_module = true
 
   closure_flags =
       strict_error_checking_closure_args + [
diff --git a/ui/file_manager/file_manager/background/js/drive_sync_handler.js b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
index ea3b68c..88981e1 100644
--- a/ui/file_manager/file_manager/background/js/drive_sync_handler.js
+++ b/ui/file_manager/file_manager/background/js/drive_sync_handler.js
@@ -227,6 +227,9 @@
    * @private
    */
   async onFileTransfersStatusReceived_(item, status) {
+    if (!this.isProcessableEvent(status)) {
+      return;
+    }
     switch (status.transferState) {
       case 'in_progress':
         await this.updateItem_(item, status);
@@ -308,12 +311,34 @@
   }
 
   /**
+   * Attempts to infer of the given event is processable by the drive sync
+   * handler. It uses fileUrl and window.isSwa flag to make a decision. It
+   * errs on the side of 'yes', when passing the judgement.
+   * @param {!Object} event
+   * @return {boolean} Whether or not the event should be processed.
+   */
+  isProcessableEvent(event) {
+    const fileUrl = event.fileUrl;
+    if (fileUrl) {
+      const match = 'filesystem:' +
+          (window.isSWA ?
+               'chrome://file-manager' :
+               'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj');
+      return fileUrl.startsWith(match);
+    }
+    return true;
+  }
+
+  /**
    * Handles drive's sync errors.
    * @param {chrome.fileManagerPrivate.DriveSyncErrorEvent} event Drive sync
    * error event.
    * @private
    */
   onDriveSyncError_(event) {
+    if (!this.isProcessableEvent(event)) {
+      return;
+    }
     const postError = name => {
       const item = new ProgressCenterItem();
       item.type = ProgressItemType.SYNC;
@@ -390,6 +415,9 @@
    * @private
    */
   async onDriveConfirmDialog_(event) {
+    if (!this.isProcessableEvent(event)) {
+      return;
+    }
     let appId = null;
     // When a file manager is launched, its dialog will be added to dialogs_, so
     // check it to see if there is already a window open.
diff --git a/ui/file_manager/file_manager/background/js/drive_sync_handler_unittest.m.js b/ui/file_manager/file_manager/background/js/drive_sync_handler_unittest.m.js
index 2fc5e57..1a6245f 100644
--- a/ui/file_manager/file_manager/background/js/drive_sync_handler_unittest.m.js
+++ b/ui/file_manager/file_manager/background/js/drive_sync_handler_unittest.m.js
@@ -22,6 +22,15 @@
 let driveSyncHandler;
 
 /**
+ * @param {string} name file name
+ * @return {string} Valid file URL
+ */
+function asFileURL(name) {
+  return 'filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
+      `external/${name}`;
+}
+
+/**
  * Mock chrome APIs.
  * @type {Object}
  */
@@ -227,7 +236,7 @@
 export async function testOffline() {
   // Start a transfer.
   await mockChrome.fileManagerPrivate.onFileTransfersUpdated.listener_({
-    fileUrl: 'name',
+    fileUrl: asFileURL('name'),
     transferState: 'in_progress',
     processed: 50.0,
     total: 100.0,
@@ -258,7 +267,7 @@
 export async function testTransferUpdate() {
   // Start a pin transfer.
   await mockChrome.fileManagerPrivate.onPinTransfersUpdated.listener_({
-    fileUrl: 'name',
+    fileUrl: asFileURL('name'),
     transferState: 'in_progress',
     processed: 50.0,
     total: 100.0,
@@ -275,7 +284,7 @@
 
   // Start a sync transfer.
   await mockChrome.fileManagerPrivate.onFileTransfersUpdated.listener_({
-    fileUrl: 'name',
+    fileUrl: asFileURL('name'),
     transferState: 'in_progress',
     processed: 25.0,
     total: 100.0,
@@ -290,7 +299,7 @@
 
   // Finish the pin transfer.
   await mockChrome.fileManagerPrivate.onPinTransfersUpdated.listener_({
-    fileUrl: 'name',
+    fileUrl: asFileURL('name'),
     transferState: 'completed',
     processed: 100.0,
     total: 100.0,
@@ -307,7 +316,7 @@
 
   // Fail the sync transfer.
   await mockChrome.fileManagerPrivate.onFileTransfersUpdated.listener_({
-    fileUrl: 'name',
+    fileUrl: asFileURL('name'),
     transferState: 'failed',
     processed: 40.0,
     total: 100.0,
diff --git a/ui/file_manager/file_manager/common/js/BUILD.gn b/ui/file_manager/file_manager/common/js/BUILD.gn
index eb997bc..94d6e137 100644
--- a/ui/file_manager/file_manager/common/js/BUILD.gn
+++ b/ui/file_manager/file_manager/common/js/BUILD.gn
@@ -319,7 +319,6 @@
 }
 
 js_test_gen_html("js_test_gen_html_modules") {
-  js_module = true
   deps = [
     ":file_type_unittest.m",
     ":files_app_entry_types_unittest.m",
diff --git a/ui/file_manager/file_manager/foreground/elements/elements_bundle.html b/ui/file_manager/file_manager/foreground/elements/elements_bundle.html
deleted file mode 100644
index 98bc30a..0000000
--- a/ui/file_manager/file_manager/foreground/elements/elements_bundle.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!-- Copyright 2016 The Chromium Authors. All rights reserved.
-  -- Use of this source code is governed by a BSD-style license that can be
-  -- found in the LICENSE file.
-  -->
-
-<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-progress/paper-progress.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-ripple/paper-ripple.html">
-<link rel="import" href="files_format_dialog.html">
-<link rel="import" href="files_message.html">
-<link rel="import" href="files_password_dialog.html">
-<link rel="import" href="files_ripple.html">
-<link rel="import" href="files_spinner.html">
-<link rel="import" href="files_toast.html">
-<link rel="import" href="files_toggle_ripple.html">
-<link rel="import" href="files_tooltip.html">
-<link rel="import" href="files_xf_elements.html">
-<link rel="import" href="icons.html">
diff --git a/ui/file_manager/file_manager/foreground/elements/files_xf_elements.html b/ui/file_manager/file_manager/foreground/elements/files_xf_elements.html
deleted file mode 100644
index 7af4077a..0000000
--- a/ui/file_manager/file_manager/foreground/elements/files_xf_elements.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!-- Copyright 2019 The Chromium Authors. All rights reserved.
-  -- Use of this source code is governed by a BSD-style license that can be
-  -- found in the LICENSE file.
-  -->
-<link rel="import" href="chrome://resources/html/polymer.html">
-
-<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-
-<link rel="import" href="icons.html">
-
-<script src="xf_button.js"></script>
-<script src="xf_circular_progress.js"></script>
-<script src="xf_display_panel.js"></script>
-<script src="xf_panel_item.js"></script>
diff --git a/ui/file_manager/file_manager/foreground/elements/icons.html b/ui/file_manager/file_manager/foreground/elements/icons.html
index ce6a0794..06cdea4 100644
--- a/ui/file_manager/file_manager/foreground/elements/icons.html
+++ b/ui/file_manager/file_manager/foreground/elements/icons.html
@@ -2,10 +2,6 @@
   -- Use of this source code is governed by a BSD-style license that can be
   -- found in the LICENSE file.
   -->
-
-<link rel="import" href="chrome://resources/html/polymer.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
-
 <iron-iconset-svg name="files" size="24">
   <svg>
     <defs>
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index 2beb467..ecdb708 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -1035,12 +1035,6 @@
       DialogType.FULL_PAGE,
     ]);
 
-    if (window.isSWA) {
-      // TODO: Verify that SWA will work with module version for dispatcher.
-      ContentMetadataProvider.configure(
-          'foreground/js/metadata/metadata_dispatcher.js');
-    }
-
     // Create the metadata cache.
     assert(this.volumeManager_);
     this.metadataModel_ = MetadataModel.create(this.volumeManager_);
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 419254e..2df4358 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -2201,8 +2201,13 @@
     // space in the file list.
     const noEntries = selection.entries.length === 0;
     event.command.setHidden(noEntries);
+
+    // TODO(crbug/1226915) Make it work with MTP.
+    const isOnEligibleLocation =
+        !util.isZipPackEnabled() || !fileManager.directoryModel.isOnMTP();
+
     event.canExecute = dirEntry && !fileManager.directoryModel.isReadOnly() &&
-        selection && selection.totalCount > 0;
+        isOnEligibleLocation && selection && selection.totalCount > 0;
   }
 };
 
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn
index ae9f9e7b..3909e878 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/metadata/BUILD.gn
@@ -360,7 +360,6 @@
     ":multi_metadata_provider_unittest.m",
     ":thumbnail_model_unittest.m",
   ]
-  js_module = true
 
   closure_flags = strict_error_checking_closure_args + [
                     "js_module_root=./gen/ui",
diff --git a/ui/file_manager/file_manager_resources.grd b/ui/file_manager/file_manager_resources.grd
index 09fa321..897bfa2 100644
--- a/ui/file_manager/file_manager_resources.grd
+++ b/ui/file_manager/file_manager_resources.grd
@@ -15,9 +15,6 @@
       <!-- The Files app pages and scripts. -->
       <include name="IDR_FILE_MANAGER_BACKGROUND_HTML" file="file_manager/background.html" type="BINDATA" />
       <!-- Polymer elements -->
-      <include name="IDR_FILE_MANAGER_ELEMENTS_ELEMENTS_BUNDLE_HTML" file="file_manager/foreground/elements/elements_bundle.html" type="BINDATA"/>
-      <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_MESSAGE_HTML" file="file_manager/foreground/elements/files_message.html" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_PASSWORD_DIALOG_HTML" file="file_manager/foreground/elements/files_password_dialog.html" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_QUICK_PREVIEW_CSS" file="file_manager/foreground/elements/files_quick_view.css"  type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SAFE_AUDIO_WEBVIEW_CONTENT_CSS" file="file_manager/foreground/elements/files_safe_audio_webview_content.css" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SAFE_AUDIO_WEBVIEW_CONTENT_HTML" file="file_manager/foreground/elements/files_safe_audio_webview_content.html" type="BINDATA" />
@@ -28,9 +25,6 @@
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SAFE_MEDIA_WEBVIEW_CONTENT_JS" file="file_manager/foreground/elements/files_safe_media_webview_content.js" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SAFE_VIDEO_WEBVIEW_CONTENT_CSS" file="file_manager/foreground/elements/files_safe_video_webview_content.css" type="BINDATA" />
       <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SAFE_VIDEO_WEBVIEW_CONTENT_HTML" file="file_manager/foreground/elements/files_safe_video_webview_content.html" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_SPINNER_HTML" file="file_manager/foreground/elements/files_spinner.html" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_ELEMENTS_ICONS_HTML" file="file_manager/foreground/elements/icons.html" type="BINDATA" />
-      <include name="IDR_FILE_MANAGER_ELEMENTS_FILES_XF_ELEMENTS_HTML" file="file_manager/foreground/elements/files_xf_elements.html" type="BINDATA" />
 
       <!-- Scripts required by the metadata parser worker. -->
 
@@ -51,7 +45,6 @@
 
       <!-- The VideoPlayer app pages and scripts. -->
       <include name="IDR_VIDEO_PLAYER_MANIFEST" file="video_player/manifest.json" type="BINDATA" />
-      <include name="IDR_VIDEO_PLAYER" file="video_player/video_player.html" allowexternalscript="true" flattenhtml="true" type="BINDATA" />
       <include name="IDR_VIDEO_PLAYER_MODULE" file="video_player/video_player_module.html" allowexternalscript="true" flattenhtml="true" type="BINDATA" />
       <include name="IDR_VIDEO_PLAYER_BACKGROUND_HTML" file="video_player/background.html" type="BINDATA" />
       <include name="IDR_VIDEO_PLAYER_ICON_FAVICON_16" file="video_player/images/icon/video-player-favicon-16.png" type="BINDATA" />
diff --git a/ui/file_manager/image_loader/BUILD.gn b/ui/file_manager/image_loader/BUILD.gn
index 17f4384..a38ff76 100644
--- a/ui/file_manager/image_loader/BUILD.gn
+++ b/ui/file_manager/image_loader/BUILD.gn
@@ -129,7 +129,6 @@
     ":image_loader_unittest.m",
     ":scheduler_unittest.m",
   ]
-  js_module = true
 
   closure_flags = strict_error_checking_closure_args + [
                     "js_module_root=./gen/ui",
diff --git a/ui/file_manager/video_player/video_player.html b/ui/file_manager/video_player/video_player.html
deleted file mode 100644
index 471925d..0000000
--- a/ui/file_manager/video_player/video_player.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!--
-  -- Copyright 2014 The Chromium Authors. All rights reserved.
-  -- Use of this source code is governed by a BSD-style license that can be
-  -- found in the LICENSE file.
-  -->
-
-<html>
-<head>
-  <title>#xFEFF;</title>
-  <script src="chrome://resources/polymer/v1_0/html-imports/html-imports.min.js"></script>
-  <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-
-  <link rel="stylesheet" type="text/css" href="css/video_player.css">
-  <link rel="stylesheet" type="text/css" href="css/arrow_box.css">
-
-  <link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
-
-  <script src="chrome://resources/js/load_time_data.js"></script>
-  <script src="js/video_player_scripts.js"></script>
-</head>
-<body>
-  <custom-style>
-    <style>
-
-      /* Let cr-toast appear at top left corner */
-      cr-toast {
-          bottom: auto;
-          top: 0;
-          transform: translateY(-100px);
-      }
-
-      cr-toast[open] {
-          transform: translateY(0);
-      }
-
-    </style>
-  </custom-style>
-  <div id="video-player">
-    <cr-toast id="toast" duration="3000">
-      <div id="toast-content"></div>
-    </cr-toast>
-    <div id="video-container">
-    </div>
-    <div class="arrow-box">
-      <div class="arrow left tool"><div></div></div>
-      <div class="arrow-spacer"></div>
-      <div class="arrow right tool"><div></div></div>
-    </div>
-  </div>
-</body>
-</html>
diff --git a/ui/gfx/android/android_surface_control_compat.cc b/ui/gfx/android/android_surface_control_compat.cc
index 994b8125..6f0a99b8 100644
--- a/ui/gfx/android/android_surface_control_compat.cc
+++ b/ui/gfx/android/android_surface_control_compat.cc
@@ -597,6 +597,17 @@
 void SurfaceControl::Transaction::Apply() {
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("gpu,benchmark",
                                     "SurfaceControlTransaction", id_);
+
+  PrepareCallbacks();
+  SurfaceControlMethods::Get().ASurfaceTransaction_applyFn(transaction_);
+}
+
+ASurfaceTransaction* SurfaceControl::Transaction::GetTransaction() {
+  PrepareCallbacks();
+  return transaction_;
+}
+
+void SurfaceControl::Transaction::PrepareCallbacks() {
   if (on_commit_cb_) {
     TransactionAckCtx* ack_ctx = new TransactionAckCtx;
     ack_ctx->latch_callback = std::move(on_commit_cb_);
@@ -614,8 +625,6 @@
     SurfaceControlMethods::Get().ASurfaceTransaction_setOnCompleteFn(
         transaction_, ack_ctx, &OnTransactionCompletedOnAnyThread);
   }
-
-  SurfaceControlMethods::Get().ASurfaceTransaction_applyFn(transaction_);
 }
 
 }  // namespace gfx
diff --git a/ui/gfx/android/android_surface_control_compat.h b/ui/gfx/android/android_surface_control_compat.h
index cd12d68..3d74956 100644
--- a/ui/gfx/android/android_surface_control_compat.h
+++ b/ui/gfx/android/android_surface_control_compat.h
@@ -151,9 +151,11 @@
                        scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
     void Apply();
-    ASurfaceTransaction* transaction() { return transaction_; }
+    ASurfaceTransaction* GetTransaction();
 
    private:
+    void PrepareCallbacks();
+
     int id_;
     ASurfaceTransaction* transaction_;
     OnCommitCb on_commit_cb_;
diff --git a/ui/gfx/delegated_ink_metadata.h b/ui/gfx/delegated_ink_metadata.h
index a110315..04b8c7c0 100644
--- a/ui/gfx/delegated_ink_metadata.h
+++ b/ui/gfx/delegated_ink_metadata.h
@@ -51,6 +51,7 @@
         frame_time_(frame_time),
         is_hovering_(hovering) {}
   DelegatedInkMetadata(const DelegatedInkMetadata& other) = default;
+  DelegatedInkMetadata& operator=(const DelegatedInkMetadata& other) = default;
 
   const PointF& point() const { return point_; }
   double diameter() const { return diameter_; }
diff --git a/ui/gfx/display_color_spaces.cc b/ui/gfx/display_color_spaces.cc
index 19a552ec..a5b8e14 100644
--- a/ui/gfx/display_color_spaces.cc
+++ b/ui/gfx/display_color_spaces.cc
@@ -47,9 +47,12 @@
     buffer_format = DefaultBufferFormat();
 }
 
-DisplayColorSpaces::DisplayColorSpaces(const gfx::DisplayColorSpaces& c) =
+DisplayColorSpaces::DisplayColorSpaces(const gfx::DisplayColorSpaces&) =
     default;
 
+DisplayColorSpaces& DisplayColorSpaces::operator=(
+    const gfx::DisplayColorSpaces&) = default;
+
 DisplayColorSpaces::DisplayColorSpaces(const gfx::ColorSpace& c)
     : DisplayColorSpaces() {
   if (!c.IsValid())
diff --git a/ui/gfx/display_color_spaces.h b/ui/gfx/display_color_spaces.h
index db5700b06..85d3d8e8 100644
--- a/ui/gfx/display_color_spaces.h
+++ b/ui/gfx/display_color_spaces.h
@@ -46,6 +46,7 @@
   // Initialize as sRGB-only.
   DisplayColorSpaces();
   DisplayColorSpaces(const DisplayColorSpaces& display_color_space);
+  DisplayColorSpaces& operator=(const DisplayColorSpaces& display_color_space);
 
   // Initialize as |color_space| for all settings. If |color_space| is the
   // default (invalid) color space, then initialize to sRGB. The BufferFormat
diff --git a/ui/gfx/font_fallback_linux.cc b/ui/gfx/font_fallback_linux.cc
index d9138ab..dcdcba57 100644
--- a/ui/gfx/font_fallback_linux.cc
+++ b/ui/gfx/font_fallback_linux.cc
@@ -57,6 +57,8 @@
  public:
   TypefaceCacheKey(const base::FilePath& font_path, int ttc_index)
       : font_path_(font_path), ttc_index_(ttc_index) {}
+  TypefaceCacheKey(const TypefaceCacheKey&) = default;
+  TypefaceCacheKey& operator=(const TypefaceCacheKey&) = default;
 
   const base::FilePath& font_path() const { return font_path_; }
   int ttc_index() const { return ttc_index_; }
@@ -69,8 +71,6 @@
  private:
   base::FilePath font_path_;
   int ttc_index_;
-
-  DISALLOW_ASSIGN(TypefaceCacheKey);
 };
 
 // Returns a SkTypeface for a given font path and ttc_index. The typeface is
@@ -514,6 +514,8 @@
 
 FallbackFontData::FallbackFontData() = default;
 FallbackFontData::FallbackFontData(const FallbackFontData& other) = default;
+FallbackFontData& FallbackFontData::operator=(const FallbackFontData& other) =
+    default;
 
 bool GetFallbackFontForChar(UChar32 c,
                             const std::string& locale,
diff --git a/ui/gfx/font_fallback_linux.h b/ui/gfx/font_fallback_linux.h
index 6e418b7..7a76869 100644
--- a/ui/gfx/font_fallback_linux.h
+++ b/ui/gfx/font_fallback_linux.h
@@ -28,6 +28,7 @@
 
   FallbackFontData();
   FallbackFontData(const FallbackFontData& other);
+  FallbackFontData& operator=(const FallbackFontData& other);
 };
 
 // Return a font family which provides a glyph for the Unicode code point
diff --git a/ui/gfx/hdr_metadata.cc b/ui/gfx/hdr_metadata.cc
index d545475..07a6aca 100644
--- a/ui/gfx/hdr_metadata.cc
+++ b/ui/gfx/hdr_metadata.cc
@@ -8,8 +8,11 @@
 
 MasteringMetadata::MasteringMetadata() = default;
 MasteringMetadata::MasteringMetadata(const MasteringMetadata& rhs) = default;
+MasteringMetadata& MasteringMetadata::operator=(const MasteringMetadata& rhs) =
+    default;
 
 HDRMetadata::HDRMetadata() = default;
 HDRMetadata::HDRMetadata(const HDRMetadata& rhs) = default;
+HDRMetadata& HDRMetadata::operator=(const HDRMetadata& rhs) = default;
 
 }  // namespace gfx
diff --git a/ui/gfx/hdr_metadata.h b/ui/gfx/hdr_metadata.h
index dfb55a9..3079a13 100644
--- a/ui/gfx/hdr_metadata.h
+++ b/ui/gfx/hdr_metadata.h
@@ -22,6 +22,7 @@
 
   MasteringMetadata();
   MasteringMetadata(const MasteringMetadata& rhs);
+  MasteringMetadata& operator=(const MasteringMetadata& rhs);
 
   bool operator==(const MasteringMetadata& rhs) const {
     return ((primary_r == rhs.primary_r) && (primary_g == rhs.primary_g) &&
@@ -43,6 +44,7 @@
 
   HDRMetadata();
   HDRMetadata(const HDRMetadata& rhs);
+  HDRMetadata& operator=(const HDRMetadata& rhs);
 
   bool IsValid() const {
     return !((max_content_light_level == 0) &&
diff --git a/ui/gfx/hdr_static_metadata.cc b/ui/gfx/hdr_static_metadata.cc
index 50b0e08..b5b3f0a 100644
--- a/ui/gfx/hdr_static_metadata.cc
+++ b/ui/gfx/hdr_static_metadata.cc
@@ -10,5 +10,7 @@
 HDRStaticMetadata::HDRStaticMetadata(double max, double max_avg, double min)
     : max(max), max_avg(max_avg), min(min) {}
 HDRStaticMetadata::HDRStaticMetadata(const HDRStaticMetadata& rhs) = default;
+HDRStaticMetadata& HDRStaticMetadata::operator=(const HDRStaticMetadata& rhs) =
+    default;
 
 }  // namespace gfx
diff --git a/ui/gfx/hdr_static_metadata.h b/ui/gfx/hdr_static_metadata.h
index 7920ad7..035d3ac 100644
--- a/ui/gfx/hdr_static_metadata.h
+++ b/ui/gfx/hdr_static_metadata.h
@@ -28,6 +28,7 @@
   HDRStaticMetadata();
   HDRStaticMetadata(double max, double max_avg, double min);
   HDRStaticMetadata(const HDRStaticMetadata& rhs);
+  HDRStaticMetadata& operator=(const HDRStaticMetadata& rhs);
 
   bool operator==(const HDRStaticMetadata& rhs) const {
     return ((max == rhs.max) && (max_avg == rhs.max_avg) && (min == rhs.min));
diff --git a/ui/gfx/image/image_ios_unittest.mm b/ui/gfx/image/image_ios_unittest.mm
index 4df71ce..3d7f9c6 100644
--- a/ui/gfx/image/image_ios_unittest.mm
+++ b/ui/gfx/image/image_ios_unittest.mm
@@ -6,8 +6,8 @@
 #include <stddef.h>
 #import <UIKit/UIKit.h>
 
+#include "base/cxx17_backports.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
diff --git a/ui/gfx/ios/uikit_util_unittest.mm b/ui/gfx/ios/uikit_util_unittest.mm
index 61d024c..269b4b3 100644
--- a/ui/gfx/ios/uikit_util_unittest.mm
+++ b/ui/gfx/ios/uikit_util_unittest.mm
@@ -5,7 +5,7 @@
 #import <Foundation/Foundation.h>
 #include <stddef.h>
 
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/platform_test.h"
 #import "ui/gfx/ios/uikit_util.h"
 
diff --git a/ui/gfx/path_mac.mm b/ui/gfx/path_mac.mm
index ae10817..fd82ad9 100644
--- a/ui/gfx/path_mac.mm
+++ b/ui/gfx/path_mac.mm
@@ -8,8 +8,8 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/cxx17_backports.h"
 #include "base/notreached.h"
-#include "base/stl_util.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/core/SkRegion.h"
 
diff --git a/ui/gfx/path_mac_unittest.mm b/ui/gfx/path_mac_unittest.mm
index 1f2dff56..149c4e3ce 100644
--- a/ui/gfx/path_mac_unittest.mm
+++ b/ui/gfx/path_mac_unittest.mm
@@ -10,7 +10,7 @@
 #import <Cocoa/Cocoa.h>
 
 #include "base/check_op.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/core/SkRegion.h"
diff --git a/ui/gfx/platform_font_mac_unittest.mm b/ui/gfx/platform_font_mac_unittest.mm
index ca6e523..46b2e6d 100644
--- a/ui/gfx/platform_font_mac_unittest.mm
+++ b/ui/gfx/platform_font_mac_unittest.mm
@@ -7,9 +7,9 @@
 #include <Cocoa/Cocoa.h>
 #include <stddef.h>
 
+#include "base/cxx17_backports.h"
 #import "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/font.h"
 
diff --git a/ui/gfx/transform.h b/ui/gfx/transform.h
index bba654b..a005b71 100644
--- a/ui/gfx/transform.h
+++ b/ui/gfx/transform.h
@@ -40,7 +40,8 @@
   // initialized before use.
   Transform(SkipInitialization)
       : matrix_(skia::Matrix44::kUninitialized_Constructor) {}
-  Transform(const Transform& rhs) : matrix_(rhs.matrix_) {}
+  Transform(const Transform& rhs) = default;
+  Transform& operator=(const Transform& rhs) = default;
   // Initialize with the concatenation of lhs * rhs.
   Transform(const Transform& lhs, const Transform& rhs)
       : matrix_(lhs.matrix_, rhs.matrix_) {}
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 879bd28..bb7d843 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -11,6 +11,7 @@
 import("//build/config/ui.gni")
 import("//testing/test.gni")
 import("//third_party/angle/gni/angle.gni")
+import("//third_party/dawn/scripts/dawn_features.gni")
 import("//ui/gl/features.gni")
 
 declare_args() {
@@ -29,6 +30,7 @@
 buildflag_header("buildflags") {
   header = "buildflags.h"
   flags = [
+    "DAWN_ENABLE_BACKEND_OPENGLES=$dawn_enable_opengles",
     "ENABLE_SWIFTSHADER=$enable_swiftshader",
     "USE_DAWN=$use_dawn",
     "USE_STATIC_ANGLE=$use_static_angle",
diff --git a/ui/gl/gl_image_d3d.h b/ui/gl/gl_image_d3d.h
index fa62f42..fba31d13 100644
--- a/ui/gl/gl_image_d3d.h
+++ b/ui/gl/gl_image_d3d.h
@@ -74,6 +74,8 @@
   size_t array_slice() const { return array_slice_; }
   size_t plane_index() const { return plane_index_; }
 
+  void* egl_image() const { return egl_image_; }
+
  protected:
   const gfx::Size size_;
   const unsigned internal_format_;  // GLenum
diff --git a/ui/gl/gl_image_egl.h b/ui/gl/gl_image_egl.h
index 2d0a5725..18d59d4 100644
--- a/ui/gl/gl_image_egl.h
+++ b/ui/gl/gl_image_egl.h
@@ -25,6 +25,8 @@
   bool BindTexImage(unsigned target) override;
   void ReleaseTexImage(unsigned target) override {}
 
+  void* egl_image() const { return egl_image_; }
+
  protected:
   ~GLImageEGL() override;
 
diff --git a/ui/message_center/OWNERS b/ui/message_center/OWNERS
index 80f2be4d..8b446e3 100644
--- a/ui/message_center/OWNERS
+++ b/ui/message_center/OWNERS
@@ -1,5 +1,4 @@
 dewittj@chromium.org
 estade@chromium.org
 peter@chromium.org
-yoshiki@chromium.org
-tengs@chromium.org
+yoshiki@chromium.org
\ No newline at end of file
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc
index 4874ef5..7f32d59 100644
--- a/ui/ozone/platform/drm/common/drm_util.cc
+++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -503,8 +503,8 @@
     DCHECK(edid_blob->length);
     edid.assign(static_cast<uint8_t*>(edid_blob->data),
                 static_cast<uint8_t*>(edid_blob->data) + edid_blob->length);
-
-    display::EdidParser edid_parser(edid);
+    const bool is_external = type != display::DISPLAY_CONNECTION_TYPE_INTERNAL;
+    display::EdidParser edid_parser(edid, is_external);
     display_name = edid_parser.display_name();
     active_pixel_size = edid_parser.active_pixel_size();
     product_code = edid_parser.GetProductCode();
diff --git a/ui/ozone/platform/drm/gpu/drm_device.h b/ui/ozone/platform/drm/gpu/drm_device.h
index 400c9a8..ded9f34c 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.h
+++ b/ui/ozone/platform/drm/gpu/drm_device.h
@@ -64,11 +64,11 @@
 
   struct Property {
     // Unique identifier for the property. 0 denotes an invalid ID.
-    uint32_t id;
+    uint32_t id = 0;
 
     // Depending on the property, this may be an actual value describing the
     // property or an ID of another property.
-    uint64_t value;
+    uint64_t value = 0;
   };
 
   DrmDevice(const base::FilePath& device_path,
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
index 43c9c79..4285fb5 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -44,6 +44,7 @@
 constexpr uint32_t kActivePropId = 1000;
 constexpr uint32_t kModePropId = 1001;
 constexpr uint32_t kCrtcIdPropId = 2000;
+constexpr uint32_t kLinkStatusPropId = 2001;
 
 constexpr uint32_t kPlaneCrtcId = 3001;
 constexpr uint32_t kCrtcX = 3002;
@@ -163,6 +164,7 @@
   std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2);
   std::map<uint32_t, std::string> connector_property_names = {
       {kCrtcIdPropId, "CRTC_ID"},
+      {kLinkStatusPropId, "link-status"},
   };
   for (size_t i = 0; i < connector_properties.size(); ++i) {
     connector_properties[i].id = kConnectorIdBase + i;
@@ -340,11 +342,20 @@
   ui::ScopedDrmObjectPropertyPtr connector_props =
       drm_->GetObjectProperties(kConnectorIdBase, DRM_MODE_OBJECT_CONNECTOR);
 
-  ui::DrmDevice::Property prop = {};
-  ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "CRTC_ID",
-                            &prop);
-  EXPECT_EQ(kCrtcIdPropId, prop.id);
-  EXPECT_EQ(kCrtcIdBase, prop.value);
+  {
+    ui::DrmDevice::Property prop = {};
+    ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "CRTC_ID",
+                              &prop);
+    EXPECT_EQ(kCrtcIdPropId, prop.id);
+    EXPECT_EQ(kCrtcIdBase, prop.value);
+  }
+  {
+    ui::DrmDevice::Property prop = {};
+    ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "link-status",
+                              &prop);
+    EXPECT_EQ(kLinkStatusPropId, prop.id);
+    EXPECT_EQ(static_cast<uint64_t>(DRM_MODE_LINK_STATUS_GOOD), prop.value);
+  }
 }
 
 TEST_F(HardwareDisplayControllerTest, PlanePropsAfterModeset) {
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
index c2a2426..a8daf90f 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
@@ -35,6 +35,8 @@
 }
 
 }  // namespace
+HardwareDisplayPlane::Properties::Properties() = default;
+HardwareDisplayPlane::Properties::~Properties() = default;
 
 HardwareDisplayPlane::HardwareDisplayPlane(uint32_t id) : id_(id) {}
 
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane.h b/ui/ozone/platform/drm/gpu/hardware_display_plane.h
index aea531a7..5e976758 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane.h
@@ -46,6 +46,8 @@
 
  protected:
   struct Properties {
+    Properties();
+    ~Properties();
     // These properties are mandatory on DRM atomic. On legacy they may or may
     // not be present.
     DrmDevice::Property crtc_id;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 448cfa9..e3add6a 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -36,6 +36,11 @@
 
 HardwareDisplayPlaneList::PageFlipInfo::~PageFlipInfo() = default;
 
+HardwareDisplayPlaneManager::CrtcProperties::CrtcProperties() = default;
+HardwareDisplayPlaneManager::CrtcProperties::CrtcProperties(
+    const CrtcProperties& other) = default;
+HardwareDisplayPlaneManager::CrtcProperties::~CrtcProperties() = default;
+
 HardwareDisplayPlaneManager::CrtcState::CrtcState() = default;
 
 HardwareDisplayPlaneManager::CrtcState::~CrtcState() = default;
@@ -252,6 +257,8 @@
     }
     GetDrmPropertyForName(drm_, props.get(), "CRTC_ID", &state_props.crtc_id);
     DCHECK(!drm_->is_atomic() || state_props.crtc_id.id);
+    GetDrmPropertyForName(drm_, props.get(), "link-status",
+                          &state_props.link_status);
 
     connectors_props_.emplace_back(std::move(state_props));
   }
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 4c6bfd39..9a58fe7f 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -58,6 +58,9 @@
 class HardwareDisplayPlaneManager {
  public:
   struct CrtcProperties {
+    CrtcProperties();
+    CrtcProperties(const CrtcProperties& other);
+    ~CrtcProperties();
     // Unique identifier for the CRTC. This must be greater than 0 to be valid.
     uint32_t id;
     // Keeps track of the CRTC state. If a surface has been bound, then the
@@ -193,6 +196,7 @@
   struct ConnectorProperties {
     uint32_t id;
     DrmDevice::Property crtc_id;
+    DrmDevice::Property link_status;
   };
 
   bool InitializeCrtcState();
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
index 6a6f660..915341fc 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -98,9 +98,18 @@
   // updated only after a successful modeset.
   ConnectorProperties connector_props = connectors_props_[connector_index];
   connector_props.crtc_id.value = crtc_id;
+  // Always set link-status to DRM_MODE_LINK_STATUS_GOOD. In case a link
+  // training has failed and link-status is now BAD, the kernel expects the
+  // userspace to reset it to GOOD; otherwise, it will ignore modeset requests
+  // which have the same mode as the reported bad status.
+  // https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
+  connector_props.link_status.value = DRM_MODE_LINK_STATUS_GOOD;
 
-  return AddPropertyIfValid(atomic_request, connector_id,
-                            connector_props.crtc_id);
+  bool status =
+      AddPropertyIfValid(atomic_request, connector_id, connector_props.crtc_id);
+  status &= AddPropertyIfValid(atomic_request, connector_id,
+                               connector_props.link_status);
+  return status;
 }
 
 bool HardwareDisplayPlaneManagerAtomic::Commit(CommitRequest commit_request,
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc
index 1afd9dc..42c247e 100644
--- a/ui/ozone/platform/wayland/host/wayland_surface.cc
+++ b/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -11,6 +11,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/size_f.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/platform/wayland/common/wayland_util.h"
 #include "ui/ozone/platform/wayland/host/wayland_connection.h"
@@ -135,9 +136,8 @@
   }
   // Apply viewport scale (wp_viewport.set_destination).
   gfx::Size viewport_dst = bounds;
-  if (!display_size_px_.IsEmpty()) {
-    viewport_dst =
-        gfx::ScaleToCeiledSize(display_size_px_, 1.f / buffer_scale_);
+  if (!display_size_dip_.IsEmpty()) {
+    viewport_dst = display_size_dip_;
   }
 
   if (connection_->compositor_version() >=
@@ -308,22 +308,20 @@
 }
 
 void WaylandSurface::SetViewportDestination(const gfx::Size& dest_size_px) {
-  if (dest_size_px == display_size_px_)
+  if (dest_size_px == gfx::ScaleToRoundedSize(display_size_dip_, buffer_scale_))
     return;
 
   if (dest_size_px.IsEmpty()) {
-    display_size_px_ = gfx::Size();
+    display_size_dip_ = gfx::Size();
     if (viewport()) {
       wp_viewport_set_destination(viewport(), -1, -1);
     }
     return;
   }
-  display_size_px_ = dest_size_px;
-  gfx::Size viewport_dst =
-      gfx::ScaleToCeiledSize(display_size_px_, 1.f / buffer_scale_);
+  display_size_dip_ = gfx::ScaleToCeiledSize(dest_size_px, 1.f / buffer_scale_);
   if (viewport()) {
-    wp_viewport_set_destination(viewport(), viewport_dst.width(),
-                                viewport_dst.height());
+    wp_viewport_set_destination(viewport(), display_size_dip_.width(),
+                                display_size_dip_.height());
   }
 }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h
index a5d9af6..ef3efefa 100644
--- a/ui/ozone/platform/wayland/host/wayland_surface.h
+++ b/ui/ozone/platform/wayland/host/wayland_surface.h
@@ -180,11 +180,10 @@
   // If empty, no cropping is applied.
   gfx::RectF crop_rect_ = gfx::RectF();
 
-  // Current size of the destination of the viewport in physical pixels. Wayland
-  // compositor will scale the (cropped) buffer content to fit the
-  // |display_size_px_|.
+  // Current size of the destination of the viewport in DIP. Wayland compositor
+  // will scale the (cropped) buffer content to fit the |display_size_dip_|.
   // If empty, no scaling is applied.
-  gfx::Size display_size_px_ = gfx::Size();
+  gfx::Size display_size_dip_ = gfx::Size();
 
   void ExplicitRelease(struct zwp_linux_buffer_release_v1* linux_buffer_release,
                        absl::optional<int32_t> fence);
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc
index 302245e8..de0bd0d 100644
--- a/ui/platform_window/x11/x11_window.cc
+++ b/ui/platform_window/x11/x11_window.cc
@@ -1199,9 +1199,19 @@
   // Process X11-specific bits
   HandleEvent(xev);
 
+  x11::Event last_xev;
+  std::unique_ptr<ui::Event> last_motion;
+  if (CoalesceEventsIfNeeded(xev, event->type(), &last_xev)) {
+    last_motion = ui::BuildEventFromXEvent(last_xev);
+    event = last_motion.get();
+  }
+
   // If |event| is a located event (mouse, touch, etc) and another X11 window
   // is set as the current located events grabber, the |event| must be
   // re-routed to that grabber. Otherwise, just send the event.
+  // Note: We want to coalesce events before doing this, since this modifies our
+  // ui::Event's coordinates, and coalescing would simply undo the coordinate
+  // change.
   auto* located_events_grabber = window_manager->located_events_grabber();
   if (event->IsLocatedEvent() && located_events_grabber &&
       located_events_grabber != this) {
@@ -1216,13 +1226,6 @@
     return located_events_grabber->DispatchUiEvent(event, xev);
   }
 
-  x11::Event last_xev;
-  std::unique_ptr<ui::Event> last_motion;
-  if (CoalesceEventsIfNeeded(xev, event->type(), &last_xev)) {
-    last_motion = ui::BuildEventFromXEvent(last_xev);
-    event = last_motion.get();
-  }
-
   // If after CoalescePendingMotionEvents the type of xev is resolved to
   // UNKNOWN, i.e: xevent translation returns nullptr, don't dispatch the
   // event. TODO(804418): investigate why ColescePendingMotionEvents can
diff --git a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
index 224ac8d..f7e99f4 100644
--- a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
+++ b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
@@ -4,12 +4,12 @@
 
 #import "ui/shell_dialogs/select_file_dialog_mac.h"
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #import "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
-#include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/ui/strings/translations/ui_strings_en-GB.xtb b/ui/strings/translations/ui_strings_en-GB.xtb
index 778df8b..cc61eba 100644
--- a/ui/strings/translations/ui_strings_en-GB.xtb
+++ b/ui/strings/translations/ui_strings_en-GB.xtb
@@ -178,6 +178,7 @@
 <translation id="6156262341071374681">Expand to all apps</translation>
 <translation id="6165508094623778733">Learn more</translation>
 <translation id="6166852626429024716">Search your device, apps, settings, web…</translation>
+<translation id="6237461503717005873"><ph name="ROW_NAME" /> is selected.</translation>
 <translation id="6264365405983206840">Select &amp;All</translation>
 <translation id="6351032674660237738">APP SUGGESTIONS</translation>
 <translation id="6364916375976753737">Scroll Left</translation>
diff --git a/ui/views/accessibility/ax_root_obj_wrapper.cc b/ui/views/accessibility/ax_root_obj_wrapper.cc
index 58ccb4c..0d4e3c6 100644
--- a/ui/views/accessibility/ax_root_obj_wrapper.cc
+++ b/ui/views/accessibility/ax_root_obj_wrapper.cc
@@ -19,15 +19,9 @@
 
 AXRootObjWrapper::AXRootObjWrapper(views::AXAuraObjCache::Delegate* delegate,
                                    views::AXAuraObjCache* cache)
-    : AXAuraObjWrapper(cache), delegate_(delegate) {
-  if (display::Screen::GetScreen())
-    display::Screen::GetScreen()->AddObserver(this);
-}
+    : AXAuraObjWrapper(cache), delegate_(delegate) {}
 
-AXRootObjWrapper::~AXRootObjWrapper() {
-  if (display::Screen::GetScreen())
-    display::Screen::GetScreen()->RemoveObserver(this);
-}
+AXRootObjWrapper::~AXRootObjWrapper() = default;
 
 bool AXRootObjWrapper::HasChild(views::AXAuraObjWrapper* child) {
   std::vector<views::AXAuraObjWrapper*> children;
diff --git a/ui/views/accessibility/ax_root_obj_wrapper.h b/ui/views/accessibility/ax_root_obj_wrapper.h
index e77a5454..708b653a 100644
--- a/ui/views/accessibility/ax_root_obj_wrapper.h
+++ b/ui/views/accessibility/ax_root_obj_wrapper.h
@@ -41,6 +41,7 @@
   void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
 
+  display::ScopedOptionalDisplayObserver display_observer_{this};
   ui::AXUniqueId unique_id_;
 
   views::AXAuraObjCache::Delegate* delegate_;
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm
index 7029b99..fcf8db6 100644
--- a/ui/views/test/event_generator_delegate_mac.mm
+++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -5,10 +5,10 @@
 #import <Cocoa/Cocoa.h>
 #include <stddef.h>
 
+#include "base/cxx17_backports.h"
 #import "base/mac/scoped_nsobject.h"
 #import "base/mac/scoped_objc_class_swizzler.h"
 #include "base/memory/singleton.h"
-#include "base/stl_util.h"
 #include "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
diff --git a/ui/web_dialogs/web_dialog_ui.cc b/ui/web_dialogs/web_dialog_ui.cc
index 13c36efd..87ed9fb 100644
--- a/ui/web_dialogs/web_dialog_ui.cc
+++ b/ui/web_dialogs/web_dialog_ui.cc
@@ -103,7 +103,7 @@
   WebDialogDelegate* delegate = GetDelegate(web_ui_->GetWebContents());
   if (delegate) {
     std::string json_retval;
-    if (args && !args->empty() && !args->GetString(0, &json_retval))
+    if (args && !args->GetList().empty() && !args->GetString(0, &json_retval))
       NOTREACHED() << "Could not read JSON argument";
 
     delegate->OnDialogCloseFromWebUI(json_retval);
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn
index 8f68987..bd5d27f 100644
--- a/ui/webui/resources/BUILD.gn
+++ b/ui/webui/resources/BUILD.gn
@@ -182,16 +182,24 @@
 
   definitions += [
     # Auto-generated .d.ts files.
+    "$root_dir/cr_components/managed_dialog/managed_dialog.d.ts",
     "$root_dir/cr_elements/action_link_css.m.d.ts",
+    "$root_dir/cr_elements/cr_fingerprint/cr_fingerprint_icon.m.d.ts",
+    "$root_dir/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.d.ts",
     "$root_dir/cr_elements/cr_actionable_row_style.m.d.ts",
     "$root_dir/cr_elements/cr_grid/cr_grid.d.ts",
     "$root_dir/cr_elements/cr_icons_css.m.d.ts",
     "$root_dir/cr_elements/cr_auto_img/cr_auto_img.d.ts",
     "$root_dir/cr_elements/cr_input/cr_input_style_css.m.d.ts",
     "$root_dir/cr_elements/cr_link_row/cr_link_row.d.ts",
+    "$root_dir/cr_elements/cr_lottie/cr_lottie.m.d.ts",
     "$root_dir/cr_elements/cr_menu_selector/cr_menu_selector.d.ts",
     "$root_dir/cr_elements/cr_page_host_style_css.d.ts",
+    "$root_dir/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.d.ts",
+    "$root_dir/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.d.ts",
     "$root_dir/cr_elements/cr_radio_button/cr_radio_button_style_css.m.d.ts",
+    "$root_dir/cr_elements/cr_scrollable_behavior.m.d.ts",
+    "$root_dir/cr_elements/cr_slider/cr_slider.d.ts",
     "$root_dir/cr_elements/cr_splitter/cr_splitter.d.ts",
     "$root_dir/cr_elements/cr_toolbar/cr_toolbar.d.ts",
     "$root_dir/cr_elements/cr_toolbar/cr_toolbar_selection_overlay.d.ts",
@@ -201,10 +209,14 @@
     "$root_dir/cr_elements/mouse_hoverable_mixin.d.ts",
     "$root_dir/cr_elements/mwb_shared_style.d.ts",
     "$root_dir/cr_elements/mwb_shared_vars.d.ts",
+    "$root_dir/cr_elements/policy/cr_policy_pref_behavior.m.d.ts",
+    "$root_dir/cr_elements/policy/cr_policy_pref_indicator.m.d.ts",
+    "$root_dir/cr_elements/search_highlight_style_css.d.ts",
     "$root_dir/cr_elements/shared_style_css.m.d.ts",
     "$root_dir/cr_elements/shared_vars_css.m.d.ts",
     "$root_dir/js/action_link.d.ts",
     "$root_dir/js/assert.m.d.ts",
+    "$root_dir/js/color_utils.d.ts",
     "$root_dir/js/cr/event_target.m.d.ts",
     "$root_dir/js/cr.m.d.ts",
     "$root_dir/js/cr/ui/drag_wrapper.d.ts",
@@ -217,10 +229,18 @@
     "$root_dir/js/load_time_data.m.d.ts",
     "$root_dir/js/parse_html_subset.m.d.ts",
     "$root_dir/js/plural_string_proxy.d.ts",
+    "$root_dir/js/search_highlight_utils.d.ts",
     "$root_dir/js/icon.m.d.ts",
     "$root_dir/js/util.m.d.ts",
   ]
 
+  if (is_chromeos_ash) {
+    definitions += [
+      "$root_dir/cr_elements/chromeos/cros_color_overrides.m.d.ts",
+      "$root_dir/cr_elements/chromeos/cr_picture/png.m.d.ts",
+    ]
+  }
+
   if (!is_android) {
     definitions += [ "$root_dir/js/cr/ui/focus_without_ink.m.d.ts" ]
   }
@@ -236,31 +256,43 @@
   root_dir = preprocessed_folder
   out_dir = preprocessed_folder
   js_files = [
+    "cr_components/managed_dialog/managed_dialog.js",
     "cr_elements/action_link_css.m.js",
     "cr_elements/cr_actionable_row_style.m.js",
+    "cr_elements/cr_fingerprint/cr_fingerprint_icon.m.js",
+    "cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.js",
     "cr_elements/cr_grid/cr_grid.js",
     "cr_elements/cr_icons_css.m.js",
     "cr_elements/cr_auto_img/cr_auto_img.js",
     "cr_elements/cr_input/cr_input_style_css.m.js",
     "cr_elements/cr_link_row/cr_link_row.js",
+    "cr_elements/cr_lottie/cr_lottie.m.js",
     "cr_elements/cr_menu_selector/cr_menu_selector.js",
     "cr_elements/cr_page_host_style_css.js",
+    "cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector_grid.js",
+    "cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js",
     "cr_elements/cr_radio_button/cr_radio_button_style_css.m.js",
+    "cr_elements/cr_scrollable_behavior.m.js",
     "cr_elements/cr_search_field/cr_search_field.js",
+    "cr_elements/cr_slider/cr_slider.js",
     "cr_elements/cr_splitter/cr_splitter.js",
     "cr_elements/cr_tabs/cr_tabs.js",
     "cr_elements/cr_toolbar/cr_toolbar.js",
     "cr_elements/cr_toolbar/cr_toolbar_selection_overlay.js",
     "cr_elements/hidden_style_css.m.js",
+    "cr_elements/icons.m.js",
+    "cr_elements/md_select_css.m.js",
     "cr_elements/mouse_hoverable_mixin.js",
     "cr_elements/mwb_shared_style.js",
     "cr_elements/mwb_shared_vars.js",
-    "cr_elements/icons.m.js",
-    "cr_elements/md_select_css.m.js",
+    "cr_elements/policy/cr_policy_pref_behavior.m.js",
+    "cr_elements/policy/cr_policy_pref_indicator.m.js",
+    "cr_elements/search_highlight_style_css.js",
     "cr_elements/shared_style_css.m.js",
     "cr_elements/shared_vars_css.m.js",
     "js/action_link.js",
     "js/assert.m.js",
+    "js/color_utils.js",
     "js/cr/event_target.m.js",
     "js/cr.m.js",
     "js/cr/ui/drag_wrapper.js",
@@ -268,16 +300,24 @@
     "js/cr/ui/focus_outline_manager.m.js",
     "js/cr/ui/focus_row.m.js",
     "js/cr/ui/keyboard_shortcut_list.m.js",
-    "js/cr/ui/store.m.js",
     "js/cr/ui/store_client.m.js",
+    "js/cr/ui/store.m.js",
     "js/event_tracker.m.js",
     "js/icon.m.js",
     "js/load_time_data.m.js",
     "js/parse_html_subset.m.js",
     "js/plural_string_proxy.js",
+    "js/search_highlight_utils.js",
     "js/util.m.js",
   ]
 
+  if (is_chromeos_ash) {
+    js_files += [
+      "cr_elements/chromeos/cros_color_overrides.m.js",
+      "cr_elements/chromeos/cr_picture/png.m.js",
+    ]
+  }
+
   if (!is_android) {
     js_files += [ "js/cr/ui/focus_without_ink.m.js" ]
   }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_icon.html b/ui/webui/resources/cr_components/chromeos/network/network_icon.html
index 0649dc01..bceb439 100644
--- a/ui/webui/resources/cr_components/chromeos/network/network_icon.html
+++ b/ui/webui/resources/cr_components/chromeos/network/network_icon.html
@@ -19,8 +19,8 @@
 
       #icon {
         height: 20px;
-        opacity: .65;  /* Equivalent to #5a5a5a */
         width: 20px;
+        background: var(--cros-icon-color-primary)
       }
 
       /* Upper-left corner */
@@ -55,41 +55,41 @@
 
       /* Images */
       #icon.ethernet {
-        background: url(chrome://resources/cr_components/chromeos/network/ethernet.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/ethernet.svg);
       }
 
       #icon.vpn {
-        background: url(chrome://resources/cr_components/chromeos/network/vpn.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/vpn.svg);
       }
 
       /* Wi-Fi images */
       #icon.wifi-not-connected {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_0_with_x.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_0_with_x.svg);
       }
 
       #icon.wifi-no-network,
       #icon.wifi-0 {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_0.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_0.svg);
       }
 
       #icon.wifi-1 {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_1.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_1.svg);
       }
 
       #icon.wifi-2 {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_2.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_2.svg);
       }
 
       #icon.wifi-3 {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_3.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_3.svg);
       }
 
       #icon.wifi-4 {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_4.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_4.svg);
       }
 
       #icon.wifi-off {
-        background: url(chrome://resources/cr_components/chromeos/network/wifi_off.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_off.svg);
       }
 
       #icon.wifi-connecting {
@@ -100,54 +100,54 @@
 
       @keyframes wifi-levels {
         0% {
-          background: url(chrome://resources/cr_components/chromeos/network/wifi_0.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_0.svg);
         }
         25% {
-          background: url(chrome://resources/cr_components/chromeos/network/wifi_1.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_1.svg);
         }
         50% {
-          background: url(chrome://resources/cr_components/chromeos/network/wifi_2.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_2.svg);
         }
         75% {
-          background: url(chrome://resources/cr_components/chromeos/network/wifi_3.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_3.svg);
         }
         100% {
-          background: url(chrome://resources/cr_components/chromeos/network/wifi_4.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/wifi_4.svg);
         }
       }
 
       /* Cellular images */
       #icon.cellular-not-connected {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_0_with_x.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_0_with_x.svg);
       }
 
       #icon.cellular-no-network,
       #icon.cellular-0 {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_0.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_0.svg);
       }
 
       #icon.cellular-1 {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_1.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_1.svg);
       }
 
       #icon.cellular-2 {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_2.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_2.svg);
       }
 
       #icon.cellular-3 {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_3.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_3.svg);
       }
 
       #icon.cellular-4 {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_4.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_4.svg);
       }
 
       #icon.cellular-off {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_off.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_off.svg);
       }
 
       #icon.cellular-locked {
-        background: url(chrome://resources/cr_components/chromeos/network/cellular_locked.svg);
+        -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_locked.svg);
       }
 
       #icon.cellular-connecting {
@@ -158,19 +158,19 @@
 
       @keyframes cellular-levels {
         0% {
-          background: url(chrome://resources/cr_components/chromeos/network/cellular_0.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_0.svg);
         }
         25% {
-          background: url(chrome://resources/cr_components/chromeos/network/cellular_1.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_1.svg);
         }
         50% {
-          background: url(chrome://resources/cr_components/chromeos/network/cellular_2.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_2.svg);
         }
         75% {
-          background: url(chrome://resources/cr_components/chromeos/network/cellular_3.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_3.svg);
         }
         100% {
-          background: url(chrome://resources/cr_components/chromeos/network/cellular_4.svg);
+          -webkit-mask: url(chrome://resources/cr_components/chromeos/network/cellular_4.svg);
         }
       }
     </style>
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.mojom b/ui/webui/resources/cr_components/most_visited/most_visited.mojom
index b10f146..0a1b115 100644
--- a/ui/webui/resources/cr_components/most_visited/most_visited.mojom
+++ b/ui/webui/resources/cr_components/most_visited/most_visited.mojom
@@ -20,9 +20,6 @@
   int32 source;
   // Identifier of most visited entry title source (e.g. page's title tag).
   int32 title_source;
-  // Time the most visited entry was generated (e.g. received by a suggestion
-  // server).
-  mojo_base.mojom.Time data_generation_time;
 };
 
 // Theme settings for the NTP MV tiles.
diff --git a/weblayer/browser/ad_tagging_browsertest.cc b/weblayer/browser/ad_tagging_browsertest.cc
index 1b0a8b3..3c5a57a1 100644
--- a/weblayer/browser/ad_tagging_browsertest.cc
+++ b/weblayer/browser/ad_tagging_browsertest.cc
@@ -68,8 +68,9 @@
       ad_frame_tagged_by_script->GetFrameTreeNodeId()));
 }
 
+// TODO(crbug.com/1210190): This test is flaky.
 IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest,
-                       AdContentSettingBlocked_AdTaggingEnabled) {
+                       DISABLED_AdContentSettingBlocked_AdTaggingEnabled) {
   HostContentSettingsMapFactory::GetForBrowserContext(
       web_contents()->GetBrowserContext())
       ->SetDefaultContentSetting(ContentSettingsType::ADS,
diff --git a/weblayer/browser/persistence/browser_persister_file_utils.cc b/weblayer/browser/persistence/browser_persister_file_utils.cc
index 8a109cd..27d74dfd5 100644
--- a/weblayer/browser/persistence/browser_persister_file_utils.cc
+++ b/weblayer/browser/persistence/browser_persister_file_utils.cc
@@ -4,10 +4,10 @@
 
 #include "weblayer/browser/persistence/browser_persister_file_utils.h"
 
+#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/stl_util.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "components/base32/base32.h"
diff --git a/weblayer/shell/browser/shell_views.cc b/weblayer/shell/browser/shell_views.cc
index e8d08e36d..33a7291 100644
--- a/weblayer/shell/browser/shell_views.cc
+++ b/weblayer/shell/browser/shell_views.cc
@@ -9,7 +9,7 @@
 #include <memory>
 
 #include "base/command_line.h"
-#include "base/stl_util.h"
+#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
diff --git a/weblayer/tools/run_weblayer_shell.py b/weblayer/tools/run_weblayer_shell.py
index 7ae95f4..41391b2 100755
--- a/weblayer/tools/run_weblayer_shell.py
+++ b/weblayer/tools/run_weblayer_shell.py
@@ -3,6 +3,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from __future__ import absolute_import
+from __future__ import print_function
 import argparse
 import os
 import subprocess
@@ -37,21 +39,21 @@
   devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices)
 
   def install(device):
-    print 'Installing %s...' % args.shell_apk_path
+    print('Installing %s...' % args.shell_apk_path)
     device.Install(args.shell_apk_path, reinstall=True, allow_downgrade=True)
-    print 'Success'
+    print('Success')
     for path in args.support_apk_path:
-      print 'Installing %s...' % path
+      print('Installing %s...' % path)
       device.Install(path, reinstall=True, allow_downgrade=True)
-      print 'Success'
+      print('Success')
     if args.switch_webview_to:
-      print 'Installing %s...' % args.switch_webview_to
+      print('Installing %s...' % args.switch_webview_to)
       device.Install(args.switch_webview_to, reinstall=True,
                      allow_downgrade=True)
       package = apk_helper.GetPackageName(args.switch_webview_to)
-      print 'Setting WebView implementation to %s' % package
+      print('Setting WebView implementation to %s' % package)
       device.SetWebViewImplementation(package)
-      print 'Done'
+      print('Done')
 
     if os.path.basename(args.shell_apk_path) == 'WebLayerShell.apk':
       # When launching weblayer shell use 'weblayer_shell_apk', which supports
diff --git a/weblayer/weblayer_resource_exclusions.gni b/weblayer/weblayer_resource_exclusions.gni
index 35c92e1..427feb2b 100644
--- a/weblayer/weblayer_resource_exclusions.gni
+++ b/weblayer/weblayer_resource_exclusions.gni
@@ -22,7 +22,6 @@
   "${_material_package}:[Bb]ottomSheet",
   "${_material_package}:[Bb]uttonToggleGroup",
   "${_material_package}:[Cc]alendar",
-  "${_material_package}:[Cc]ardView",
   "${_material_package}:design_snackbar",
   "${_material_package}:[Ff]loatingActionButton",
   "${_material_package}:[Mm]aterialAlertDialog",
@@ -49,7 +48,7 @@
 # https://crbug.com/636448
 weblayer_resource_exclusion_regex += "|${_material_package}/layout"
 weblayer_resource_exclusion_regex +=
-    "|${_material_package}/color.*(card_|calendar_|bottom_nav_|slider_)"
+    "|${_material_package}/color.*(calendar_|bottom_nav_|slider_)"
 weblayer_resource_exclusion_regex +=
     "|${_material_package}/drawable.*design_snackbar"
 weblayer_resource_exclusion_regex += "|${_material_package}/xml.*badge_"